/* ==========================================================================
   《不就是语法和长难句吗》· 交互学习站  ——  设计系统 v2
   方向：编辑部式暗色手册（Editorial Dark）
     · 深色为默认，像专业阅读器；浅色是暖纸，不像纯白屏幕
     · 六章各有身份色（--acc），进入哪章，整站强调色跟着变
     · 正文用无衬线，英文例句用衬线 —— 一眼分清"讲解"和"原文"
     · 知识点用悬挂编号（01 02 03），像技术手册而不是卡片瀑布
     · 思维导图是真 SVG 树，不是缩进列表
   ========================================================================== */

/* ---------------------------------------------------------------- tokens */
:root {
  --ink:        #08090C;
  --bg:         #0C0E12;
  --surface:    #14171D;
  --surface-2:  #1A1E26;
  --surface-3:  #222733;
  --line:       rgba(255, 255, 255, 0.075);
  --line-2:     rgba(255, 255, 255, 0.14);

  --fg:         #E9EBF0;
  --fg-2:       #B7BDC8;
  --fg-3:       #9AA2AE;

  /* 章节身份色，由 JS 写到 :root 上 */
  --acc:        #4E8BFF;
  --acc-soft:   rgba(78, 139, 255, 0.14);
  --acc-line:   rgba(78, 139, 255, 0.40);

  --warn:       #FFA23A;
  --ok:         #22C3A6;
  --bad:        #FF6E62;
  /* 点词查义：悬停用「深绿」，点中的那个词用「荧光绿 + 光晕」（暗底要更亮才发得出来） */
  --wdgreen:    #34D399;
  --wdglow:     #7BF7B0;

  --r-xs: 7px;
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;

  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
          "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  --serif: "Iowan Old Style", "Palatino Linotype", Georgia, "Times New Roman", serif;
  --mono: "SF Mono", ui-monospace, "JetBrains Mono", Consolas, Menlo, monospace;

  --topbar-h: 54px;
  --rail-w: 264px;
  /* 正文宽度随视口伸缩：窄屏保底可读，宽屏吃满可用空间，但不超过舒适行长 */
  --read-w: clamp(740px, 68vw, 1200px);
  --wide-w: clamp(980px, 82vw, 1480px);
  --read-scale: 1;

  --sh: 0 1px 2px rgba(0, 0, 0, 0.4), 0 16px 40px -24px rgba(0, 0, 0, 0.9);
  --sh-lg: 0 2px 8px rgba(0, 0, 0, 0.5), 0 40px 80px -32px rgba(0, 0, 0, 0.95);

  --mm-link: rgba(255, 255, 255, 0.26);
  --mm-dot: rgba(255, 255, 255, 0.075);
}

/* 浅色：暖纸，不是冷白 */
html[data-theme="light"] {
  --ink:        #EFEBE3;
  --bg:         #FAF8F3;
  --surface:    #FFFFFF;
  --surface-2:  #F4F1EA;
  --surface-3:  #EAE6DD;
  --line:       rgba(28, 24, 16, 0.10);
  --line-2:     rgba(28, 24, 16, 0.17);

  --fg:         #17181C;
  --fg-2:       #4A5058;
  --fg-3:       #5E646E;

  --acc:        #2563EB;
  --acc-soft:   rgba(37, 99, 235, 0.10);
  --acc-line:   rgba(37, 99, 235, 0.34);

  --warn:       #B35B00;
  --ok:         #0E8A72;
  --bad:        #D9453A;
  --wdgreen:    #12703C;   /* 悬停：浅色主题下的深绿（米白底上够沉、够清楚） */
  --wdglow:     #0EA34B;   /* 点中：荧光绿（米白底上要亮，配一层绿晕才有"发光"感） */

  --sh: 0 1px 2px rgba(60, 50, 30, 0.05), 0 14px 34px -22px rgba(60, 50, 30, 0.30);
  --sh-lg: 0 2px 8px rgba(60, 50, 30, 0.07), 0 36px 70px -30px rgba(60, 50, 30, 0.36);

  --mm-link: rgba(20, 24, 30, 0.20);
  --mm-dot: rgba(20, 24, 30, 0.075);
}

/* ---------------------------------------------------------------- 基础 */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--topbar-h) + 44px);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-size: calc(16px * var(--read-scale));
  line-height: 1.86;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-feature-settings: "kern" 1;
}

a { color: var(--acc); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }
button { font-family: inherit; }

::selection { background: var(--acc-soft); color: var(--fg); }

:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
  border-radius: 5px;
}

* { scrollbar-width: thin; scrollbar-color: var(--surface-3) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb {
  background: var(--surface-3); border-radius: 10px;
  border: 3px solid transparent; background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--line-2); background-clip: content-box; }

.skip-link {
  position: absolute; left: 10px; top: -70px; z-index: 200;
  background: var(--acc); color: #fff; padding: 10px 16px;
  border-radius: var(--r-sm); font-size: 13px; transition: top .18s;
}
.skip-link:focus { top: 10px; }

/* ---------------------------------------------------------------- 顶栏 */
.progress-rail {
  position: fixed; top: 0; left: 0; height: 2px; width: 0;
  background: var(--acc); z-index: 90;
  box-shadow: 0 0 12px var(--acc-line);
  transition: width .09s linear;
}

.topbar {
  position: sticky; top: 0; z-index: 80;
  height: var(--topbar-h);
  display: flex; align-items: center; gap: 12px;
  padding: 0 18px;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  -webkit-backdrop-filter: saturate(160%) blur(18px);
  backdrop-filter: saturate(160%) blur(18px);
  border-bottom: 1px solid var(--line);
}
.topbar > * { min-width: 0; }

.mark {
  display: flex; align-items: center; gap: 10px;
  color: inherit; text-decoration: none; flex: 0 0 auto;
}
.mark:hover { text-decoration: none; }
.mark-glyph {
  width: 28px; height: 28px; border-radius: 8px;
  display: grid; place-items: center;
  background: var(--acc); color: #fff;
  font-size: 14px; font-weight: 800; letter-spacing: -0.03em;
  box-shadow: 0 2px 10px var(--acc-line);
  transition: background .3s;
}
.mark-txt { display: flex; flex-direction: column; line-height: 1.22; }
.mark-txt b { font-size: 13px; font-weight: 650; letter-spacing: -0.01em; }
.mark-txt em { font-size: 10.5px; font-style: normal; color: var(--fg-3); letter-spacing: .02em; }

/* 顶部章节滑动条 */
.chapter-strip {
  display: flex; align-items: center; gap: 2px;
  margin-left: auto; margin-right: auto;
  overflow-x: auto; scrollbar-width: none;
  padding: 0 4px;
}
.chapter-strip::-webkit-scrollbar { display: none; }
.strip-item {
  flex: 0 0 auto;
  padding: 5px 10px; border-radius: 7px;
  border: none; background: transparent; cursor: pointer;
  font-size: 12px; font-weight: 500; color: var(--fg-2);
  display: flex; align-items: center; gap: 5px;
  transition: color .15s, background .15s;
  white-space: nowrap;
}
.strip-item:hover { color: var(--fg); background: var(--surface); }
.strip-item[aria-current="true"] { color: var(--fg); background: var(--surface); }
.strip-item .pip {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--c); flex: 0 0 auto;
}
.strip-item .strip-name { font-size: 11.5px; opacity: .85; letter-spacing: .01em; }
@media (max-width: 1180px) { .strip-item .strip-name { display: none; } }

.top-actions { display: flex; align-items: center; gap: 3px; flex: 0 0 auto; }

.icon-btn {
  width: 32px; height: 32px; border-radius: 8px;
  display: grid; place-items: center;
  border: 1px solid transparent; background: transparent;
  color: var(--fg-2); cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.icon-btn:hover { background: var(--surface); color: var(--fg); border-color: var(--line); }
.icon-btn svg { width: 17px; height: 17px; }
.icon-btn .glyph-a { font-size: 12.5px; font-weight: 700; letter-spacing: -0.02em; }
.icon-btn .glyph-a sup { font-size: 8px; }
html[data-theme="dark"] .ico-sun { display: none; }
html[data-theme="light"] .ico-moon { display: none; }

.search-trigger {
  display: flex; align-items: center; gap: 8px;
  height: 32px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); color: var(--fg-3);
  font-size: 12.5px; cursor: pointer;
  transition: border-color .15s, color .15s;
  min-width: 150px;
}
.search-trigger:hover { border-color: var(--line-2); color: var(--fg-2); }
.search-trigger svg { width: 14px; height: 14px; flex: 0 0 auto; }
.search-trigger span { flex: 1 1 auto; text-align: left; }
.search-trigger kbd {
  font-family: var(--mono); font-size: 10.5px; color: var(--fg-3);
  border: 1px solid var(--line-2); border-radius: 4px; padding: 0 4px; line-height: 15px;
}

/* ---------------------------------------------------------------- 布局 */
.shell {
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr);
  align-items: start;
  max-width: 1860px;
  margin: 0 auto;
}

/* ---------------------------------------------------------------- 侧栏 */
.rail {
  position: sticky; top: var(--topbar-h);
  height: calc(100vh - var(--topbar-h));
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column;
  overflow: hidden;
}
.rail-head {
  padding: 16px 18px 10px;
  display: flex; align-items: center; justify-content: space-between;
}
.rail-head span {
  font-size: 10.5px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--fg-3);
}
.rail-head button {
  border: none; background: transparent; color: var(--fg-3);
  font-size: 11px; cursor: pointer; padding: 3px 6px; border-radius: 5px;
}
.rail-head button:hover { color: var(--fg-2); background: var(--surface); }

.rail-scroll { flex: 1 1 auto; overflow-y: auto; padding: 0 10px 20px; scroll-behavior: smooth; }

.rail-foot {
  padding: 11px 18px; border-top: 1px solid var(--line);
  display: flex; align-items: center; gap: 10px;
  font-size: 11.5px; color: var(--fg-3);
}
.rail-foot a { color: var(--fg-2); }
.rail-foot .sep { opacity: .45; }

/* 侧栏树 */
.nav-ch { margin-bottom: 1px; }
.nav-ch-row {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 8px 9px; border: none; border-radius: 8px;
  background: transparent; cursor: pointer; text-align: left;
  color: var(--fg-2); font-size: 13px; font-weight: 560; line-height: 1.4;
  transition: background .14s, color .14s;
}
.nav-ch-row:hover { background: var(--surface); color: var(--fg); }
.nav-ch.active > .nav-ch-row { color: var(--fg); background: var(--surface); }
.nav-ch-row .ch-dot {
  width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto;
  background: var(--c); box-shadow: 0 0 0 3px color-mix(in srgb, var(--c) 18%, transparent);
}
.nav-ch-row .ch-label { flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-ch-row .ch-caret {
  width: 11px; height: 11px; flex: 0 0 auto; color: var(--fg-3);
  transition: transform .2s;
}
.nav-ch.collapsed .ch-caret { transform: rotate(-90deg); }
.nav-ch.collapsed .nav-secs { display: none; }

.nav-secs { margin: 2px 0 6px 15px; padding-left: 9px; border-left: 1px solid var(--line); }

.nav-sec {
  display: flex; align-items: center; gap: 7px;
  width: 100%; padding: 6px 8px; border: none; border-radius: 7px;
  background: transparent; cursor: pointer; text-align: left;
  color: var(--fg-2); font-size: 12.5px; line-height: 1.45;
  transition: background .14s, color .14s;
}
.nav-sec:hover { background: var(--surface); color: var(--fg-2); }
.nav-sec.active { background: var(--acc-soft); color: var(--acc); font-weight: 620; }
.nav-sec .num-mini {
  font-family: var(--mono); font-size: 10px; color: var(--fg-3);
  flex: 0 0 auto; opacity: .8;
}
.nav-sec.active .num-mini { color: var(--acc); opacity: 1; }
.nav-sec .sec-txt { flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-sec .done-mark {
  width: 11px; height: 11px; flex: 0 0 auto; color: var(--ok);
  opacity: 0; transition: opacity .2s;
}
.nav-sec.is-done .done-mark { opacity: 1; }

/* 三级：节内知识点 */
.nav-points { margin: 1px 0 7px 12px; padding-left: 8px; border-left: 1px dashed var(--line-2); }
.nav-point {
  display: block; width: 100%; text-align: left;
  padding: 4px 7px; border: none; border-radius: 6px; background: transparent;
  color: var(--fg-2); font-size: 11.5px; line-height: 1.45; cursor: pointer;
  transition: color .14s, background .14s;
}
.nav-point:hover { color: var(--fg); background: var(--surface); }
.nav-point.active {
  color: var(--acc); background: var(--acc-soft); font-weight: 620;
}

/* ---------------------------------------------------------------- 主区 */
.main { min-width: 0; padding: 0 0 140px; }

.wrap-read { max-width: var(--read-w); margin: 0 auto; padding: 0 34px; }
.wrap-wide { max-width: var(--wide-w); margin: 0 auto; padding: 0 34px; }

/* 宽屏：留白跟着放大，内容不至于贴边 */
@media (min-width: 1560px) {
  .wrap-read, .wrap-wide { padding: 0 12px; }
}

/* 面包屑 */
.crumbs {
  display: flex; align-items: center; gap: 7px;
  font-size: 11.5px; color: var(--fg-3);
  padding: 22px 0 0;
}
.crumbs a { color: var(--fg-3); }
.crumbs a:hover { color: var(--acc); text-decoration: none; }
.crumbs .csep { opacity: .5; }

/* ---------------------------------------------------------------- 章首页 */
.book-hero {
  position: relative;
  padding: 44px 0 34px;
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.book-hero::before {
  content: ""; position: absolute; left: -140px; top: -190px;
  width: 520px; height: 460px; pointer-events: none;
  background: radial-gradient(circle at 50% 50%, var(--acc-soft), transparent 66%);
  filter: blur(6px);
}
.hero-inner { position: relative; display: flex; align-items: flex-end; gap: 30px; }
.hero-num {
  font-family: var(--mono);
  font-size: 108px; line-height: .82; font-weight: 700;
  letter-spacing: -0.06em;
  color: transparent;
  -webkit-text-stroke: 1.4px var(--acc);
  opacity: .38;
  flex: 0 0 auto;
  user-select: none;
}
.hero-body { min-width: 0; flex: 1 1 auto; }
.hero-kicker {
  font-size: 11px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--acc); margin-bottom: 9px;
}
h1.hero-title {
  font-size: 38px; line-height: 1.16; font-weight: 750;
  letter-spacing: -0.028em; margin: 0 0 12px;
}
.hero-hook {
  font-size: 17px; line-height: 1.6; color: var(--fg-2);
  margin: 0 0 14px; max-width: 620px;
}
.hero-summary {
  font-size: 14.8px; line-height: 1.82; color: var(--fg-2);
  margin: 0; max-width: 660px;
}

.hero-meta {
  display: flex; align-items: center; gap: 22px;
  margin-top: 22px; flex-wrap: wrap;
}
.meta-item { display: flex; align-items: baseline; gap: 6px; }
.meta-item b { font-size: 17px; font-weight: 700; letter-spacing: -0.02em; }
.meta-item span { font-size: 11.5px; color: var(--fg-3); }

/* 进度环 */
.ring-wrap { display: flex; align-items: center; gap: 10px; }
.ring { width: 40px; height: 40px; transform: rotate(-90deg); }
.ring circle { fill: none; stroke-width: 3.4; }
.ring .track { stroke: var(--surface-3); }
.ring .fill { stroke: var(--acc); stroke-linecap: round; transition: stroke-dashoffset .5s ease; }
.ring-txt { font-size: 11.5px; color: var(--fg-3); line-height: 1.3; }
.ring-txt b { display: block; font-size: 13px; color: var(--fg); font-weight: 650; }

/* ---------------------------------------------------------------- 知识地图（导图容器） */
.map-panel {
  margin: 30px 0 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  overflow: hidden;
}
.map-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px; border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface-2) 60%, transparent);
}
.map-bar h3 {
  margin: 0; font-size: 11px; font-weight: 700; letter-spacing: .11em;
  text-transform: uppercase; color: var(--fg-3);
}
.map-bar .spacer { flex: 1 1 auto; }
.chip-btn {
  height: 26px; padding: 0 10px; border-radius: 6px;
  border: 1px solid var(--line); background: transparent;
  color: var(--fg-2); font-size: 11.5px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px;
  transition: color .14s, border-color .14s, background .14s;
}
.chip-btn:hover { color: var(--fg); border-color: var(--line-2); background: var(--surface-2); }
.chip-btn svg { width: 12px; height: 12px; }

.map-canvas {
  padding: 20px 16px;
  overflow: auto;
  max-height: 480px;
  display: flex; justify-content: center;
  background:
    radial-gradient(circle at 1px 1px, var(--mm-dot) 1px, transparent 0) 0 0 / 22px 22px;
  /* 像画布一样按住拖动平移 */
  cursor: grab;
  touch-action: pan-y;          /* 竖向留给页面滚动，横向由拖动接管 */
  overscroll-behavior: contain; /* 拖到头别把整页带着滚 */
}
.map-canvas.is-panning { cursor: grabbing; user-select: none; -webkit-user-select: none; }
.map-canvas.is-panning * { cursor: grabbing; }
/* 画布操作提示（放在按钮行里，不挡内容、不受滚动影响） */
.map-tip {
  margin-left: 10px;
  font-size: 11px; line-height: 1.6; letter-spacing: .02em;
  color: var(--fg-3);
  white-space: nowrap;
}
/* 放大 / 缩小按钮：方形、图标居中，两个挨在一起 */
.map-zoom-btn {
  width: 26px; min-width: 26px; height: 24px;
  padding: 0; margin-right: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 15px; line-height: 1; font-weight: 600;
}
.map-zoom-btn + .map-zoom-btn { margin-right: 10px; }
.map-canvas > .mm-svg { flex: 0 0 auto; margin: 0 auto; }
/* 节页的结构图是核心内容，让它完整展开，不设高度上限 */
.map-canvas[data-map-canvas^="sec-"] { max-height: none; }
.map-canvas::-webkit-scrollbar { height: 8px; width: 8px; }

/* SVG 导图：颜色全部由 JS 写成 SVG 属性（fill/stroke/font-size），
   这里只负责字体族与悬停反馈 —— 不要再写 fill/stroke，否则会覆盖属性、
   把节点压回接近黑色。 */
.mm-svg { display: block; }
.mm-svg text { font-family: var(--font); }
.mm-svg .link { fill: none; stroke: var(--mm-link); stroke-width: 1.4; transition: stroke .2s; }
.mm-svg .node-box { transition: stroke .18s, fill .18s; }
.mm-svg g.node { cursor: pointer; outline: none; }
.mm-svg g.node:hover .node-box { stroke: var(--acc); }
.mm-svg g.node:focus-visible .node-box { stroke: var(--acc); stroke-width: 2; }
.mm-svg .tog { stroke: var(--fg-2); }
.mm-svg .tog-ring { fill: var(--surface-2); stroke: var(--mm-link); stroke-width: 1; }

/* ---------------------------------------------------------------- 章页：节预览卡 */
.sec-preview-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 12px; margin: 26px 0 0;
}
.sec-preview {
  display: block; text-decoration: none; color: inherit;
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface);
  padding: 18px 20px 16px;
  position: relative; overflow: hidden;
  transition: border-color .18s, transform .18s, box-shadow .18s;
}
.sec-preview:hover {
  text-decoration: none; border-color: var(--acc-line);
  transform: translateY(-2px); box-shadow: var(--sh);
}
.sec-preview .sp-top {
  display: flex; align-items: center; gap: 8px; margin-bottom: 8px;
}
.sec-preview .sp-num {
  font-family: var(--mono); font-size: 11px; font-weight: 700;
  color: var(--acc); letter-spacing: .04em;
}
.sec-preview .sp-done {
  margin-left: auto; font-size: 10.5px; color: var(--ok);
  display: inline-flex; align-items: center; gap: 3px;
}
.sec-preview .sp-done svg { width: 11px; height: 11px; }
.sec-preview h4 {
  font-size: 16.5px; font-weight: 660; margin: 0 0 7px;
  line-height: 1.42; letter-spacing: -0.012em;
}
.sec-preview .sp-tag {
  font-size: 13.2px; color: var(--fg-2); line-height: 1.62; margin: 0 0 12px;
}
.sec-preview .sp-points {
  display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 12px;
}
.sec-preview .sp-points i {
  font-style: normal; font-size: 11.5px; color: var(--fg-2);
  border: 1px solid var(--line-2); border-radius: 5px; padding: 2px 7px;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sec-preview .sp-foot {
  display: flex; align-items: center; gap: 10px;
  font-size: 11.5px; color: var(--fg-2);
  padding-top: 11px; border-top: 1px solid var(--line);
}
.sec-preview .sp-foot .arrow { margin-left: auto; color: var(--acc); }

/* 章末导航 */
.pager {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  margin-top: 48px; padding-top: 26px; border-top: 1px solid var(--line);
}
.pager a {
  display: block; padding: 18px 20px; border-radius: var(--r-md);
  border: 1px solid var(--line); background: var(--surface);
  color: inherit; text-decoration: none;
  text-align: center;
  transition: border-color .16s, background .16s;
}
.pager a:hover { border-color: var(--acc-line); background: var(--surface-2); text-decoration: none; }
.pager small { display: block; font-size: 10.5px; color: var(--fg-3);
  letter-spacing: .08em; text-transform: uppercase; margin-bottom: 5px; }
.pager b { font-size: 14.5px; font-weight: 620; line-height: 1.45; }
.pager .ph { visibility: hidden; }

/* ---------------------------------------------------------------- 节页（阅读） */
.sec-head { padding: 26px 0 0; }
.sec-kicker {
  display: flex; align-items: center; gap: 9px;
  font-size: 11px; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: var(--acc); margin-bottom: 10px;
}
.sec-kicker .rule { flex: 1 1 auto; height: 1px; background: var(--line); }
h1.sec-title {
  font-size: 33px; line-height: 1.24; font-weight: 740;
  letter-spacing: -0.026em; margin: 0 0 10px;
}
.sec-epigraph {
  font-family: var(--serif); font-style: italic;
  font-size: 16.5px; line-height: 1.7; color: var(--fg-2);
  margin: 0 0 20px; padding-left: 14px;
  border-left: 2px solid var(--acc-line);
}
.sec-toolbar {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 0 20px; border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.sec-toolbar .spacer { flex: 1 1 auto; }

.done-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 12px; border-radius: 7px;
  border: 1px solid var(--line); background: transparent;
  color: var(--fg-2); font-size: 12.5px; cursor: pointer;
  transition: all .16s;
}
.done-toggle:hover { border-color: var(--line-2); color: var(--fg); }
.done-toggle.is-done {
  background: color-mix(in srgb, var(--ok) 14%, transparent);
  border-color: color-mix(in srgb, var(--ok) 42%, transparent);
  color: var(--ok);
}
.done-toggle svg { width: 13px; height: 13px; }

/* 节内知识点快跳条 */
.point-strip {
  display: flex; gap: 6px; overflow-x: auto;
  padding: 14px 0 2px; scrollbar-width: none;
}
.point-strip::-webkit-scrollbar { display: none; }
.point-strip button {
  flex: 0 0 auto; height: 28px; padding: 0 11px;
  border-radius: 14px; border: 1px solid var(--line-2);
  background: transparent; color: var(--fg-2);
  font-size: 11.8px; cursor: pointer; white-space: nowrap;
  transition: all .14s;
}
.point-strip button:hover { color: var(--fg); border-color: var(--acc-line); }
.point-strip button.active { background: var(--acc-soft); border-color: var(--acc-line); color: var(--acc); }

/* ---------------------------------------------------------------- 手册体条目 */
.entries { margin-top: 8px; }

.entry {
  display: grid; grid-template-columns: 46px minmax(0, 1fr);
  gap: 0 14px;
  padding: 26px 0;
  border-bottom: 1px solid var(--line);
  scroll-margin-top: calc(var(--topbar-h) + 60px);
}
.entry:last-child { border-bottom: none; }
.entry.flash { animation: flashIn 1.6s ease; }
@keyframes flashIn {
  0% { background: var(--acc-soft); }
  100% { background: transparent; }
}
.entry-no {
  font-family: var(--mono); font-size: 13px; font-weight: 700;
  color: var(--fg-3); letter-spacing: -0.02em;
  padding-top: 4px; user-select: none;
  transition: color .2s;
}
.entry:hover .entry-no { color: var(--acc); }
.entry-body { min-width: 0; }

.entry h3 {
  font-size: 18px; font-weight: 660; line-height: 1.42;
  letter-spacing: -0.014em; margin: 0 0 9px;
}
.entry p {
  margin: 0 0 10px; font-size: 15.5px; line-height: 1.88; color: var(--fg-2);
}
.entry p:last-child { margin-bottom: 0; }
.entry strong { color: var(--fg); font-weight: 660; }
.entry em { font-style: normal; color: var(--acc); font-weight: 600; }
.entry code {
  font-family: var(--mono); font-size: 13.2px;
  background: var(--surface-2); padding: 1.5px 5px; border-radius: 4px;
  color: var(--fg); border: 1px solid var(--line);
}

/* 例句：像引文 */
.quote {
  margin: 14px 0 12px; padding: 2px 0 2px 16px;
  border-left: 2.5px solid var(--acc-line);
}
.quote .q-en {
  font-family: var(--serif); font-size: 17.5px; line-height: 1.66;
  color: var(--fg); margin-bottom: 6px;
  letter-spacing: 0.002em;
}
.quote .q-cn {
  font-size: 14.2px; line-height: 1.72; color: var(--fg-2);
}
.quote .q-note {
  margin-top: 9px; font-size: 13px; line-height: 1.72; color: var(--fg-2);
  position: relative; padding-left: 18px;
}
.quote .q-note::before {
  content: "↳"; color: var(--acc);
  position: absolute; left: 0; top: 0;
  font-size: 13px; line-height: 1.72;
}

/* 内嵌在正文里的例句：中文译文在上、英文原句在下，块间自带呼吸 */
.quote.embedded { margin: 13px 0; padding-top: 1px; padding-bottom: 1px; }
.quote.embedded .q-cn {
  font-size: 14.5px; color: var(--fg-2); margin-bottom: 7px; line-height: 1.7;
}
.quote.embedded .q-en { font-size: 17px; margin-bottom: 0; }

/* ---- 语义分层排版：例句单元 / 练习单元 ---- */
.ex {
  margin: 14px 0;
  padding: 2px 0 2px 16px;
  border-left: 2.5px solid var(--acc-line);
}
.ex + .ex { margin-top: 11px; }
.ex-lead {
  display: inline;
  font-size: 13px; color: var(--fg-3); margin-right: 7px;
  letter-spacing: .01em;
}
.ex-en {
  display: inline;
  font-family: var(--serif); font-size: 17px; line-height: 1.6;
  color: var(--fg); letter-spacing: .002em;
}
.ex-cn {
  font-size: 13.8px; line-height: 1.7; color: var(--fg-2); margin-top: 5px;
}
/* 练习单元：换成「做一道」的颜色，和讲解区分开 */
.ex.practice {
  border-left-color: color-mix(in srgb, var(--ok) 62%, transparent);
  background: color-mix(in srgb, var(--ok) 7%, transparent);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  padding: 10px 14px 10px 15px;
}
.ex.practice .ex-lead { color: var(--ok); font-weight: 650; }
.ex.practice .ex-en { font-size: 16.5px; }
.ex.practice .ex-cn { color: var(--fg-2); }

/* 裸英文短语：夹在中文正文里的 `send sb. sth.` 这类，单独一块浅底 + 强调色，
   否则中英文在视觉上完全一样，看不出"这是要背的形式"。
   注意必须是 inline-block（宽度跟内容 + 相邻的横向并排）：
   用块级的话每个短语会独占一整行 824px，六个短语就是一屏的大色条。 */
.ex.bare {
  display: inline-block; max-width: 100%;
  background: color-mix(in srgb, var(--acc) 8%, transparent);
  border-left: 2.5px solid color-mix(in srgb, var(--acc) 68%, transparent);
  border-radius: 0 8px 8px 0;
  padding: 4px 12px 4px 10px;
  margin: 4px 6px 4px 0;
  vertical-align: baseline;
}
.ex.bare::after { display: none; }        /* 去掉 .ex 的 clear:both，否则会被挤到下一行 */
.ex.bare .ex-en {
  color: color-mix(in srgb, var(--acc) 52%, var(--fg));
  font-weight: 520;
  font-size: 16px;
  line-height: 1.5;
}
.ex.bare .ex-lead { font-size: 12px; margin-right: 4px; }
/* 两个例句块之间的「、」，留在原位置，不并进任何一边 */
.ex-sep {
  display: inline; font-size: 14px; color: var(--fg-3);
  margin: 0 1px; vertical-align: baseline;
}
/* 例句块内的第一行（lead + en）需要正常换行 */
.ex::after { content: ""; display: block; clear: both; }
.q-tag {
  display: inline-block; font-size: 9.5px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
  padding: 1.5px 5px; border-radius: 4px; margin-bottom: 7px;
  background: var(--surface-3); color: var(--fg-3);
}
.q-tag.ext { background: color-mix(in srgb, var(--ok) 16%, transparent); color: var(--ok); }

/* 结构公式 */
.formula {
  margin: 14px 0 12px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--ink);
  padding: 15px 17px;
  font-family: var(--mono); font-size: 14.5px; line-height: 1.8;
  color: var(--fg);
  white-space: pre-wrap; word-break: break-word;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.03);
}
.formula b { color: var(--acc); font-weight: 700; }
.formula .fn {
  display: block; margin-top: 9px; padding-top: 9px;
  border-top: 1px dashed var(--line-2);
  font-family: var(--font); font-size: 13.2px; line-height: 1.7; color: var(--fg-2);
}

/* 侧注：易错 / 口诀 */
.note {
  margin: 14px 0 4px;
  padding: 12px 14px 12px 15px;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  border-left: 2px solid var(--warn);
  background: color-mix(in srgb, var(--warn) 8%, transparent);
}
.note.tip { border-left-color: var(--ok); background: color-mix(in srgb, var(--ok) 8%, transparent); }
.note .note-h {
  display: flex; align-items: center; gap: 6px;
  font-size: 10.5px; font-weight: 750; letter-spacing: .1em;
  text-transform: uppercase; color: var(--warn); margin-bottom: 6px;
}
.note.tip .note-h { color: var(--ok); }
.note p { font-size: 14px; line-height: 1.78; color: var(--fg-2); margin: 0 0 7px; }
.note p:last-child { margin-bottom: 0; }
.note .note-body p { font-size: 14px; line-height: 1.8; color: var(--fg-2); margin: 0 0 8px; }
.note .note-body p:last-child { margin-bottom: 0; }
.note .note-body .quote { margin: 10px 0 8px; }
.note .note-body .q-en { font-size: 15px; }

/* 表格 */
.tbl { margin: 14px 0 6px; overflow-x: auto; border-radius: var(--r-xs); }
table.grid {
  width: 100%; border-collapse: collapse; font-size: 13.6px; min-width: 360px;
}
table.grid th {
  text-align: left; font-weight: 700; font-size: 10.5px;
  letter-spacing: .09em; text-transform: uppercase; color: var(--fg-2);
  padding: 8px 12px 8px 0; border-bottom: 1px solid var(--line-2);
  white-space: nowrap;
}
table.grid td {
  padding: 10px 12px 10px 0; border-bottom: 1px solid var(--line);
  vertical-align: top; line-height: 1.68; color: var(--fg-2);
  min-width: 76px;
}
/* 第一列通常是 while / as 这种短标签，别让它被压成竖排。
   注意：这里不能给 td 加 nowrap —— 有些表第一列就是整段英文长句，
   nowrap 会把它撑成一行四千像素，把后面几列全推出屏幕。 */
table.grid th:first-child { white-space: nowrap; }
/* 中间列别被最后一列的长文挤成三行 */
table.grid td:nth-child(2), table.grid th:nth-child(2) { min-width: 108px; }

/* ---- 长内容表格：逐条卡片 ---- */
.rec-list { margin: 14px 0 6px; }
.rec {
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface-2);
  padding: 15px 17px; margin-bottom: 10px;
}
.rec:last-child { margin-bottom: 0; }
.rec-v.main {
  font-size: 15.4px; line-height: 1.8; color: var(--fg-2);
  padding-bottom: 3px;
}
.rec-v.main.en { font-size: 16.2px; line-height: 1.74; color: var(--fg); }
.rec-row {
  display: grid; grid-template-columns: 62px minmax(0, 1fr);
  gap: 14px; padding: 8px 0;
}
.rec-row + .rec-row { border-top: 1px dashed var(--line); }
.rec-k {
  font-size: 11.5px; color: var(--fg-3); line-height: 1.75;
  padding-top: 2px;
}
.rec-v {
  font-size: 14.2px; line-height: 1.82; color: var(--fg-2);
  word-break: break-word;
}
.rec-v.en {
  font-family: var(--serif); font-size: 15.6px; line-height: 1.76;
  color: var(--fg);
}
table.grid tr:last-child td { border-bottom: none; }
table.grid td:first-child { color: var(--fg); }
table.grid code {
  font-family: var(--mono); font-size: 12.6px; color: var(--fg);
  background: var(--surface-2); padding: 1px 4px; border-radius: 3px;
}

/* 表格 / 步骤之后跟的说明文字 */
.card-note { margin: 12px 0 2px; }
.card-note p { font-size: 14px; line-height: 1.82; color: var(--fg-2); margin: 0 0 8px; }
.card-note p:last-child { margin-bottom: 0; }
.card-note .quote { margin: 10px 0 8px; }

/* 步骤 */
.steps-list { margin: 12px 0 4px; padding: 0; list-style: none; counter-reset: st; }
.steps-list li {
  position: relative; padding-left: 30px; margin-bottom: 12px;
  font-size: 15px; line-height: 1.82; color: var(--fg-2);
  counter-increment: st;
}
.steps-list li::before {
  content: counter(st, decimal-leading-zero);
  position: absolute; left: 0; top: 2px;
  font-family: var(--mono); font-size: 11px; font-weight: 700;
  color: var(--acc); opacity: .85;
}
.steps-list li::after {
  content: ""; position: absolute; left: 9px; top: 20px; bottom: -12px;
  width: 1px; background: var(--line);
}
.steps-list li:last-child::after { display: none; }

/* ==========================================================================
   可视化组件（viz）
   diagram  句子骨架：横向色块 + 箭头
   timeline 时态：迷你时间轴
   compare  双语 / 主被动 左右对照
   flow     判定流程：一步一亮
   ========================================================================== */
.viz {
  margin: 22px 0 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  padding: 18px 20px 16px;
  overflow: hidden;
}
.viz-h {
  display: flex; align-items: center; gap: 8px;
  font-size: 10.5px; font-weight: 750; letter-spacing: .11em;
  text-transform: uppercase; color: var(--acc);
  margin-bottom: 14px;
}
.viz-h::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--line); }
.viz-note {
  margin-top: 13px; font-size: 13.8px; line-height: 1.78; color: var(--fg-2);
}
.viz-note b, .viz-note strong { color: var(--fg); }

/* 入场动画：默认就是可见的；只有「还在视口下方」的元素才被加 .pre 先藏起来，
   滚到跟前再显形。这样 JS 出错 / IO 不触发也不会出现整块空白。 */
.viz [data-anim] {
  transition: opacity .5s ease, transform .55s cubic-bezier(.2, .8, .3, 1);
}
.viz [data-anim].pre {
  opacity: 0;
  transform: translateY(10px);
}

/* ---- diagram：句子骨架 ----
   Swiss / minimal：去掉大块淡色底，只用一根顶部色条标角色。
   两种淡色块并排是最"土"的根因——颜色承载不了角色，位置和线才能。
   宽度跟内容走（flex-basis:auto + 不增长），不再三等分撑满 —— 
   "She / is / a teacher." 撑到三个 330px 大白块是最刺眼的。 */
.dg { display: flex; flex-wrap: wrap; align-items: stretch; gap: 8px; justify-content: center; }
.dg-part {
  flex: 0 1 auto; min-width: 132px; max-width: 100%;
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  border-top: 3px solid var(--line-2);
  border-radius: 11px;
  background: var(--surface);
  padding: 10px 15px 12px;
  position: relative;
  text-align: center;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
}
.dg-part[data-tone="1"] { border-top-color: var(--acc); }
.dg-part[data-tone="2"] { border-top-color: var(--ok); }
.dg-k {
  font-size: 11.5px; font-weight: 700; letter-spacing: .09em;
  text-indent: .09em;          /* 抵消末字符后的字距，居中时才不偏右 */
  color: var(--fg-3); margin-bottom: 6px;
  white-space: nowrap;
}
.dg-part[data-tone="1"] .dg-k { color: color-mix(in srgb, var(--acc) 80%, var(--fg-2)); }
.dg-part[data-tone="2"] .dg-k { color: color-mix(in srgb, var(--ok) 82%, var(--fg-2)); }
.dg-v {
  font-family: var(--serif); font-size: 17.5px; line-height: 1.42; color: var(--fg);
  word-break: break-word;
}
.dg-v.cn { font-family: var(--font); font-size: 15px; color: var(--fg-2); }
.dg-arrow {
  flex: 0 0 auto; align-self: center;
  font-size: 13px; color: var(--fg-3); line-height: 1;
  padding: 0 3px;
}
.dg-cap {
  margin-top: 12px; font-size: 13.4px; color: var(--fg-3); line-height: 1.65;
}


/* ---- flow：竖向判定流程 ----
   之前这组类根本没有样式，所以它长得像一段 markdown 列表。 */
.viz-flow .fl {
  position: relative;
  display: flex; flex-direction: column;
}
.fl-step {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  column-gap: 18px;
  padding: 20px 0;
  border-top: 1px solid var(--line);
}
.fl-step:first-child { border-top: 0; padding-top: 6px; }
.fl-step:last-child { padding-bottom: 4px; }

.fl-rail { position: relative; display: flex; justify-content: center; }
.fl-rail::before {
  content: ''; position: absolute; left: 50%; top: 34px; bottom: -24px;
  width: 1px; transform: translateX(-50%);
  background: linear-gradient(180deg, var(--line-2), transparent);
}
.fl-step:last-child .fl-rail::before { display: none; }
.fl-dot {
  position: relative; z-index: 1;
  width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--mono); font-size: 13px; font-weight: 700; line-height: 1;
  color: var(--acc);
  background: color-mix(in srgb, var(--acc) 13%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--acc) 42%, transparent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--acc) 6%, transparent);
}

.fl-body { min-width: 0; }
.fl-q {
  font-size: 15px; font-weight: 640; color: var(--fg);
  line-height: 1.65; margin-bottom: 13px;
  letter-spacing: -0.005em;
}
.fl-demo {
  display: flex; align-items: center; gap: 11px; flex-wrap: wrap;
  padding: 12px 15px; border-radius: 11px;
  background: color-mix(in srgb, var(--fg) 4.5%, transparent);
  font-family: var(--serif); font-size: 16.5px; line-height: 1.5;
}
.fl-before { color: var(--fg-2); }
.fl-arrow { color: var(--fg-3); font-size: 14px; flex: 0 0 auto; }
.fl-after { color: var(--fg); font-weight: 600; }
.fl-mark { font-size: 15px; font-weight: 800; flex: 0 0 auto; }
.fl-mark.ok { color: var(--ok); }
.fl-mark.bad { color: var(--bad, #e2574c); }

.fl-verdict {
  display: inline-block; margin-top: 13px;
  padding: 7px 15px; border-radius: 9px;
  font-size: 13.5px; font-weight: 720; letter-spacing: .01em;
  color: var(--acc);
  background: color-mix(in srgb, var(--acc) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--acc) 28%, transparent);
}
.fl-verdict.ok {
  color: var(--ok);
  background: color-mix(in srgb, var(--ok) 12%, transparent);
  border-color: color-mix(in srgb, var(--ok) 32%, transparent);
}
.fl-verdict.bad {
  color: var(--bad, #e2574c);
  background: color-mix(in srgb, var(--bad, #e2574c) 12%, transparent);
  border-color: color-mix(in srgb, var(--bad, #e2574c) 32%, transparent);
}
.fl-a {
  margin-top: 13px; font-size: 13.8px; color: var(--fg-2); line-height: 1.8;
}
@media (max-width: 640px) {
  .fl-step { grid-template-columns: 32px minmax(0, 1fr); column-gap: 13px; }
  .fl-dot { width: 26px; height: 26px; font-size: 11.5px; }
  .fl-demo { font-size: 15px; padding: 10px 12px; }
}

/* ---- 可视化实验台 ----
   原则：句子是主体，控件退到旁边；一切动效都在回答"这句话为什么成立/为什么不成立"。 */
.lab {
  position: relative;
  margin: 22px 0 10px;
  padding: 20px 22px 22px;
  border-radius: 18px;
  border: 1px solid color-mix(in srgb, var(--acc) 22%, var(--line-2));
  background:
    radial-gradient(130% 120% at 50% -20%, color-mix(in srgb, var(--acc) 15%, transparent), transparent 62%),
    var(--surface-2);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 8%, transparent),
    inset 0 -1px 0 color-mix(in srgb, #000 12%, transparent),
    0 26px 54px -34px rgba(0, 0, 0, .6),
    0 4px 12px -7px rgba(0, 0, 0, .3);
  overflow: hidden;
}
.lab::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--acc), transparent);
  opacity: .8;
}
.lab-hd { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.lab-tag {
  font-size: 10.5px; font-weight: 780; letter-spacing: .1em; text-indent: .1em;
  color: var(--acc); background: color-mix(in srgb, var(--acc) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--acc) 36%, transparent);
  padding: 3px 10px; border-radius: 6px; white-space: nowrap;
}
.lab-t { font-size: 12.6px; color: var(--fg-2); line-height: 1.6; }
.lab-reset {
  margin-top: 16px; font: inherit; font-size: 12.2px; font-weight: 640;
  color: var(--fg-2); background: color-mix(in srgb, var(--fg) 5%, transparent);
  border: 1px solid var(--line-2); border-radius: 8px;
  padding: 7px 14px; cursor: pointer; transition: border-color .18s, color .18s, background .18s;
}
.lab-reset:hover { color: var(--fg); border-color: var(--acc); background: color-mix(in srgb, var(--acc) 12%, transparent); }

/* ---- 1. 阶梯 ---- */
.st-stage { display: flex; align-items: flex-end; gap: 6px; padding: 6px 0 0; }
.st-step {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; gap: 4px; align-items: flex-start;
  padding: 10px 12px calc(10px + var(--i) * 18px);
  border-radius: 10px 10px 5px 5px;
  background: linear-gradient(180deg, var(--surface), color-mix(in srgb, var(--acc) 7%, var(--surface-2)));
  border: 1px solid var(--line-2);
  border-bottom: 4px solid color-mix(in srgb, var(--acc) 34%, var(--line-2));
  box-shadow: 0 10px 20px -18px rgba(0, 0, 0, .5);
  font: inherit; text-align: left; cursor: pointer;
  transition: transform .26s cubic-bezier(.2, .8, .3, 1), border-color .2s, background .2s, box-shadow .2s;
}
.st-step:hover { transform: translateY(-2px); }
.st-step.on {
  border-bottom-color: var(--acc);
  background: linear-gradient(180deg, color-mix(in srgb, var(--acc) 18%, var(--surface)), var(--surface));
  transform: translateY(-4px);
  box-shadow: 0 14px 26px -20px color-mix(in srgb, var(--acc) 90%, transparent);
}
.st-n { font-family: var(--mono); font-size: 11px; font-weight: 700; color: var(--acc); }
.st-t { font-size: 12.3px; color: var(--fg-3); line-height: 1.35; }
.st-step.on .st-t { color: var(--fg); font-weight: 640; }
.st-panes { margin-top: 18px; }
.st-pane { display: none; }
.st-pane.on { display: block; animation: labIn .3s ease both; }
.st-pt { font-size: 13.4px; font-weight: 700; color: var(--fg); margin-bottom: 7px; }
.st-pt b { font-family: var(--mono); color: var(--acc); margin-right: 8px; }
.st-pd { font-size: 13.4px; color: var(--fg-2); line-height: 1.8; }
@keyframes labIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* 右侧承重表：既是图例，也是一块控制面 */
.xr-wrap {
  display: grid; grid-template-columns: minmax(0, 1fr) 244px;
  gap: 22px; align-items: start;
}
.xr-main { min-width: 0; }
.xr-panel {
  position: sticky; top: 96px;
  border: 1px solid var(--line-2); border-radius: 14px;
  background: linear-gradient(180deg, var(--surface), color-mix(in srgb, var(--fg) 3%, var(--surface)));
  padding: 14px 12px 12px;
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 8%, transparent),
    0 16px 30px -24px rgba(0, 0, 0, .5);
}
.xp-title {
  font-size: 10.5px; font-weight: 780; letter-spacing: .1em;
  color: var(--fg-3); margin-bottom: 10px; padding-left: 8px;
}
.xp-head {
  display: grid; grid-template-columns: 1fr 20px 20px;
  gap: 10px; align-items: center;
  padding: 0 8px 6px; margin-bottom: 2px;
  font-family: var(--mono); font-size: 9.5px; color: var(--fg-3);
  border-bottom: 1px solid var(--line);
}
.xp-head span:not(:first-child) { text-align: center; }
.xp-row {
  display: grid; grid-template-columns: 1fr 20px 20px;
  gap: 10px; align-items: center;
  padding: 9px 8px; border-radius: 8px; cursor: pointer;
  transition: background .18s;
}
.xp-row:hover { background: color-mix(in srgb, var(--acc) 9%, transparent); }
.xp-row.on {
  background: color-mix(in srgb, var(--acc) 15%, transparent);
  box-shadow: inset 2px 0 0 var(--acc);
}
.xp-name { font-size: 12.4px; color: var(--fg-2); }
.xp-row.on .xp-name { color: var(--fg); font-weight: 660; }
.xp-dot {
  width: 13px; height: 13px; border-radius: 50%;
  justify-self: center; transition: all .3s;
}
.xp-dot[data-dead="1"] {
  background: var(--bad, #e2574c);
  box-shadow: 0 0 9px color-mix(in srgb, var(--bad, #e2574c) 70%, transparent);
}
.xp-dot[data-dead="0"] {
  background: transparent;
  border: 2px dashed color-mix(in srgb, var(--ok) 75%, transparent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--ok) 35%, transparent);
}
.xp-foot {
  margin-top: 10px; padding: 8px 8px 0; border-top: 1px solid var(--line);
  font-size: 10.5px; line-height: 1.7; color: var(--fg-3);
}
@media (max-width: 900px) {
  .xr-wrap { grid-template-columns: 1fr; }
  .xr-panel { position: static; }
  .xp-row { padding: 7px 8px; }
}
/* ---- 2. X 光透视台 ---- */
.xr-stage { margin-bottom: 20px; }
.xr-led {
  display: flex; align-items: center; gap: 8px; margin-bottom: 9px;
  font-size: 11px; font-weight: 750; letter-spacing: .1em; color: var(--fg-3);
}
.xr-led i {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--bad, #e2574c); box-shadow: 0 0 8px var(--bad, #e2574c);
}
.xr-stage[data-side="cn"] .xr-led i { background: var(--ok); box-shadow: 0 0 8px var(--ok); }
.xr-frame {
  position: relative; padding: 30px 18px 14px;
  /* 宽度贴合句子：固定满宽时短句右边会空出一大片，看着像"另一个空框" */
  display: inline-block; max-width: 100%; min-width: 220px;
  border-radius: 12px; border: 1px solid var(--line);
  border-left: 3px solid color-mix(in srgb, var(--acc) 55%, transparent);
  background:
    repeating-linear-gradient(0deg, color-mix(in srgb, var(--acc) 5%, transparent) 0 1px, transparent 1px 15px),
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--acc) 5%, transparent) 0 1px, transparent 1px 15px),
    linear-gradient(180deg, color-mix(in srgb, var(--acc) 7%, transparent), transparent 72%);
}
.xr-stage[data-side="en"] .xr-frame { border-left-color: color-mix(in srgb, var(--bad, #e2574c) 50%, transparent); }
.xr-stage.is-dead .xr-frame { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--bad, #e2574c) 26%, transparent); }

.xr-sent {
  position: relative; z-index: 1; white-space: pre-wrap;
  display: block; width: fit-content; max-width: 100%;
  font-family: var(--serif); font-size: clamp(19px, 2.1vw, 25px); line-height: 1.9;
  color: var(--fg); transition: color .3s;
}
.xr-w {
  position: relative; display: inline-block; padding: 1px 1px;
  cursor: pointer; transition: transform .2s, color .2s;
  border-bottom: 1px solid transparent;
}
.xr-w b { display: inline-block; font-weight: 500; }
.xr-tag {
  position: absolute; left: 50%; top: -15px;
  transform: translateX(-50%) translateY(5px);
  font-family: var(--font); font-size: 9.5px; font-style: normal; font-weight: 750;
  letter-spacing: .08em; color: var(--acc); white-space: nowrap;
  opacity: 0; transition: opacity .18s, transform .18s; pointer-events: none;
}
.xr-w:hover { transform: translateY(-2px); color: var(--acc); border-bottom-color: var(--acc); }
.xr-w:hover .xr-tag { opacity: 1; transform: translateX(-50%) translateY(0); }
.xr-w.out { color: transparent; border-bottom-color: transparent; cursor: pointer; min-width: 1em; }
.xr-w.out b { animation: suck .5s cubic-bezier(.4, 0, .6, 1) both; }
@keyframes suck {
  0% { transform: translateY(0) scale(1) rotate(0); opacity: 1; filter: blur(0); }
  55% { transform: translateY(-24px) scale(.88) rotate(-3deg); opacity: .45; filter: blur(1px); }
  100% { transform: translateY(-36px) scale(.8) rotate(-5deg); opacity: 0; filter: blur(3px); }
}
.xr-w.out::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 3px; height: 1.35em;
  border: 2px dashed color-mix(in srgb, var(--acc) 72%, transparent);
  border-radius: 6px;
  background: color-mix(in srgb, var(--acc) 9%, transparent);
  /* 等文字飞走（.5s）之后再显形，否则虚框会压在还在飞的字上，看着像"交叉" */
  animation: holeIn .3s .46s ease both;
}
@keyframes holeIn { from { opacity: 0; transform: scale(.55); } to { opacity: 1; transform: none; } }
.xr-floor {
  height: 2px; margin-top: 22px; border-radius: 2px;
  background: var(--line-2); transition: all .34s;
}
.xr-stage.is-dead .xr-floor {
  height: 3px; background: none;
  background-image: linear-gradient(90deg,
    var(--bad, #e2574c) 0 40%, transparent 40% 60%, var(--bad, #e2574c) 60% 100%);
  box-shadow: 0 3px 10px -3px color-mix(in srgb, var(--bad, #e2574c) 75%, transparent);
}
.xr-stage.is-dead .xr-sent {
  color: var(--bad, #e2574c);
  animation: collapse .5s cubic-bezier(.3, 0, .4, 1) both;
}
@keyframes collapse {
  0% { transform: translateY(0) skewX(0); }
  45% { transform: translateY(6px) skewX(-1.4deg); }
  100% { transform: translateY(3px) skewX(0); }
}
.xr-verdict, .rl-verdict {
  margin-top: 12px; font-size: 13px; line-height: 1.72; color: var(--fg-3);
}
.xr-verdict.is-ok, .rl-verdict.is-ok { color: var(--ok); }
.xr-verdict.is-bad, .rl-verdict.is-bad { color: var(--bad, #e2574c); font-weight: 640; }

/* ---- 3. 语序轨道 ---- */
.rl-switch {
  display: inline-flex; gap: 2px; padding: 3px; margin-bottom: 16px;
  border-radius: 9px; background: color-mix(in srgb, var(--fg) 6%, transparent);
  border: 1px solid var(--line-2);
}
.rl-switch button {
  font: inherit; font-size: 12.3px; font-weight: 640; padding: 5px 16px;
  border: 0; border-radius: 7px; background: none; color: var(--fg-3);
  cursor: pointer; transition: all .18s;
}
.rl-switch button.on { background: var(--surface); color: var(--fg); box-shadow: 0 1px 4px rgba(0, 0, 0, .12); }
.rl-set { display: none; }
.rl-set.on { display: block; animation: labIn .3s ease both; }
.rl-slots { display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); gap: 10px; margin-bottom: 2px; }
.rl-slot {
  min-width: 0; text-align: center;
  font-size: 10.5px; font-weight: 750; letter-spacing: .08em;
  color: var(--fg-3); padding: 3px 0;
  border-bottom: 1px dashed var(--line-2);
}
.rl-set[data-rlset="en"] .rl-slot { color: var(--acc); border-bottom-color: color-mix(in srgb, var(--acc) 45%, transparent); }
.rl-track { position: relative; padding: 78px 0 28px; }   /* 顶部留出抬升空间，否则飞起来会被 .lab 的 overflow 裁掉 */
.rl-line {
  position: absolute; left: 0; right: 0; bottom: 6px; height: 9px;
  background:
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--acc) 26%, transparent) 0 1.5px, transparent 1.5px 19px),
    linear-gradient(180deg, transparent 4px, var(--line-2) 4px 6px, transparent 6px);
  opacity: .55;
}
.rl-cars { position: relative; display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); gap: 10px; }
.rl-car {
  position: relative; display: flex; align-items: center; justify-content: center;
  min-width: 0; padding: 11px 10px; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--line-2);
  font-family: var(--serif); font-size: 17px; color: var(--fg);
  cursor: pointer; box-shadow: 0 2px 0 color-mix(in srgb, var(--fg) 7%, transparent);
  transition: border-color .18s, background .18s, box-shadow .2s;
}
.rl-car b { font-weight: 500; }
.rl-car::after {
  content: ''; position: absolute; left: 50%; bottom: -13px; width: 8px; height: 8px;
  transform: translateX(-50%) rotate(45deg);
  background: var(--surface); border-right: 1px solid var(--line-2); border-bottom: 1px solid var(--line-2);
  transition: border-color .18s;
}
.rl-car:hover { border-color: var(--acc); }
.rl-car.pick {
  border-color: var(--acc); background: color-mix(in srgb, var(--acc) 14%, var(--surface));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 24%, transparent), 0 2px 0 transparent;
}
.rl-car.glide {
  z-index: 6;
  border-color: color-mix(in srgb, var(--acc) 75%, transparent);
  box-shadow:
    0 6px 0 color-mix(in srgb, var(--acc) 28%, transparent),
    0 26px 34px -14px rgba(0, 0, 0, .55),
    0 50px 60px -40px rgba(0, 0, 0, .4);
}
.rl-car.bad { border-color: color-mix(in srgb, var(--bad, #e2574c) 70%, transparent); }
.lab-rail.rl-locked .rl-car {
  border-color: color-mix(in srgb, var(--ok) 60%, transparent);
  background: color-mix(in srgb, var(--ok) 10%, var(--surface));
}

/* ---- 操作引导 ---- */
.lab-guide {
  display: flex; align-items: center; gap: 9px;
  margin: -2px 0 16px; padding: 9px 14px;
  border-radius: 10px;
  background: linear-gradient(90deg, color-mix(in srgb, var(--acc) 16%, transparent), transparent 85%);
  border: 1px dashed color-mix(in srgb, var(--acc) 45%, transparent);
  font-size: 12.6px; color: var(--fg); font-weight: 620;
  animation: labIn .45s ease both;
}
.lg-hand {
  display: grid; place-items: center; flex: 0 0 auto;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--acc); color: #fff;
  animation: handTap 1.7s ease-in-out infinite;
}
@keyframes handTap {
  0%, 100% { transform: translateY(0) scale(1); box-shadow: 0 0 0 0 color-mix(in srgb, var(--acc) 55%, transparent); }
  45% { transform: translateY(-3px) scale(1.05); box-shadow: 0 0 0 9px color-mix(in srgb, var(--acc) 0%, transparent); }
}
.lab.used .lab-guide { display: none; }

/* ---- 4. 手术台：错译与正译同屏 ---- */
.sg-nav { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.sg-nav button {
  width: 28px; height: 28px; border-radius: 50%;
  border: 1px solid var(--line-2); background: var(--surface); color: var(--fg-2);
  cursor: pointer; font-size: 15px; line-height: 1; padding-bottom: 2px;
  box-shadow: 0 2px 0 color-mix(in srgb, var(--fg) 8%, transparent);
  transition: border-color .18s, color .18s, transform .1s;
}
.sg-nav button:hover { border-color: var(--acc); color: var(--acc); }
.sg-nav button:active { transform: translateY(2px); box-shadow: none; }
.sg-nav span { font-family: var(--mono); font-size: 11.5px; color: var(--fg-3); letter-spacing: .06em; }
.sg-case { display: none; }
.sg-case.on { display: block; animation: labIn .28s ease both; }
.sg-zh { font-size: 12.4px; color: var(--fg-3); margin-bottom: 14px; }
.sg-zh::before { content: '中文 · '; opacity: .55; }

.sg-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 96px minmax(0, 1fr);
  align-items: stretch;
}
.sg-col {
  padding: 15px 16px 17px; border-radius: 14px;
  border: 1px solid var(--line-2);
  background: linear-gradient(180deg, var(--surface), color-mix(in srgb, var(--fg) 3%, var(--surface)));
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 8%, transparent),
    0 14px 26px -22px rgba(0, 0, 0, .5);
  transition: border-color .32s, box-shadow .32s;
}
.sg-left { border-color: color-mix(in srgb, var(--bad, #e2574c) 36%, var(--line-2)); }
.sg-right { border-color: color-mix(in srgb, var(--ok) 36%, var(--line-2)); }
.sg-case.done .sg-left { border-color: var(--line-2); opacity: .82; }
.sg-case.done .sg-right {
  border-color: color-mix(in srgb, var(--ok) 70%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 10%, transparent),
    0 0 0 3px color-mix(in srgb, var(--ok) 12%, transparent),
    0 16px 30px -24px color-mix(in srgb, var(--ok) 80%, transparent);
}
.sg-cap {
  display: flex; align-items: center; gap: 7px;
  font-size: 10.5px; font-weight: 780; letter-spacing: .1em;
  margin-bottom: 10px;
}
.sg-cap i { width: 7px; height: 7px; border-radius: 50%; }
.sg-cap.bad { color: var(--bad, #e2574c); }
.sg-cap.bad i { background: var(--bad, #e2574c); box-shadow: 0 0 8px var(--bad, #e2574c); }
.sg-cap.ok { color: var(--ok); }
.sg-cap.ok i { background: var(--ok); box-shadow: 0 0 8px var(--ok); }
.sg-cap.spent { color: var(--fg-3); }
.sg-cap.spent i { background: var(--fg-3); box-shadow: none; }
.sg-cap.fixed { color: var(--ok); }
.sg-line {
  font-family: var(--serif); font-size: clamp(16px, 1.7vw, 20px); line-height: 1.75;
  color: var(--fg-2); overflow-wrap: anywhere;
}
.sg-bad {
  position: relative; display: inline-block; font-style: normal; font-weight: 620;
  color: var(--bad, #e2574c);
  border-bottom: 2px solid color-mix(in srgb, var(--bad, #e2574c) 48%, transparent);
  animation: badGlow 1.9s ease-in-out infinite;
}
@keyframes badGlow {
  0%, 100% { text-shadow: 0 0 0 transparent; }
  50% { text-shadow: 0 0 15px color-mix(in srgb, var(--bad, #e2574c) 60%, transparent); }
}
.sg-bad.shattered {
  color: transparent; border-bottom-style: dashed;
  border-bottom-color: color-mix(in srgb, var(--fg-3) 40%, transparent);
  min-width: 2em;
}
.sg-bad.gone {
  color: color-mix(in srgb, var(--bad, #e2574c) 50%, transparent);
  text-decoration: line-through; text-decoration-thickness: 2px;
  border-bottom-color: transparent;
  text-shadow: none; animation: none; min-width: 0;
}
.sg-slot {
  display: inline-block; min-width: 2.4em; text-align: center;
  font-style: normal; font-weight: 700; color: var(--acc);
  padding: 1px 10px; margin: 0 2px;
  border: 2px dashed color-mix(in srgb, var(--acc) 68%, transparent);
  border-radius: 7px;
  background: color-mix(in srgb, var(--acc) 9%, transparent);
  animation: slotPulse 1.9s ease-in-out infinite;
}
@keyframes slotPulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--acc) 42%, transparent); }
  50% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--acc) 0%, transparent); }
}
.sg-slot.filled {
  border-style: solid; border-color: var(--ok); color: var(--ok);
  background: color-mix(in srgb, var(--ok) 13%, transparent);
  animation: slotIn .52s cubic-bezier(.2, .9, .3, 1) both;
}
@keyframes slotIn {
  0% { transform: translateY(-16px) scale(.8); opacity: .3; filter: blur(4px); }
  60% { transform: translateY(2px) scale(1.06); opacity: 1; filter: none; }
  100% { transform: none; }
}
.sg-arrow {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 7px; padding: 0 6px;
}
.sg-arrow i {
  width: 100%; height: 2px; position: relative;
  background: repeating-linear-gradient(90deg, color-mix(in srgb, var(--acc) 62%, transparent) 0 6px, transparent 6px 12px);
  transition: background .3s;
}
.sg-arrow i::after {
  content: ''; position: absolute; right: -1px; top: -4px;
  border: 5px solid transparent; border-left-color: var(--acc);
  transition: border-color .3s;
}
.sg-arrow b {
  font-size: 9.5px; font-weight: 780; color: var(--acc);
  letter-spacing: .05em; white-space: nowrap;
}
.sg-case.done .sg-arrow i { background: var(--ok); }
.sg-case.done .sg-arrow i::after { border-left-color: var(--ok); }
.sg-case.done .sg-arrow b { color: var(--ok); }

.sg-foot { display: flex; align-items: flex-start; gap: 18px; margin-top: 18px; flex-wrap: wrap; }
.sg-go {
  flex: 0 0 auto; font: inherit; font-size: 13px; font-weight: 720;
  padding: 10px 21px; border-radius: 11px; border: 1px solid color-mix(in srgb, var(--acc) 80%, #000);
  background: linear-gradient(180deg, color-mix(in srgb, var(--acc) 92%, #fff), var(--acc));
  color: #fff; cursor: pointer;
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 30%, transparent),
    0 4px 0 color-mix(in srgb, var(--acc) 45%, #000),
    0 12px 22px -10px color-mix(in srgb, var(--acc) 75%, transparent);
  transition: transform .1s, box-shadow .1s, filter .2s;
}
.sg-go:hover { filter: brightness(1.07); }
.sg-go:active {
  transform: translateY(4px);
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 20%, transparent), 0 0 0 color-mix(in srgb, var(--acc) 45%, #000);
}
.lab:not(.used) .sg-go { animation: goBreathe 2s ease-in-out infinite; }
@keyframes goBreathe {
  0%, 100% { filter: brightness(1); }
  50% { filter: brightness(1.14); }
}
.sg-why { flex: 1 1 200px; font-size: 12.8px; color: var(--fg-2); line-height: 1.72; }
.sg-why b { color: var(--fg); }

/* 碎片（shatter 生成） */
.sw-shard {
  position: absolute; left: 0; top: 0; white-space: nowrap; pointer-events: none;
  animation: shardFly .66s cubic-bezier(.3, 0, .6, 1) forwards;
}
@keyframes shardFly {
  0% { transform: translate(0, 0) rotate(0); opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) rotate(var(--dr)); opacity: 0; filter: blur(2.5px); }
}

@media (max-width: 760px) {
  .sg-grid { grid-template-columns: 1fr; gap: 10px; }
  .sg-arrow { flex-direction: row; gap: 8px; }
  .sg-arrow i { width: 40px; }
  .sg-arrow i::after { right: -1px; top: -4px; }
}

/* ---- 5. 松紧对照 ---- */
.mr-switch {
  display: inline-flex; gap: 2px; padding: 3px; margin-bottom: 18px;
  border-radius: 9px; background: color-mix(in srgb, var(--fg) 6%, transparent);
  border: 1px solid var(--line-2);
}
.mr-switch button {
  font: inherit; font-size: 12.3px; font-weight: 640; padding: 5px 17px;
  border: 0; border-radius: 7px; background: none; color: var(--fg-3);
  cursor: pointer; transition: all .18s;
}
.mr-switch button.on { background: var(--surface); color: var(--fg); box-shadow: 0 1px 4px rgba(0, 0, 0, .12); }

.mr-rows { display: flex; flex-direction: column; }
.mr-row {
  display: grid; grid-template-columns: 56px 128px minmax(0, 1fr);
  align-items: center; gap: 18px;
  padding: 14px 0; border-top: 1px solid var(--line);
}
.mr-row:first-child { border-top: 0; }
.mr-name {
  font-size: 11px; font-weight: 780; letter-spacing: .1em;
  color: var(--fg-3); white-space: nowrap;
}

/* 主谓宾：空心虚线圈 → 实心块 */
.mr-dots { display: flex; gap: 9px; align-items: center; }
.mr-dots i {
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px dashed color-mix(in srgb, var(--fg-3) 62%, transparent);
  background: transparent;
  transition: all .5s cubic-bezier(.2, .8, .3, 1);
}
.lab-mirror.en .mr-dots i {
  border-style: solid; border-color: var(--ok);
  background: color-mix(in srgb, var(--ok) 88%, transparent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--ok) 55%, transparent);
  transform: scale(1.08);
}
.lab-mirror.en .mr-dots i:nth-child(2) { transition-delay: .07s; }
.lab-mirror.en .mr-dots i:nth-child(3) { transition-delay: .14s; }

/* 语序：高低错落 → 对齐到基线 */
.mr-order { display: flex; gap: 8px; align-items: flex-end; position: relative; height: 28px; }
.mr-order b {
  width: 28px; height: 19px; border-radius: 4px;
  background: color-mix(in srgb, var(--fg-3) 20%, transparent);
  border: 1px solid color-mix(in srgb, var(--fg-3) 34%, transparent);
  transition: all .5s cubic-bezier(.2, .8, .3, 1);
}
.mr-order b:nth-child(1) { transform: translateY(-9px); }
.mr-order b:nth-child(2) { transform: translateY(5px); }
.mr-order b:nth-child(3) { transform: translateY(-4px); }
.mr-base {
  position: absolute; left: 0; right: 0; bottom: 0; height: 1.5px;
  background: var(--ok); opacity: 0; transition: opacity .4s .1s;
}
.lab-mirror.en .mr-order b {
  transform: none;
  background: color-mix(in srgb, var(--ok) 72%, transparent);
  border-color: var(--ok);
}
.lab-mirror.en .mr-order b:nth-child(2) { transition-delay: .06s; }
.lab-mirror.en .mr-order b:nth-child(3) { transition-delay: .12s; }
.lab-mirror.en .mr-base { opacity: 1; }

/* 语法：断续斜线 → 笔直实线 */
.mr-rule u {
  display: block; height: 3px; width: 100%; border-radius: 2px; text-decoration: none;
  background: repeating-linear-gradient(90deg,
    color-mix(in srgb, var(--fg-3) 48%, transparent) 0 5px, transparent 5px 11px);
  transform: skewY(3deg);
  transition: all .5s cubic-bezier(.2, .8, .3, 1);
}
.lab-mirror.en .mr-rule u {
  background: var(--ok); transform: none;
  box-shadow: 0 0 12px color-mix(in srgb, var(--ok) 55%, transparent);
}

/* 文案：中文说法 ↔ 英文说法 交叉淡化 */
.mr-text { position: relative; min-height: 24px; }
.mr-cn, .mr-en {
  display: block; font-size: 13.4px; line-height: 1.6;
  transition: opacity .38s, transform .38s;
}
.mr-cn { color: var(--fg-2); }
.mr-en {
  position: absolute; left: 0; top: 0;
  color: var(--fg); font-weight: 640;
  opacity: 0; transform: translateY(7px);
}
.lab-mirror.en .mr-cn { opacity: 0; transform: translateY(-7px); }
.lab-mirror.en .mr-en { opacity: 1; transform: none; }

.mr-verdict {
  margin-top: 16px; font-size: 13px; color: var(--fg-2); line-height: 1.75;
  padding: 12px 15px; border-radius: 10px;
  background: color-mix(in srgb, var(--fg) 5%, transparent);
  border-left: 3px solid var(--acc);
}
.mr-verdict .mr-v { display: none; animation: labIn .36s ease both; }
.lab-mirror:not(.en) .mr-verdict .mr-v.cn { display: block; }
.lab-mirror.en .mr-verdict .mr-v.en { display: block; }
@media (max-width: 720px) {
  .mr-row { grid-template-columns: 48px 100px minmax(0, 1fr); gap: 12px; }
  .mr-cn, .mr-en { font-size: 12.4px; }
}


/* ---- 6. 骨架装配 ---- */
.fr-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 22px; }
.fr-chip {
  display: flex; flex-direction: column; gap: 2px; align-items: flex-start;
  padding: 9px 16px; border-radius: 10px; font: inherit;
  border: 1px solid var(--line-2);
  background: linear-gradient(180deg, var(--surface), color-mix(in srgb, var(--fg) 4%, var(--surface)));
  box-shadow: 0 3px 0 color-mix(in srgb, var(--fg) 9%, transparent);
  cursor: pointer;
  transition: transform .2s cubic-bezier(.2, .8, .3, 1), border-color .18s, box-shadow .2s, background .2s;
}
.fr-chip b { font-family: var(--serif); font-size: 15.5px; font-weight: 600; color: var(--fg); line-height: 1.2; }
.fr-chip span { font-size: 10px; letter-spacing: .06em; color: var(--fg-3); }
.fr-chip:hover { border-color: var(--acc-line); transform: translateY(-1px); }
.fr-chip.on {
  border-color: var(--acc);
  background: linear-gradient(180deg, color-mix(in srgb, var(--acc) 18%, var(--surface)), var(--surface));
  box-shadow:
    0 4px 0 color-mix(in srgb, var(--acc) 45%, #000),
    0 16px 24px -18px color-mix(in srgb, var(--acc) 80%, transparent);
  transform: translateY(-2px);
}
.fr-chip.on b { color: var(--acc); }

.fr-stage { min-height: 78px; }   /* 只留一行槽位的高度，切换动词时不会跳动，也不空一大片 */
.fr-line { display: none; gap: 10px; flex-wrap: wrap; }
.fr-line.on { display: flex; }
.fr-slot {
  flex: 0 1 auto; min-width: 96px; max-width: 100%;
  padding: 11px 15px 13px; border-radius: 11px;
  border: 1px solid var(--line-2);
  background: linear-gradient(180deg, var(--surface), color-mix(in srgb, var(--fg) 3%, var(--surface)));
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 8%, transparent),
    0 12px 22px -18px rgba(0, 0, 0, .5);
  text-align: center;          /* 和 diagram 槽位一致：框里的词居中 */
  animation: slotRise .44s cubic-bezier(.2, .9, .3, 1) both;
  animation-delay: calc(var(--i, 0) * 75ms);
}
@keyframes slotRise {
  from { opacity: 0; transform: translateY(16px) scale(.95); }
  to { opacity: 1; transform: none; }
}
.fr-k { display: block; font-size: 10px; font-weight: 780; letter-spacing: .08em; text-indent: .08em; color: var(--acc); margin-bottom: 7px; }
.fr-v { font-family: var(--serif); font-size: 16.5px; color: var(--fg); }
.fr-why { margin-top: 18px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }
.fr-w { display: none; }
.fr-w.on { display: block; animation: labIn .3s ease both; }

/* ---- 7. 加 be 判断 ---- */
.bt-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 20px; }
.bt-tabs button {
  font: inherit; font-size: 12.2px; padding: 6px 15px; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--fg-3);
  cursor: pointer; transition: all .18s;
}
.bt-tabs button.on {
  color: #fff; background: var(--acc); border-color: var(--acc);
  box-shadow: 0 3px 0 color-mix(in srgb, var(--acc) 45%, #000);
}
.bt-case { display: none; }
.bt-case.on { display: block; animation: labIn .28s ease both; }

.bt-sent {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0;
  font-family: var(--serif); font-size: clamp(18px, 2vw, 22px); line-height: 1.9;
  color: var(--fg);
}
.bt-case.done .bt-case.done.bad .bt-go {
  margin-top: 18px; font: inherit; font-size: 13px; font-weight: 720;
  padding: 10px 21px; border-radius: 11px;
  border: 1px solid color-mix(in srgb, var(--acc) 80%, #000);
  background: linear-gradient(180deg, color-mix(in srgb, var(--acc) 92%, #fff), var(--acc));
  color: #fff; cursor: pointer;
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 30%, transparent),
    0 4px 0 color-mix(in srgb, var(--acc) 45%, #000),
    0 12px 22px -10px color-mix(in srgb, var(--acc) 75%, transparent);
  transition: transform .1s, box-shadow .1s, filter .2s;
}
.bt-case.done .bt-go {
  background: transparent; color: var(--fg-2);
  border: 1px solid var(--line-2); box-shadow: none;
  font-weight: 620; padding: 7px 15px; font-size: 12.4px;
}
.bt-go:hover { filter: brightness(1.06); }
.bt-go:active {
  transform: translateY(4px);
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 20%, transparent), 0 0 0 color-mix(in srgb, var(--acc) 45%, #000);
}
.bt-case.done .bt-judge { margin-top: 9px; font-size: 13.5px; font-weight: 720; }
.bt-judge.is-ok { color: var(--ok); }
.bt-judge.is-bad { color: var(--bad, #e2574c); }
.bt-case.done.bad .bt-sent { animation: deadShake .44s ease; }
.bt-why { margin-top: 12px; font-size: 13px; color: var(--fg-2); line-height: 1.76; }

.bt-sent {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0;
  font-family: var(--serif); font-size: clamp(18px, 2vw, 22px); line-height: 1.9;
  color: var(--fg-2);
}
.bt-sent > span { white-space: pre; }
.bt-chunk, .bt-verb {
  position: relative; display: inline-block;
  font-style: normal; color: var(--fg); font-weight: 600;
  padding: 1px 9px; margin: 0 2px; border-radius: 7px;
  background: color-mix(in srgb, var(--acc) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--acc) 34%, transparent);
  transition: all .3s cubic-bezier(.2, .8, .3, 1);
}
/* 拎走之后原位留一个虚线空槽，一眼看出"这块被搬下去了" */
.bt-chunk.lifted {
  opacity: .32; transform: translateY(-8px) scale(.94);
  background: transparent; border-style: dashed;
}
/* 换动词模式：原词划掉留在原位，新句子在下面，避免上下两行一模一样 */
.bt-verb.replaced {
  opacity: .42; background: transparent; border-style: dashed;
  text-decoration: line-through; text-decoration-thickness: 1.5px;
  text-decoration-color: color-mix(in srgb, var(--acc) 60%, transparent);
}
.bt-hint {
  margin-top: 12px; font-size: 12.6px; color: var(--fg-3); line-height: 1.65;
  transition: opacity .3s ease;
}
.bt-case.done .bt-hint { opacity: .48; }

.bt-pair {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 18px; padding: 0;
  max-height: 0; overflow: hidden; opacity: 0;
  transition: max-height .4s ease, opacity .34s ease, margin-top .3s ease;
}
.bt-case.done .bt-pair {
  max-height: 150px; opacity: 1;
}
/* 试验台上方一句话，说清"下面这行是什么" */
.bt-pair::before {
  content: '↓ 换成 be 之后：';
  flex: 0 0 100%; margin-bottom: 4px;
  font-family: var(--sans); font-size: 12.3px; font-weight: 600; letter-spacing: .01em;
  color: var(--fg-2);
}
.bt-case[data-mode="chunk"] .bt-pair::before {
  content: '↓ 把这两块单独拎出来，拼成一句话：';
}
.bt-piece {
  display: inline-block;
  padding: 9px 15px; border-radius: 10px;
  font-family: var(--serif); font-size: 17px; color: var(--fg);
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--line-2) 70%, transparent);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
}
.bt-case.done .bt-piece {
  animation: pieceIn .44s cubic-bezier(.2, .9, .3, 1) both;
}
.bt-case.done .bt-piece[data-piece="b"] { animation-delay: .08s; }
@keyframes pieceIn {
  from { opacity: 0; transform: translateY(-14px) scale(.94); }
  to { opacity: 1; transform: none; }
}
.bt-link {
  display: inline-block; min-width: 46px; text-align: center;
  padding: 7px 12px; border-radius: 9px;
  font-family: var(--serif); font-size: 16px; font-weight: 700;
  color: #fff; background: var(--acc);
  box-shadow: 0 0 16px color-mix(in srgb, var(--acc) 45%, transparent);
}
.bt-case.bad .bt-link {
  background: var(--bad, #e2574c);
  box-shadow: 0 0 16px color-mix(in srgb, var(--bad, #e2574c) 55%, transparent);
}
.bt-q { font-family: var(--serif); font-size: 20px; color: var(--fg-3); margin-left: -4px; }
.bt-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; }
.bt-judge.is-ok { color: var(--ok); }
.bt-judge.is-bad { color: var(--bad, #e2574c); }
.bt-why { margin-top: 11px; font-size: 13px; color: var(--fg-2); line-height: 1.76; }
.bt-case.done.bad .bt-pair { animation: deadShake .44s ease; }

@media (max-width: 720px) {
  .fr-chip { padding: 8px 12px; }
  .fr-slot { min-width: 92px; padding: 11px 12px 13px; }
}

/* 单词发音提示 */
.word-toast {
  position: fixed; left: 50%; bottom: 34px;
  transform: translateX(-50%) translateY(10px);
  background: var(--surface); color: var(--fg);
  border: 1px solid var(--line-2); border-radius: 10px;
  padding: 9px 17px; font-size: 13.5px; font-weight: 620;
  box-shadow: var(--sh-lg); z-index: 200;
  opacity: 0; pointer-events: none;
  transition: opacity .18s ease, transform .25s cubic-bezier(.2,.8,.3,1);
}
.word-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* 可发音区域：高亮必须只包住句子本身，不能铺满整行。
   关键是让盒子宽度贴合文字 —— .q-en / .rec-v 原来是块级 div，宽 724px 而文字只有 166px，
   任何背景都会拉满一行。改成 inline-block 后，背景/光晕自然只覆盖句子。 */
.ex-en, .q-en, .rec-v.en { cursor: pointer; }
.quote .q-en, .rec-v.en { display: inline-block; max-width: 100%; }
.ex-en { -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.ex-en:hover, .q-en:hover, .rec-v.en:hover {
  background: color-mix(in srgb, var(--acc) 10%, transparent);
  border-radius: 6px;
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--acc) 10%, transparent);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  text-decoration: none;
}

/* ---- 自测 ---- */
.quiz {
  margin: 20px 0 6px; padding: 18px 20px;
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface);
}
.quiz-h {
  display: flex; align-items: center; gap: 7px;
  font-size: 10.5px; font-weight: 750; letter-spacing: .11em;
  text-transform: uppercase; color: var(--acc); margin-bottom: 10px;
}
.quiz-q { font-size: 15.5px; font-weight: 620; line-height: 1.7; margin-bottom: 14px; color: var(--fg); }
.quiz-opts { display: flex; flex-direction: column; gap: 7px; }
.quiz-opt {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 11px 14px; border-radius: var(--r-xs);
  border: 1px solid var(--line); background: transparent;
  color: var(--fg-2); font-size: 14.2px; line-height: 1.62;
  cursor: pointer; text-align: left;
  transition: border-color .14s, background .14s, transform .1s;
}
.quiz-opt:hover { border-color: var(--acc-line); color: var(--fg); }
.quiz-opt:active { transform: scale(.997); }
.quiz-opt .k {
  font-family: var(--mono); font-size: 11px; font-weight: 700;
  width: 18px; height: 18px; border-radius: 4px; flex: 0 0 auto;
  display: grid; place-items: center; margin-top: 1px;
  background: var(--surface-3); color: var(--fg-3);
}
.quiz-opt.ok { border-color: color-mix(in srgb, var(--ok) 50%, transparent);
  background: color-mix(in srgb, var(--ok) 11%, transparent); color: var(--fg); }
.quiz-opt.ok .k { background: var(--ok); color: #08100E; }
.quiz-opt.no { border-color: color-mix(in srgb, #FF5E5E 50%, transparent);
  background: color-mix(in srgb, #FF5E5E 10%, transparent); }
.quiz-opt.no .k { background: #FF5E5E; color: #180808; }
.quiz-exp {
  margin-top: 13px; padding-top: 13px; border-top: 1px solid var(--line);
  font-size: 13.8px; line-height: 1.78; color: var(--fg-2);
  display: none;
}
.quiz-exp.show { display: block; }

/* 本节要点 */
.takeaways {
  margin: 30px 0 0; padding: 20px 22px;
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface);
}
.takeaways h4 {
  margin: 0 0 13px; font-size: 10.5px; font-weight: 750;
  letter-spacing: .12em; text-transform: uppercase; color: var(--fg-3);
}
.takeaways ul { margin: 0; padding: 0; list-style: none; }
.takeaways li {
  position: relative; padding-left: 24px; margin-bottom: 9px;
  font-size: 14.5px; line-height: 1.74; color: var(--fg-2);
}
.takeaways li:last-child { margin-bottom: 0; }
.takeaways li::before {
  content: ""; position: absolute; left: 0; top: 8px;
  width: 11px; height: 6px;
  border-left: 1.8px solid var(--acc); border-bottom: 1.8px solid var(--acc);
  transform: rotate(-45deg);
}

/* 原文 */
.raw-wrap { margin: 26px 0 0; border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
.raw-wrap > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: flex; align-items: center; gap: 10px;
  padding: 13px 18px; font-size: 13px; color: var(--fg-2);
  transition: background .15s;
}
.raw-wrap > summary::-webkit-details-marker { display: none; }
.raw-wrap > summary:hover { background: var(--surface-2); }
.raw-wrap > summary .sw { width: 26px; height: 15px; border-radius: 8px;
  background: var(--surface-3); position: relative; flex: 0 0 auto; transition: background .2s; }
.raw-wrap > summary .sw::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 11px; height: 11px; border-radius: 50%; background: var(--fg-3);
  transition: transform .2s, background .2s;
}
.raw-wrap[open] > summary .sw { background: var(--acc-line); }
.raw-wrap[open] > summary .sw::after { transform: translateX(11px); background: var(--acc); }
.raw-wrap > summary .raw-meta { margin-left: auto; font-family: var(--mono); font-size: 11px; }
.raw-body {
  padding: 10px 24px 26px; border-top: 1px solid var(--line);
  background: var(--ink);
}
.raw-body p {
  font-size: 14.2px; line-height: 1.95; color: var(--fg-2);
  margin: 0 0 11px;
}
/* 原文里的小标题 */
.raw-body h4 {
  font-size: 15.5px; font-weight: 700; color: var(--fg);
  line-height: 1.5; letter-spacing: -0.012em;
  margin: 28px 0 10px; padding-left: 11px;
  border-left: 2.5px solid var(--acc-line);
}
.raw-body h4.raw-h5 {
  font-size: 14.2px; font-weight: 650; color: var(--fg-2);
  border-left-color: var(--line-2); margin: 20px 0 8px;
}
.raw-body h4:first-child { margin-top: 6px; }
/* 【错译】【正译】【解析】 */
.raw-body p.raw-tag {
  padding-left: 13px; border-left: 2px solid var(--line-2);
  margin-bottom: 9px;
}
.raw-tag-k {
  display: inline-block; margin-right: 7px;
  font-size: 12.5px; font-weight: 700; color: var(--acc);
  letter-spacing: .02em;
}
/* ①②③ 编号行 */
.raw-body p.raw-num {
  color: var(--fg); font-weight: 600;
  margin: 16px 0 8px;
}
/* 英文原句 */
.raw-body p.raw-en {
  font-family: var(--serif); font-size: 15.4px; line-height: 1.72;
  color: var(--fg);
}
/* 无序列表 */
.raw-body p.raw-li {
  position: relative; padding-left: 15px;
}
.raw-body p.raw-li::before {
  content: ""; position: absolute; left: 2px; top: 12px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--line-2);
}

/* ---------------------------------------------------------------- 首页 */
.home-hero { padding: 66px 0 20px; text-align: center; position: relative; }
.home-hero::before {
  content: ""; position: absolute; left: 50%; top: -60px; transform: translateX(-50%);
  width: 700px; height: 420px; pointer-events: none;
  background: radial-gradient(ellipse at 50% 50%, var(--acc-soft), transparent 68%);
  filter: blur(20px);
}
.home-hero .eyebrow {
  position: relative; font-size: 11px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--acc); margin-bottom: 18px;
}
.home-hero h1 {
  position: relative;
  font-size: 54px; line-height: 1.08; font-weight: 780;
  letter-spacing: -0.038em; margin: 0 0 18px;
}
.home-hero .lede {
  position: relative; font-size: 16.5px; line-height: 1.72; color: var(--fg-2);
  max-width: 560px; margin: 0 auto 30px;
}

.cta {
  position: relative;
  display: inline-flex; align-items: center; gap: 8px;
  height: 42px; padding: 0 22px; margin: -6px 0 26px;
  border-radius: 10px; background: var(--acc); color: #fff;
  font-size: 14px; font-weight: 640; text-decoration: none;
  box-shadow: 0 8px 24px -10px var(--acc-line);
  transition: transform .16s, filter .16s;
}
.cta:hover { text-decoration: none; transform: translateY(-1px); filter: brightness(1.08); }
.cta svg { width: 14px; height: 14px; }
.home-kpis {
  position: relative;
  display: inline-flex; gap: 0; flex-wrap: wrap; justify-content: center;
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface); overflow: hidden;
}
.home-kpis .kpi {
  padding: 14px 26px; text-align: center;
  border-right: 1px solid var(--line);
}
.home-kpis .kpi:last-child { border-right: none; }
.kpi b { display: block; font-size: 21px; font-weight: 750; letter-spacing: -0.025em; line-height: 1.2; }
.kpi span { font-size: 10.5px; color: var(--fg-3); letter-spacing: .04em; }

.ch-list { margin: 48px 0 0; display: flex; flex-direction: column; gap: 0; }
.ch-item {
  display: grid; grid-template-columns: 62px minmax(0,1fr) auto;
  gap: 0 20px; align-items: start;
  padding: 22px 0; border-top: 1px solid var(--line);
  text-decoration: none; color: inherit;
  transition: background .16s;
}
.ch-item:last-child { border-bottom: 1px solid var(--line); }
.ch-item:hover { text-decoration: none; background: color-mix(in srgb, var(--c) 4%, transparent); }
.ch-item .ci-num {
  font-family: var(--mono); font-size: 12px; font-weight: 700;
  color: var(--c); letter-spacing: .02em; padding-top: 5px;
}
.ch-item .ci-body { min-width: 0; }
.ch-item h3 {
  font-size: 19px; font-weight: 680; margin: 0 0 6px;
  line-height: 1.4; letter-spacing: -0.016em;
  transition: color .15s;
}
.ch-item:hover h3 { color: var(--c); }
.ch-item p { margin: 0; font-size: 13.8px; line-height: 1.7; color: var(--fg-2); }
.ch-item .ci-side {
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
  padding-top: 3px; min-width: 92px;
}
.ch-item .ci-side .cnt {
  font-family: var(--mono); font-size: 11px; color: var(--fg-3);
}
.ch-item .ci-side .bar {
  width: 92px; height: 3px; border-radius: 2px; background: var(--surface-3);
  overflow: hidden;
}
.ch-item .ci-side .bar i {
  display: block; height: 100%; background: var(--c); border-radius: 2px;
  transition: width .5s ease;
}

/* ---------------------------------------------------------------- 命令面板 */
.palette-back {
  position: fixed; inset: 0; z-index: 120;
  background: color-mix(in srgb, var(--ink) 62%, transparent);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 14vh;
}
.palette-back[hidden] { display: none; }
.palette {
  width: min(620px, calc(100vw - 32px));
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  box-shadow: var(--sh-lg);
  overflow: hidden;
  animation: palIn .18s cubic-bezier(.2,.8,.3,1);
}
@keyframes palIn { from { opacity: 0; transform: translateY(-8px) scale(.99); } }
.palette-input {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px; border-bottom: 1px solid var(--line);
}
.palette-input svg { width: 16px; height: 16px; color: var(--fg-3); flex: 0 0 auto; }
.palette-input input {
  flex: 1 1 auto; min-width: 0;
  border: none; background: transparent; outline: none;
  color: var(--fg); font-size: 15.5px; font-family: inherit;
}
.palette-input input::placeholder { color: var(--fg-3); }
.palette-input .esc {
  font-family: var(--mono); font-size: 10.5px; color: var(--fg-3);
  border: 1px solid var(--line-2); border-radius: 4px; padding: 1px 5px;
}
.palette-list { max-height: 52vh; overflow-y: auto; padding: 6px; }
.palette-item {
  display: block; width: 100%; text-align: left;
  padding: 10px 12px; border-radius: var(--r-xs);
  border: none; background: transparent; color: inherit; cursor: pointer;
}
.palette-item.sel { background: var(--acc-soft); }
.palette-item .pi-path {
  display: block; font-size: 10.5px; color: var(--fg-3); margin-bottom: 2px;
  letter-spacing: .02em;
}
.palette-item .pi-txt { font-size: 13.5px; line-height: 1.55; color: var(--fg-2); }
.palette-item mark { background: color-mix(in srgb, var(--acc) 30%, transparent);
  color: var(--fg); border-radius: 2px; }
.palette-empty { padding: 26px; text-align: center; color: var(--fg-3); font-size: 13px; }
.palette-foot {
  display: flex; gap: 14px; align-items: center;
  padding: 9px 16px; border-top: 1px solid var(--line);
  font-size: 10.5px; color: var(--fg-3); background: var(--surface-2);
}
.palette-foot b { font-family: var(--mono); font-weight: 600; color: var(--fg-2); }

/* ---------------------------------------------------------------- 空状态 */
.empty-box {
  margin: 40px 0; padding: 44px 24px; text-align: center;
  border: 1px dashed var(--line-2); border-radius: var(--r-md);
  color: var(--fg-3); font-size: 14px;
}

/* ---------------------------------------------------------------- 移动端 */
.only-mobile { display: none; }
.scrim { display: none; }

@media (max-width: 1240px) {
  :root { --rail-w: 240px; }
  .wrap-read, .wrap-wide { padding: 0 26px; }
  .chapter-strip { display: none; }
}

@media (max-width: 960px) {
  .shell { grid-template-columns: 1fr; }
  .only-mobile { display: grid; }
  .rail {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 110;
    width: 288px; height: 100vh;
    background: var(--bg);
    transform: translateX(-101%);
    transition: transform .3s cubic-bezier(.32,.72,0,1);
    box-shadow: var(--sh-lg);
    border-right: 1px solid var(--line-2);
  }
  body.nav-open .rail { transform: none; }
  body.nav-open .scrim {
    display: block; position: fixed; inset: 0; z-index: 105;
    background: color-mix(in srgb, var(--ink) 55%, transparent);
    -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  }
  .topbar { padding: 0 12px; gap: 8px; }
  .mark-txt { display: none; }
  .search-trigger { min-width: 0; width: 32px; padding: 0; justify-content: center; }
  .search-trigger span, .search-trigger kbd { display: none; }
  .wrap-read, .wrap-wide { padding: 0 18px; }
  .home-hero { padding: 40px 0 14px; }
  .home-hero h1 { font-size: 34px; }
  .home-hero .lede { font-size: 15px; }
  .home-kpis .kpi { padding: 12px 18px; }
  .book-hero { padding: 28px 0 24px; }
  .hero-inner { flex-direction: column; align-items: flex-start; gap: 14px; }
  .hero-num { font-size: 68px; }
  h1.hero-title { font-size: 27px; }
  .hero-hook { font-size: 15.5px; }
  h1.sec-title { font-size: 25px; }
  .sec-epigraph { font-size: 15px; }
  .entry { grid-template-columns: 34px minmax(0,1fr); gap: 0 10px; padding: 22px 0; }
  .entry h3 { font-size: 16.5px; }
  .entry p { font-size: 15px; }
  .quote .q-en { font-size: 16px; }
  .sec-preview-grid { grid-template-columns: 1fr; }
  .ch-item { grid-template-columns: 46px minmax(0,1fr); }
  .ch-item .ci-side { display: none; }
  .pager { grid-template-columns: 1fr; }
  .icon-btn { width: 36px; height: 36px; }
  .nav-sec { padding: 9px 8px; }
  .nav-point { padding: 7px; }
  .map-canvas { max-height: 380px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

@media print {
  .topbar, .rail, .progress-rail, .pager, .sec-toolbar, .point-strip { display: none !important; }
  .shell { grid-template-columns: 1fr; }
  .entry { break-inside: avoid; }
}


/* ---- 8. 接缝测试：逗号不能当胶水 ----
   两块句子卡 + 中间一个接缝槽。选不同的"胶水"，接缝的形态完全不同：
   咬合（圆角对接、缝隙收没）、裂开（红色断续线 + 抖）、断开（拉开成两句）。
   形态变化本身就是结论，不需要再配一行字说明。 */
.jt-stage {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 4px 0 22px;
  transition: gap .38s cubic-bezier(.2, .8, .3, 1);
}
.jt-sent {
  flex: 0 1 auto; max-width: 46%;
  padding: 13px 16px; border-radius: 12px;
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--line-2) 66%, transparent);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 10px 24px -20px rgba(0, 0, 0, .45);
  font-family: var(--serif); font-size: 16.5px; line-height: 1.55; color: var(--fg);
  transition: border-radius .34s cubic-bezier(.2, .8, .3, 1),
              background .3s, border-color .3s, box-shadow .3s;
}
.jt-slot {
  flex: 0 0 auto; position: relative;
  display: flex; align-items: center; justify-content: center;
  min-width: 32px; height: 34px; padding: 0 7px;
  border-radius: 9px;
  transition: min-width .34s cubic-bezier(.2, .8, .3, 1), background .3s;
}
.jt-sym {
  position: relative; z-index: 2; display: inline-block;
  font-family: var(--serif); font-size: 19px; font-weight: 700;
  color: var(--bad); white-space: nowrap;
  animation: symIn .38s cubic-bezier(.2, .9, .3, 1) both;
}
@keyframes symIn {
  from { opacity: 0; transform: translateY(10px) scale(.78); }
  to { opacity: 1; transform: none; }
}

/* 咬合：缝隙收没、靠缝的两侧改成小圆角 —— 两块长成一个整体 */
.jt-stage.is-ok { gap: 3px; }
.jt-stage.is-ok .jt-sent {
  border-color: color-mix(in srgb, var(--ok) 40%, transparent);
  background: color-mix(in srgb, var(--ok) 5%, var(--surface));
}
.jt-stage.is-ok .jt-sent[data-jt="a"] { border-radius: 12px 3px 3px 12px; }
.jt-stage.is-ok .jt-sent[data-jt="b"] { border-radius: 3px 12px 12px 3px; }
.jt-stage.is-ok .jt-slot { background: color-mix(in srgb, var(--ok) 14%, transparent); }
.jt-stage.is-ok .jt-sym { color: var(--ok); }

/* 裂开：接缝变红底、逗号反白 —— 让"这一格是问题所在"比一条细裂纹更直接 */
.jt-stage.is-bad { animation: seamShake .42s ease; }
.jt-stage.is-bad .jt-slot {
  background: color-mix(in srgb, var(--bad) 82%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--bad) 16%, transparent);
}
.jt-stage.is-bad .jt-sent { border-color: color-mix(in srgb, var(--bad) 34%, transparent); }
.jt-stage.is-bad .jt-sym { color: #fff; }
@keyframes seamShake {
  0%, 100% { transform: none; }
  22% { transform: translateX(-4px); }
  55% { transform: translateX(4px); }
  80% { transform: translateX(-2px); }
}

/* 断开：两块拉开距离、恢复完整圆角，读成两句各管各的 */
.jt-stage.is-split { gap: 34px; }
/* 必须带 [data-jt] 才压得住上面 is-ok 的咬合圆角（同分靠后定义赢） */
.jt-stage.is-split .jt-sent[data-jt="a"],
.jt-stage.is-split .jt-sent[data-jt="b"] { border-radius: 12px; }
.jt-stage.is-split .jt-slot { background: transparent; }
.jt-stage.is-split .jt-sym { color: var(--fg-3); }

/* 胶水芯片：上符号下名字，Apple 那种"轻"的分段控件 */
.jt-glues { display: flex; gap: 8px; flex-wrap: wrap; }
.jt-glue {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 9px 16px 8px; border-radius: 11px; cursor: pointer;
  font: inherit; border: 1px solid color-mix(in srgb, var(--line-2) 70%, transparent);
  background: var(--surface);
  transition: transform .2s cubic-bezier(.2, .8, .3, 1), border-color .2s,
              background .2s, box-shadow .2s;
}
.jt-glue b { font-family: var(--serif); font-size: 16.5px; font-weight: 700; color: var(--fg); line-height: 1.15; }
.jt-glue span { font-size: 10.5px; letter-spacing: .05em; color: var(--fg-3); }
.jt-glue:hover { transform: translateY(-2px); border-color: var(--acc-line); }
.jt-glue.on {
  border-color: var(--acc);
  background: color-mix(in srgb, var(--acc) 9%, var(--surface));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 12%, transparent);
}
.jt-glue.on b { color: var(--acc); }
.jt-glue[data-ok="0"].on {
  border-color: var(--bad, #e2574c);
  background: color-mix(in srgb, var(--bad, #e2574c) 8%, var(--surface));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--bad, #e2574c) 12%, transparent);
}
.jt-glue[data-ok="0"].on b { color: var(--bad, #e2574c); }

.jt-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; }
.jt-judge.is-ok { color: var(--ok); }
.jt-judge.is-bad { color: var(--bad, #e2574c); }
.jt-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }


/* ---- 9. 插拔同位语：解释员，不是主角 ----
   主语是实线框（真成分），同位语是虚线框 + 顶部一小截挂绳（挂着的东西）。
   这个视觉区分本身就是知识点：虚线 = 可以拔掉而不影响句子。 */
.ap-stage { margin: 2px 0 16px; padding-top: 14px; }   /* 给上面的挂绳留位置，别被 .lab 的 overflow 裁掉 */
.ap-sent {
  display: flex; flex-wrap: wrap; align-items: center; gap: 2px;
  font-family: var(--serif); font-size: 18px; line-height: 1.9; color: var(--fg);
}
.ap-a, .ap-b {
  display: inline-block; padding: 2px 9px; border-radius: 8px;
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--line-2) 70%, transparent);
  color: var(--fg);
}
.ap-slot {
  position: relative;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 10px; margin: 0 3px; border-radius: 9px;
  border: 1.5px dashed color-mix(in srgb, var(--acc) 55%, transparent);
  background: color-mix(in srgb, var(--acc) 7%, transparent);
  transition: background .3s, border-color .3s, padding .3s;
}
/* 空着的时候：只留一对逗号，虚框淡到几乎看不见，提示"这里现在什么都没有" */
.ap-slot[data-empty="1"] {
  border-color: color-mix(in srgb, var(--line-2) 60%, transparent);
  background: transparent;
}
.ap-comma { color: var(--fg-3); opacity: .55; }
.ap-slot:not([data-empty="1"]) .ap-comma { opacity: .8; }

/* 挂绳：一小截实线从框顶伸出去接一个小圆头，像贴了张名牌 */
.ap-slot::before {
  content: ''; position: absolute; top: -9px; left: 50%; width: 2px; height: 8px;
  transform: translateX(-50%);
  background: color-mix(in srgb, var(--acc) 78%, transparent);
  opacity: 0; transition: opacity .28s .12s;
}
.ap-slot::after {
  content: ''; position: absolute; top: -13px; left: 50%; width: 6px; height: 6px;
  border-radius: 50%; transform: translateX(-50%);
  background: var(--acc);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 16%, transparent);
  opacity: 0; transition: opacity .28s .12s;
}
.lab-appos.has-word .ap-slot::before,
.lab-appos.has-word .ap-slot::after { opacity: 1; }
.lab-appos.has-word .ap-slot[data-empty]::before,
.lab-appos.has-word .ap-slot[data-empty]::after { opacity: 0; }

.ap-word {
  font-style: normal; display: inline-block; white-space: nowrap;
  color: color-mix(in srgb, var(--acc) 75%, var(--fg));
}
.ap-word.in { animation: apDrop .42s cubic-bezier(.2, .9, .3, 1) both; }
@keyframes apDrop {
  0% { opacity: 0; transform: translateY(-13px) scale(.94); }
  70% { opacity: 1; transform: translateY(1px) scale(1); }
  100% { opacity: 1; transform: none; }
}

/* 对不上：牌子挂歪了 —— 红实线 + 抖一下 */
.ap-slot.is-bad {
  border-style: solid;
  border-color: color-mix(in srgb, var(--bad) 78%, transparent);
  background: color-mix(in srgb, var(--bad) 8%, transparent);
  animation: apReject .44s ease;
}
.ap-slot.is-bad .ap-word { color: var(--bad); }
.ap-slot.is-bad::before {
  background: repeating-linear-gradient(180deg,
    color-mix(in srgb, var(--bad) 70%, transparent) 0 3px, transparent 3px 6px);
}
@keyframes apReject {
  0%, 100% { transform: none; }
  25% { transform: translateY(-3px) rotate(-1.2deg); }
  60% { transform: translateY(2px) rotate(.8deg); }
  85% { transform: translateY(-1px) rotate(-.4deg); }
}

/* 图例：实线 = 成分，虚线 = 挂着 */
.ap-legend {
  display: flex; gap: 18px; flex-wrap: wrap;
  margin-top: 12px; font-size: 11.5px; color: var(--fg-3); letter-spacing: .02em;
}
.ap-legend span { display: inline-flex; align-items: center; gap: 6px; }
.ap-legend .k { width: 17px; height: 11px; border-radius: 4px; display: inline-block; }
.ap-legend .k-s { border: 1.5px solid color-mix(in srgb, var(--line-2) 90%, transparent); background: var(--surface-2); }
.ap-legend .k-d {
  border: 1.5px dashed color-mix(in srgb, var(--acc) 60%, transparent);
  background: color-mix(in srgb, var(--acc) 8%, transparent);
}

/* 名牌按钮 */
.ap-picks { display: flex; gap: 8px; flex-wrap: wrap; }
.ap-pick {
  padding: 8px 15px; border-radius: 10px; cursor: pointer; font: inherit;
  font-family: var(--serif); font-size: 14.5px; color: var(--fg);
  border: 1px solid color-mix(in srgb, var(--line-2) 72%, transparent);
  background: var(--surface);
  transition: transform .2s cubic-bezier(.2, .8, .3, 1), border-color .2s,
              background .2s, box-shadow .2s, color .2s;
}
.ap-pick:hover { transform: translateY(-2px); border-color: var(--acc-line); }
.ap-pick.on {
  border-color: var(--acc);
  background: color-mix(in srgb, var(--acc) 9%, var(--surface));
  color: color-mix(in srgb, var(--acc) 70%, var(--fg));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 12%, transparent);
}
.ap-pick[data-ok="0"].on {
  border-color: var(--bad);
  background: color-mix(in srgb, var(--bad) 8%, var(--surface));
  color: var(--bad);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--bad) 12%, transparent);
}

.ap-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; }
.ap-judge.is-ok { color: var(--ok); }
.ap-judge.is-bad { color: var(--bad); }
.ap-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }


/* ---- 10. 化妆台：定语给名词化妆，骨架不会多一格 ----
   句子越长，主语那一格就撑得越宽；但格子数永远是 2。
   "定语不影响主干"不是一句话，是一个能看见的几何事实。 */
.mk-stage { margin: 0 0 10px; }
.mk-sent {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 5px;
  font-family: var(--serif); font-size: 16.5px; line-height: 1.6; color: var(--fg);
}
.mk-adjs-pre, .mk-adjs-post { display: contents; }
.mk-adj {
  display: inline-block;
  padding: 1px 8px; border-radius: 7px;
  background: color-mix(in srgb, var(--acc) 9%, transparent);
  border-bottom: 1.5px dashed color-mix(in srgb, var(--acc) 48%, transparent);
  color: color-mix(in srgb, var(--acc) 72%, var(--fg));
  animation: mkIn .34s cubic-bezier(.2, .9, .3, 1) both;
}
@keyframes mkIn {
  from { opacity: 0; transform: translateY(-6px) scale(.92); }
  to { opacity: 1; transform: none; }
}
.mk-noun {
  font-weight: 600;
  border-bottom: 2px solid color-mix(in srgb, var(--fg) 55%, transparent);
}
.mk-tail { color: var(--fg-2); }

/* 骨架条：两格在左、统计在右，整行占满。
   主语格宽度跟内容走 —— 素颜时只有 "The boy" 就该只占这么宽，
   定语加得越多它越长（那才是"同一格装下更多东西"的证据）。
   原来写 flex:1 会把它撑到 900px，素颜状态下右边整片都是空的。 */
.mk-frame {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  transition: gap .3s;
}
.mk-cells { display: flex; gap: 8px; flex: 0 1 auto; min-width: 0; }
.mk-cell {
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  border-radius: 10px; padding: 7px 12px 8px;
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
  transition: flex-grow .42s cubic-bezier(.2, .8, .3, 1), border-color .3s, background .3s;
}
.mk-cell b {
  display: block; font-size: 10.5px; font-weight: 760; letter-spacing: .08em;
  color: var(--acc); margin-bottom: 3px;
}
.mk-cell span {
  font-family: var(--serif); font-size: 15px; color: var(--fg);
  word-break: break-word;
}
/* 主语格宽度跟内容走 —— 素颜时只有 "The boy" 就该只占这么宽，
   定语加得越多它越长（那才是"同一格装下更多东西"的证据）。
   原来写 flex:1 会把它撑到 900px，素颜状态下右边整片都是空的。 */
.mk-s { flex: 0 1 auto; min-width: 92px; max-width: 100%; }
.mk-p { flex: 0 0 auto; }
.mk-s b { color: color-mix(in srgb, var(--acc) 80%, var(--fg-2)); }
.mk-p b { color: color-mix(in srgb, var(--ok) 82%, var(--fg-2)); }
.mk-p { border-top: 3px solid color-mix(in srgb, var(--ok) 55%, transparent); }
.mk-s { border-top: 3px solid color-mix(in srgb, var(--acc) 55%, transparent); }

.mk-stat {
  display: flex; align-items: center; gap: 8px; flex: 0 0 auto;
  margin-left: auto;                     /* 顶到右边，把这一行的空白吃掉 */
  font-size: 12px; color: var(--fg-3); letter-spacing: .02em;
  padding: 4px 10px; border-radius: 8px;
  background: color-mix(in srgb, var(--fg) 4%, transparent);
}
.mk-stat i { font-style: normal; opacity: .5; }
.mk-words { color: color-mix(in srgb, var(--acc) 78%, var(--fg-2)); font-weight: 620; }
.mk-slots { color: color-mix(in srgb, var(--ok) 78%, var(--fg-2)); font-weight: 620; }

/* 化妆品 */
.mk-picks { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 16px; }
.mk-pick {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  padding: 8px 14px 7px; border-radius: 10px; cursor: pointer; font: inherit;
  border: 1px solid color-mix(in srgb, var(--line-2) 72%, transparent);
  background: var(--surface);
  transition: transform .2s cubic-bezier(.2, .8, .3, 1), border-color .2s,
              background .2s, box-shadow .2s;
}
.mk-pick b { font-family: var(--serif); font-size: 14.5px; font-weight: 600; color: var(--fg); }
.mk-pick span { font-size: 10.5px; letter-spacing: .04em; color: var(--fg-3); }
.mk-pick:hover { transform: translateY(-2px); border-color: var(--acc-line); }
.mk-pick.on {
  border-color: var(--acc);
  background: color-mix(in srgb, var(--acc) 9%, var(--surface));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 12%, transparent);
}
.mk-pick.on b { color: color-mix(in srgb, var(--acc) 72%, var(--fg)); }
.mk-pick[data-ok="0"] { border-style: dashed; }
.mk-pick.shake { animation: mkReject .44s ease; border-color: var(--bad); }
@keyframes mkReject {
  0%, 100% { transform: none; }
  25% { transform: translateX(-4px); }
  60% { transform: translateX(4px); }
  85% { transform: translateX(-2px); }
}

.mk-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; color: var(--fg-2); }
.mk-judge.is-ok { color: var(--ok); }
.mk-judge.is-bad { color: var(--bad); }
.mk-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }


/* ---- 11. 状语换装：同一个岗位，五种成分都能坐 ----
   主干是一块实线框（框内永远三个词，从不变）；状语是框外两边的虚线空槽。
   填进去之后虚线变实线、框内一个字不动 —— 这就是"状语不影响主干"。 */
.zv-track {
  display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap;
  margin: 4px 0 10px;
}
.zv-core {
  flex: 1 1 220px; min-width: 0; order: 2;
  padding: 12px 16px 13px; border-radius: 12px;
  border: 1.5px solid color-mix(in srgb, var(--line-2) 88%, transparent);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 10px 22px -18px rgba(0, 0, 0, .4);
}
.zv-core b {
  display: block; font-size: 10.5px; font-weight: 760; letter-spacing: .08em;
  color: var(--fg-3); margin-bottom: 5px;
}
.zv-core-txt {
  font-family: var(--serif); font-size: 18px; color: var(--fg); line-height: 1.5;
}
.zv-slot {
  flex: 0 1 auto; min-width: 96px; order: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  padding: 8px 12px; border-radius: 11px;
  border: 1.5px dashed color-mix(in srgb, var(--line-2) 70%, transparent);
  background: transparent;
  transition: border-color .3s, background .3s, transform .34s cubic-bezier(.2, .8, .3, 1);
}
.zv-slot[data-slot="post"] { order: 3; }
.zv-slot::before {
  content: '空位'; font-size: 10px; letter-spacing: .06em;
  color: color-mix(in srgb, var(--fg-3) 80%, transparent);
}
.zv-slot.is-filled::before { content: none; }
.zv-slot.is-filled {
  border-style: solid;
  border-color: color-mix(in srgb, var(--acc) 55%, transparent);
  background: color-mix(in srgb, var(--acc) 8%, transparent);
}
.zv-word {
  font-family: var(--serif); font-size: 15.5px; line-height: 1.45; text-align: center;
  color: color-mix(in srgb, var(--acc) 74%, var(--fg));
  max-width: 210px;
}
.zv-slot.is-filled .zv-word { animation: zvIn .38s cubic-bezier(.2, .9, .3, 1) both; }
@keyframes zvIn {
  from { opacity: 0; transform: translateY(-7px) scale(.93); }
  to { opacity: 1; transform: none; }
}
.zv-tag {
  font-style: normal; font-size: 10px; letter-spacing: .05em;
  color: var(--fg-3); white-space: nowrap;
}

/* 拼出来的整句：前置时主干首字母会让位，这里显示真实写法 */
.zv-sent {
  margin: 0 0 18px; padding: 9px 14px; border-radius: 10px;
  background: color-mix(in srgb, var(--fg) 3%, transparent);
  font-family: var(--serif); font-size: 16px; color: var(--fg-2);
  line-height: 1.6;
}
.zv-sent-txt { animation: zvSent .3s ease both; }
@keyframes zvSent { from { opacity: .35; } to { opacity: 1; } }

.zv-picks { display: flex; gap: 8px; flex-wrap: wrap; }
.zv-pick {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  padding: 8px 14px 7px; border-radius: 10px; cursor: pointer; font: inherit;
  border: 1px solid color-mix(in srgb, var(--line-2) 72%, transparent);
  background: var(--surface);
  transition: transform .2s cubic-bezier(.2, .8, .3, 1), border-color .2s,
              background .2s, box-shadow .2s;
}
.zv-pick b { font-family: var(--serif); font-size: 14.5px; font-weight: 600; color: var(--fg); }
.zv-pick span { font-size: 10.5px; letter-spacing: .04em; color: var(--fg-3); }
.zv-pick:hover { transform: translateY(-2px); border-color: var(--acc-line); }
.zv-pick.on {
  border-color: var(--acc);
  background: color-mix(in srgb, var(--acc) 9%, var(--surface));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 12%, transparent);
}
.zv-pick.on b { color: color-mix(in srgb, var(--acc) 72%, var(--fg)); }

.zv-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; color: var(--fg-2); }
.zv-judge.is-ok { color: var(--ok); }
.zv-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }


/* ---- 12. 认词就认句：引导词一变，整句的类型就变 ----
   从句框和主句框的位置永远不动，动的是中间那条"关系"：
   虚线的条件、粗箭头的原因、对冲的让步……连线形态就是逻辑关系本身。 */
.sb-stage {
  display: flex; align-items: stretch; gap: 0; flex-wrap: nowrap;
  margin: 4px 0 12px;
  --rc: var(--fg-3);
}
.sb-stage[data-rel="time"]  { --rc: #4E8BFF; }
.sb-stage[data-rel="cond"]  { --rc: #12B8A6; }
.sb-stage[data-rel="cause"] { --rc: #E8933A; }
.sb-stage[data-rel="conc"]  { --rc: #9268E8; }
.sb-stage[data-rel="dual"]  { --rc: #C0553F; }

.sb-box {
  flex: 1 1 0; min-width: 0;
  padding: 11px 14px 12px; border-radius: 11px;
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
  transition: border-color .3s, background .3s;
}
.sb-box b {
  display: block; font-size: 10px; font-weight: 760; letter-spacing: .08em;
  color: var(--fg-3); margin-bottom: 5px;
}
.sb-box span {
  font-family: var(--serif); font-size: 15.5px; line-height: 1.5; color: var(--fg);
  word-break: break-word;
}
.sb-clause { border-left: 3px solid color-mix(in srgb, var(--rc) 62%, transparent); }
.sb-main { border-left: 3px solid color-mix(in srgb, var(--line-2) 90%, transparent); }
.sb-stage[data-rel]:not([data-rel="none"]) .sb-main { border-left-color: color-mix(in srgb, var(--rc) 38%, transparent); }

.sb-w {
  font-style: normal; font-weight: 700;
  color: var(--rc);
  display: inline-block;
  white-space: pre;        /* 保留 JS 拼的尾空格，否则 When 会和 it rains 粘在一起 */
}
.sb-w.in { animation: sbIn .36s cubic-bezier(.2, .9, .3, 1) both; }
@keyframes sbIn {
  from { opacity: 0; transform: translateY(-7px) scale(.9); }
  to { opacity: 1; transform: none; }
}

/* 中间的关系线：形态随类型变 */
.sb-link {
  flex: 0 0 auto; width: 112px;
  display: flex; align-items: center; gap: 6px;
  padding: 0 4px;
}
.sb-link i {
  flex: 1 1 auto; height: 0;
  border-top: 1.5px solid color-mix(in srgb, var(--rc) 70%, transparent);
  transition: border-color .3s, border-top-style .3s, border-top-width .3s;
}
.sb-link em {
  font-style: normal; font-size: 10.5px; font-weight: 760; letter-spacing: .04em;
  color: var(--rc); white-space: nowrap;
  padding: 1px 5px; border-radius: 5px;
  background: color-mix(in srgb, var(--rc) 12%, transparent);
}
/* 条件：虚线的门，还没发生 */
.sb-stage[data-rel="cond"] .sb-link i { border-top-style: dashed; }
/* 原因：粗箭头，已经导致 */
.sb-stage[data-rel="cause"] .sb-link i { border-top-width: 2.5px; }
/* 让步：两端都带箭头，方向对冲 */
.sb-stage[data-rel="conc"] .sb-link i { border-top-style: double; border-top-width: 3px; }
/* 双身份：一半虚一半实 */
.sb-stage[data-rel="dual"] .sb-link i { border-top-style: dashed; }

.sb-cn {
  min-height: 22px; font-size: 13.4px; color: var(--fg-2); line-height: 1.7;
  transition: color .3s;
}

.sb-picks { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.sb-pick {
  padding: 7px 16px; border-radius: 9px; cursor: pointer; font: inherit;
  font-family: var(--serif); font-size: 15px; font-weight: 600; color: var(--fg);
  border: 1px solid color-mix(in srgb, var(--line-2) 72%, transparent);
  background: var(--surface);
  transition: transform .2s cubic-bezier(.2, .8, .3, 1), border-color .2s,
              background .2s, box-shadow .2s, color .2s;
}
.sb-pick:hover { transform: translateY(-2px); border-color: var(--acc-line); }
.sb-pick.on {
  border-color: var(--acc);
  background: color-mix(in srgb, var(--acc) 9%, var(--surface));
  color: color-mix(in srgb, var(--acc) 74%, var(--fg));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 12%, transparent);
}

.sb-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; color: var(--fg-2); }
.sb-judge.is-ok { color: var(--ok); }
.sb-judge.is-warn { color: #E8933A; }
.sb-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }


/* ---- 13. 定妆台：一句话加八种状语 ----
   素颜主体是一块固定宽度的框，状语块挂在框外左右两侧。
   多出来的那一块单独上色，所以"这句变长是因为多了这一截"一眼可见。 */
.ds-stage {
  display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap;
  margin: 4px 0 12px;
}
.ds-core {
  flex: 1 1 260px; min-width: 0; order: 2;
  padding: 12px 15px 13px; border-radius: 11px;
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
  font-family: var(--serif); font-size: 15.5px; line-height: 1.55; color: var(--fg);
}
.ds-slot {
  flex: 0 1 auto; max-width: 44%; order: 1;
  display: none; flex-direction: column; justify-content: center; gap: 3px;
  padding: 9px 13px; border-radius: 11px;
  border: 1px solid color-mix(in srgb, var(--acc) 45%, transparent);
  background: color-mix(in srgb, var(--acc) 8%, transparent);
}
.ds-slot[data-pos="post"] { order: 3; }
.ds-slot.is-filled { display: flex; animation: dsIn .38s cubic-bezier(.2, .9, .3, 1) both; }
@keyframes dsIn {
  from { opacity: 0; transform: translateY(-6px) scale(.95); }
  to { opacity: 1; transform: none; }
}
.ds-slot em {
  font-style: normal; font-family: var(--serif); font-size: 15px; line-height: 1.5;
  color: color-mix(in srgb, var(--acc) 76%, var(--fg));
}
.ds-slot i {
  font-style: normal; font-size: 10px; letter-spacing: .06em;
  color: var(--fg-3);
}
.ds-slot[data-pos="pre"] i { color: color-mix(in srgb, #E8933A 78%, var(--fg-2)); }

.ds-sent {
  padding: 10px 14px; border-radius: 10px;
  background: color-mix(in srgb, var(--fg) 3%, transparent);
  font-family: var(--serif); font-size: 15.5px; line-height: 1.65; color: var(--fg-2);
  transition: color .3s;
}

.ds-picks { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 16px; }
.ds-pick {
  padding: 7px 15px; border-radius: 9px; cursor: pointer; font: inherit;
  font-size: 13px; font-weight: 620; color: var(--fg);
  border: 1px solid color-mix(in srgb, var(--line-2) 72%, transparent);
  background: var(--surface);
  transition: transform .2s cubic-bezier(.2, .8, .3, 1), border-color .2s,
              background .2s, box-shadow .2s, color .2s;
}
.ds-pick:hover { transform: translateY(-2px); border-color: var(--acc-line); }
.ds-pick.on {
  border-color: var(--acc);
  background: color-mix(in srgb, var(--acc) 9%, var(--surface));
  color: color-mix(in srgb, var(--acc) 74%, var(--fg));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 12%, transparent);
}
.ds-pick[data-pos="pre"] { border-style: dashed; }

.ds-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; color: var(--fg-2); }
.ds-judge.is-ok { color: var(--ok); }
.ds-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }


/* ---- 14. 成分换人：同一个成分位，换不同形式写 ----
   上面是分段控件（主语/定语/状语），下面是形式芯片。
   句子整句换掉，但充当成分的那一块永远单独高亮 —— 换的是形式，不是成分。 */
.role-tabs {
  display: inline-flex; padding: 3px; gap: 2px;
  border-radius: 11px;
  background: color-mix(in srgb, var(--fg) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--line-2) 55%, transparent);
}
.role-tab {
  padding: 6px 16px; border-radius: 8px; cursor: pointer; font: inherit;
  font-size: 12.6px; font-weight: 640; color: var(--fg-3);
  border: 0; background: transparent;
  transition: background .22s, color .22s, box-shadow .22s;
}
.role-tab:hover { color: var(--fg-2); }
.role-tab.on {
  background: var(--surface); color: var(--fg);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12), 0 2px 8px -4px rgba(0, 0, 0, .3);
}

.role-cn {
  margin: 16px 0 6px; font-size: 12.6px; color: var(--fg-3);
}
.role-sent {
  padding: 14px 16px; border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
  font-family: var(--serif); font-size: 17px; line-height: 1.72; color: var(--fg);
  word-break: break-word;
}
.role-hl {
  font-style: normal;
  padding: 1px 5px; margin: 0 1px; border-radius: 6px;
  background: color-mix(in srgb, var(--acc) 13%, transparent);
  border-bottom: 2px solid color-mix(in srgb, var(--acc) 55%, transparent);
  color: color-mix(in srgb, var(--acc) 78%, var(--fg));
  animation: roleHl .4s cubic-bezier(.2, .9, .3, 1) both;
}
@keyframes roleHl {
  from { opacity: .2; transform: scale(.96); }
  to { opacity: 1; transform: none; }
}

.role-forms { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 16px; }
.role-form {
  padding: 7px 14px; border-radius: 9px; cursor: pointer; font: inherit;
  font-size: 12.8px; font-weight: 620; color: var(--fg);
  border: 1px solid color-mix(in srgb, var(--line-2) 72%, transparent);
  background: var(--surface);
  transition: transform .2s cubic-bezier(.2, .8, .3, 1), border-color .2s,
              background .2s, box-shadow .2s, color .2s;
}
.role-form:hover { transform: translateY(-2px); border-color: var(--acc-line); }
.role-form.on {
  border-color: var(--acc);
  background: color-mix(in srgb, var(--acc) 9%, var(--surface));
  color: color-mix(in srgb, var(--acc) 74%, var(--fg));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 12%, transparent);
}

.role-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; color: var(--ok); }
.role-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }
.role-data { display: none; }


/* ---- 15. 拆句器：点一块，看它当什么成分 ----
   未点开时每块只有一层虚线下划线（"这里可以点"）；点开后整块染成该成分的颜色。
   全部点完，句子本身就是一张结构图 —— 主干两块、其余全是挂上去的。 */
.ck-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }
.ck-tab {
  padding: 6px 14px; border-radius: 8px; cursor: pointer; font: inherit;
  font-size: 12.4px; font-weight: 640; color: var(--fg-3);
  border: 1px solid color-mix(in srgb, var(--line-2) 60%, transparent);
  background: transparent;
  transition: background .2s, color .2s, border-color .2s;
}
.ck-tab:hover { color: var(--fg-2); border-color: var(--acc-line); }
.ck-tab.on {
  background: color-mix(in srgb, var(--acc) 10%, var(--surface));
  border-color: color-mix(in srgb, var(--acc) 45%, transparent);
  color: color-mix(in srgb, var(--acc) 78%, var(--fg));
}

.ck-cn { margin-bottom: 10px; font-size: 12.6px; color: var(--fg-3); line-height: 1.65; }

.ck-sent {
  padding: 14px 16px; border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
  font-family: var(--serif); font-size: 16.5px; line-height: 2.05; color: var(--fg);
  word-break: break-word;
}
.ck {
  cursor: pointer; border-radius: 5px; padding: 1px 0;
  border-bottom: 1.5px dashed color-mix(in srgb, var(--fg-3) 55%, transparent);
  transition: background .28s, border-color .28s, color .28s, box-shadow .28s;
}
.ck:hover { background: color-mix(in srgb, var(--acc) 8%, transparent); }
.ck.on {
  padding: 1px 4px; border-bottom: 0;
  border-radius: 5px;
  animation: ckOn .34s cubic-bezier(.2, .9, .3, 1) both;
}
@keyframes ckOn { from { opacity: .3; } to { opacity: 1; } }
/* 每种成分一套颜色 —— 颜色只是辅助，标签才是判据 */
.ck.on[data-role="主语"]      { background: color-mix(in srgb, #4E8BFF 16%, transparent); color: color-mix(in srgb, #4E8BFF 70%, var(--fg)); }
.ck.on[data-role="谓语"],
.ck.on[data-role$="谓语）"]   { background: color-mix(in srgb, #12B8A6 16%, transparent); color: color-mix(in srgb, #0E8A72 72%, var(--fg)); }
.ck.on[data-role="宾语"]      { background: color-mix(in srgb, #9268E8 16%, transparent); color: color-mix(in srgb, #9268E8 72%, var(--fg)); }
.ck.on[data-role="连词"],
.ck.on[data-role="并列连词"]  { background: color-mix(in srgb, var(--fg) 9%, transparent); color: var(--fg-2); }
.ck.on[data-role*="状语"]     { background: color-mix(in srgb, #E8933A 17%, transparent); color: color-mix(in srgb, #C4671B 78%, var(--fg)); }
.ck.on[data-role*="从句"]     { background: color-mix(in srgb, #E8933A 17%, transparent); color: color-mix(in srgb, #C4671B 78%, var(--fg)); }
.ck.on[data-role*="定语"]     { background: color-mix(in srgb, #12B8A6 15%, transparent); color: color-mix(in srgb, #0E8A72 72%, var(--fg)); }
.ck-gap { white-space: pre; }

.ck-bar { display: flex; align-items: center; gap: 14px; margin-top: 14px; }
.ck-count { font-size: 12.2px; color: var(--fg-3); letter-spacing: .02em; }
.ck-all {
  padding: 5px 13px; border-radius: 8px; cursor: pointer; font: inherit;
  font-size: 12px; font-weight: 620; color: var(--fg-2);
  border: 1px solid color-mix(in srgb, var(--line-2) 66%, transparent);
  background: transparent;
  transition: color .2s, border-color .2s, background .2s;
}
.ck-all:hover { color: var(--fg); border-color: var(--acc); background: color-mix(in srgb, var(--acc) 8%, transparent); }

.ck-note {
  margin-top: 12px; font-size: 13px; color: var(--fg-2); line-height: 1.78;
  min-height: 42px;
}
.ck-note.is-on { color: var(--fg-2); }
.ck-note.is-ok { color: var(--ok); }
.ck-data { display: none; }


/* ---- 16. 框架开关：把一块成分抬进强调框架 ----
   原句是一串可点的块；点中一块，It was 和 that 从两侧长出来，那一块被抬起来。
   其余部分一个词都不动 —— 这就是"框架只搬一块"。 */
.cf-cn { margin-bottom: 10px; font-size: 12.6px; color: var(--fg-3); line-height: 1.65; }

.cf-sent {
  padding: 16px 18px; border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
  font-family: var(--serif); font-size: 17px; line-height: 2.1; color: var(--fg);
  word-break: break-word;
  transition: border-color .3s, background .3s;
}
.cf-sent.is-bad { border-color: color-mix(in srgb, var(--bad) 45%, transparent); background: color-mix(in srgb, var(--bad) 4%, var(--surface)); }

.cf-ck {
  cursor: pointer; border-radius: 5px; padding: 1px 1px;
  border-bottom: 1.5px dashed color-mix(in srgb, var(--fg-3) 55%, transparent);
  transition: background .24s, border-color .24s, color .24s;
}
.cf-ck:hover { background: color-mix(in srgb, var(--acc) 10%, transparent); border-bottom-color: var(--acc); }

/* 被强调的那一块：抬起来、上色、带阴影 */
.cf-hi {
  display: inline-block;
  padding: 2px 10px; border-radius: 8px;
  background: color-mix(in srgb, var(--acc) 15%, transparent);
  border: 1.5px solid color-mix(in srgb, var(--acc) 52%, transparent);
  color: color-mix(in srgb, var(--acc) 80%, var(--fg));
  box-shadow: 0 3px 10px -6px color-mix(in srgb, var(--acc) 70%, transparent);
  animation: cfLift .4s cubic-bezier(.2, .9, .3, 1) both;
}
@keyframes cfLift {
  0% { opacity: .3; transform: translateY(6px) scale(.94); }
  60% { opacity: 1; transform: translateY(-2px) scale(1.02); }
  100% { opacity: 1; transform: none; }
}
.cf-sent.is-bad .cf-hi {
  background: color-mix(in srgb, var(--bad) 12%, transparent);
  border-color: color-mix(in srgb, var(--bad) 55%, transparent);
  color: var(--bad);
  box-shadow: 0 3px 10px -6px color-mix(in srgb, var(--bad) 70%, transparent);
}
/* 框架本身：灰的、小的 —— 提示"它不占成分" */
.cf-frame {
  display: inline-block;
  padding: 1px 7px; border-radius: 6px;
  background: color-mix(in srgb, var(--fg) 8%, transparent);
  color: var(--fg-3);
  font-size: 14.5px;
  animation: cfFrameIn .34s ease both;
}
@keyframes cfFrameIn { from { opacity: 0; } to { opacity: 1; } }
.cf-gap { white-space: pre; }

.cf-picks { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 16px; }
.cf-pick {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  padding: 7px 13px 6px; border-radius: 9px; cursor: pointer; font: inherit;
  border: 1px solid color-mix(in srgb, var(--line-2) 72%, transparent);
  background: var(--surface);
  transition: transform .2s cubic-bezier(.2, .8, .3, 1), border-color .2s,
              background .2s, box-shadow .2s;
}
.cf-pick b { font-family: var(--serif); font-size: 14px; font-weight: 600; color: var(--fg); }
.cf-pick span { font-size: 10px; letter-spacing: .05em; color: var(--fg-3); }
.cf-pick:hover { transform: translateY(-2px); border-color: var(--acc-line); }
.cf-pick.on {
  border-color: var(--acc);
  background: color-mix(in srgb, var(--acc) 9%, var(--surface));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 12%, transparent);
}
.cf-pick.on b { color: color-mix(in srgb, var(--acc) 74%, var(--fg)); }
.cf-pick[data-ok="0"] { border-style: dashed; }

.cf-tense {
  display: flex; align-items: center; gap: 6px;
  margin-top: 14px; font-size: 12.2px; color: var(--fg-3);
}
.cf-t {
  padding: 4px 13px; border-radius: 7px; cursor: pointer; font: inherit;
  font-family: var(--serif); font-size: 13.5px; font-weight: 600; color: var(--fg-3);
  border: 1px solid color-mix(in srgb, var(--line-2) 66%, transparent);
  background: transparent;
  transition: background .2s, color .2s, border-color .2s;
}
.cf-t:hover { color: var(--fg-2); border-color: var(--acc-line); }
.cf-t.on {
  background: color-mix(in srgb, var(--acc) 10%, var(--surface));
  border-color: color-mix(in srgb, var(--acc) 45%, transparent);
  color: color-mix(in srgb, var(--acc) 78%, var(--fg));
}
.cf-t[data-ok="0"].on {
  background: color-mix(in srgb, var(--bad) 10%, var(--surface));
  border-color: color-mix(in srgb, var(--bad) 48%, transparent);
  color: var(--bad);
}

.cf-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; color: var(--fg-2); }
.cf-judge.is-ok { color: var(--ok); }
.cf-judge.is-bad { color: var(--bad); }
.cf-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }
.cf-data { display: none; }


/* ---- 17. 退一格：真话在上面，假话在下面，中间只隔一个"退"的动作 ----
   两个盒子永远同时可见 —— 对比本身就是这个组件的全部意义，
   只留结果不给原句，用户就不知道"到底退了什么"。 */
.sj-tabs {
  display: inline-flex; padding: 3px; gap: 2px; margin-bottom: 16px;
  border-radius: 11px;
  background: color-mix(in srgb, var(--fg) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--line-2) 55%, transparent);
}
.sj-tab {
  padding: 6px 16px; border-radius: 8px; cursor: pointer; font: inherit;
  font-size: 12.6px; font-weight: 640; color: var(--fg-3);
  border: 0; background: transparent;
  transition: background .22s, color .22s, box-shadow .22s;
}
.sj-tab:hover { color: var(--fg-2); }
.sj-tab.on {
  background: var(--surface); color: var(--fg);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12), 0 2px 8px -4px rgba(0, 0, 0, .3);
}

.sj-fact, .sj-virt {
  padding: 13px 16px 14px; border-radius: 11px;
  font-family: var(--serif); font-size: 16px; line-height: 1.7; color: var(--fg);
}
.sj-fact {
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
}
.sj-virt {
  border: 1.5px solid color-mix(in srgb, var(--acc) 42%, transparent);
  background: color-mix(in srgb, var(--acc) 7%, var(--surface));
}
.sj-fact b, .sj-virt b {
  display: block; font-family: var(--font);
  font-size: 10px; font-weight: 760; letter-spacing: .08em;
  margin-bottom: 5px;
}
.sj-fact b { color: var(--fg-3); }
.sj-virt b { color: color-mix(in srgb, var(--acc) 80%, var(--fg-2)); }

/* 动词高亮：事实里用灰、虚拟里用强调色 —— 变的是同一个动词 */
.sj-em-f {
  font-style: normal; padding: 1px 5px; border-radius: 5px;
  background: color-mix(in srgb, var(--fg) 9%, transparent);
  color: var(--fg-2);
}
.sj-em-v {
  font-style: normal; padding: 1px 5px; border-radius: 5px;
  background: color-mix(in srgb, var(--acc) 16%, transparent);
  color: color-mix(in srgb, var(--acc) 80%, var(--fg));
}

/* 中间："退一格" —— 一条竖线一个箭头，方向朝下 */
.sj-arrow {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 0 8px 3px;
}
.sj-arrow i {
  display: block; width: 1.5px; height: 22px; margin-left: 15px;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--acc) 12%, transparent),
    color-mix(in srgb, var(--acc) 78%, transparent));
  position: relative;
}
.sj-arrow i::after {
  content: ''; position: absolute; left: 50%; bottom: -1px;
  width: 7px; height: 7px; transform: translateX(-50%) rotate(45deg);
  border-right: 1.5px solid color-mix(in srgb, var(--acc) 78%, transparent);
  border-bottom: 1.5px solid color-mix(in srgb, var(--acc) 78%, transparent);
}
.sj-arrow em {
  font-style: normal; font-size: 11px; font-weight: 700; letter-spacing: .04em;
  color: color-mix(in srgb, var(--acc) 72%, var(--fg-2));
}

.sj-fact.in { animation: sjFact .42s cubic-bezier(.2, .9, .3, 1) both; }
.sj-virt.in { animation: sjVirt .46s cubic-bezier(.2, .9, .3, 1) both .1s; }
.sj-arrow.in { animation: sjArrow .4s ease both .06s; }
@keyframes sjFact { from { opacity: .35; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@keyframes sjVirt { from { opacity: 0; transform: translateY(-14px); } to { opacity: 1; transform: none; } }
@keyframes sjArrow { from { opacity: 0; } to { opacity: 1; } }

.sj-rule {
  margin-top: 16px; padding: 10px 14px; border-radius: 10px;
  background: color-mix(in srgb, var(--fg) 4%, transparent);
  font-size: 13px; color: var(--fg-2); line-height: 1.75;
}
.sj-why { margin-top: 10px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }
.sj-data { display: none; }


/* ---- 18. 搬句首：否定词搬到句首，谓语跟着跑 ----
   四块的 DOM 从不重建，只有 order 在变 —— 所以能用 FLIP 让它们真的飞过去。
   橙色=要搬的那块，蓝色=被逼着跑的那块，灰色=站着不动的。 */
.iv-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }
.iv-tab {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  padding: 7px 14px; border-radius: 8px; cursor: pointer; font: inherit;
  border: 1px solid color-mix(in srgb, var(--line-2) 60%, transparent);
  background: transparent; text-align: left;
  transition: background .2s, color .2s, border-color .2s;
}
.iv-tab b { font-size: 12.4px; font-weight: 660; color: var(--fg-3); }
.iv-tab span {
  font-family: var(--mono); font-size: 11px; letter-spacing: .01em;
  color: color-mix(in srgb, #C4671B 70%, var(--fg-3));
}
.iv-tab:hover { border-color: var(--acc-line); }
.iv-tab:hover b { color: var(--fg-2); }
.iv-tab.on {
  background: color-mix(in srgb, var(--acc) 10%, var(--surface));
  border-color: color-mix(in srgb, var(--acc) 45%, transparent);
}
.iv-tab.on b { color: color-mix(in srgb, var(--acc) 78%, var(--fg)); }

.iv-cn { margin-bottom: 10px; font-size: 12.6px; color: var(--fg-3); line-height: 1.65; }

.iv-sent {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 7px;
  padding: 16px 18px; border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
  font-family: var(--serif); font-size: 17px; line-height: 1.75; color: var(--fg);
  transition: border-color .3s, background .3s;
  overflow: hidden;
}
.iv-sent.is-inv { border-color: color-mix(in srgb, var(--acc) 40%, transparent); background: color-mix(in srgb, var(--acc) 5%, var(--surface)); }
/* 只搬了一半：句子是错的，框先用红色说出来 */
.iv-sent.is-half {
  border-color: color-mix(in srgb, var(--bad) 52%, transparent);
  background: color-mix(in srgb, var(--bad) 6%, var(--surface));
}

.iv-ck {
  display: inline-block; padding: 1px 6px; border-radius: 6px;
  transition: color .3s, background .3s;
}
.iv-ck[data-role="subj"] { background: color-mix(in srgb, var(--fg) 7%, transparent); color: var(--fg); }
.iv-ck[data-role="aux"]  { background: color-mix(in srgb, #4E8BFF 16%, transparent); color: color-mix(in srgb, #4E8BFF 72%, var(--fg)); }
.iv-ck[data-role="move"] { background: color-mix(in srgb, #E8933A 18%, transparent); color: color-mix(in srgb, #C4671B 82%, var(--fg)); }
.iv-ck[data-role="rest"] { color: var(--fg-2); }
.iv-sent.is-inv .iv-ck[data-role="move"],
.iv-sent.is-half .iv-ck[data-role="move"] {
  box-shadow: 0 0 0 2px color-mix(in srgb, #E8933A 26%, transparent);
}

.iv-bar { display: flex; align-items: center; gap: 12px; margin-top: 16px; flex-wrap: wrap; }
.iv-go {
  padding: 9px 18px; border-radius: 10px; cursor: pointer; font: inherit;
  font-size: 13px; font-weight: 700; color: #fff;
  border: 1px solid color-mix(in srgb, var(--acc) 80%, #000);
  background: linear-gradient(180deg, color-mix(in srgb, var(--acc) 92%, #fff), var(--acc));
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 30%, transparent),
              0 4px 0 color-mix(in srgb, var(--acc) 45%, #000);
  transition: filter .2s, transform .12s, opacity .2s;
}
.iv-go:hover { filter: brightness(1.06); }
.iv-go:active { transform: translateY(3px); }
.iv-go:disabled {
  cursor: default; opacity: .55; box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 22%, transparent);
  background: color-mix(in srgb, var(--ok) 78%, var(--surface));
  border-color: color-mix(in srgb, var(--ok) 70%, #000);
}
.iv-go:disabled:hover { filter: none; }
.iv-go:disabled:active { transform: none; }
/* 次要动作：还原不该和主按钮抢注意力 */
.iv-undo {
  font: inherit; font-size: 12.5px; padding: 8px 4px; cursor: pointer;
  background: none; border: none; color: var(--fg-3);
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--fg-3) 40%, transparent);
  transition: color .18s;
}
.iv-undo:hover { color: var(--fg-2); }

.iv-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; color: var(--fg-2); line-height: 1.6; }
.iv-judge.is-ok { color: var(--ok); }
.iv-judge.is-bad { color: var(--bad); }
.iv-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }
.iv-why strong { color: var(--fg); }
.iv-data { display: none; }


/* ---- 19. 焊接资格：连词能焊住，副词只能提示 ----
   接缝的"形态"就是判据：连词 → 实心焊点；副词 → 虚线（靠句号断开）；
   硬用逗号连副词 → 红色裂口。一句话怎么改，看接缝就知道。 */
.wv-stage {
  display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap;
  margin: 4px 0 10px;
}
.wv-box {
  flex: 1 1 190px; min-width: 0;
  display: flex; align-items: center;
  padding: 13px 16px; border-radius: 11px;
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
  font-family: var(--serif); font-size: 16px; line-height: 1.55; color: var(--fg);
}

.wv-slot {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  padding: 13px 12px; border-radius: 11px;
  min-width: 54px;
  border: 1.5px dashed color-mix(in srgb, var(--line-2) 75%, transparent);
  background: transparent;
  transition: border-color .3s, background .3s, min-width .34s cubic-bezier(.2, .8, .3, 1);
}
.wv-slot em {
  font-style: normal; font-family: var(--serif); font-size: 16px; font-weight: 600;
  color: var(--fg-3); white-space: nowrap;
}
.wv-slot em.in { animation: wvIn .4s cubic-bezier(.2, .9, .3, 1) both; }
@keyframes wvIn {
  0% { opacity: 0; transform: scale(.72); }
  60% { opacity: 1; transform: scale(1.08); }
  100% { opacity: 1; transform: none; }
}

/* 连词：实心焊点 */
.wv-slot[data-k="conj"] {
  border-style: solid;
  border-color: color-mix(in srgb, var(--ok) 55%, transparent);
  background: color-mix(in srgb, var(--ok) 10%, transparent);
}
.wv-slot[data-k="conj"] em { color: color-mix(in srgb, var(--ok) 82%, var(--fg)); }

/* 副词：虚线 —— 它没焊住，靠的是句号把两句断开 */
.wv-slot[data-k="adv"] {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--acc) 52%, transparent);
  background: color-mix(in srgb, var(--acc) 8%, transparent);
}
.wv-slot[data-k="adv"] em { color: color-mix(in srgb, var(--acc) 78%, var(--fg)); }

/* 硬用逗号连副词：红色裂口 + 抖 */
.wv-slot[data-k="bad"] {
  border-style: solid;
  border-color: color-mix(in srgb, var(--bad) 70%, transparent);
  background: color-mix(in srgb, var(--bad) 10%, transparent);
  animation: wvShake .42s ease;
}
.wv-slot[data-k="bad"] em { color: var(--bad); }
@keyframes wvShake {
  0%, 100% { transform: none; }
  25% { transform: translateX(-4px); }
  60% { transform: translateX(4px); }
  85% { transform: translateX(-2px); }
}

/* 底下那行完整句子：改动后立刻能读一遍 */
.wv-line {
  padding: 10px 14px; border-radius: 10px;
  background: color-mix(in srgb, var(--fg) 3%, transparent);
  font-family: var(--serif); font-size: 15.5px; line-height: 1.65; color: var(--fg-2);
  transition: color .3s;
}

.wv-picks { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 16px; }
.wv-pick {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  padding: 7px 14px 6px; border-radius: 9px; cursor: pointer; font: inherit;
  border: 1px solid color-mix(in srgb, var(--line-2) 72%, transparent);
  background: var(--surface);
  transition: transform .2s cubic-bezier(.2, .8, .3, 1), border-color .2s,
              background .2s, box-shadow .2s;
}
.wv-pick b { font-family: var(--serif); font-size: 14.5px; font-weight: 600; color: var(--fg); }
.wv-pick span { font-size: 10px; letter-spacing: .05em; color: var(--fg-3); }
.wv-pick:hover { transform: translateY(-2px); border-color: var(--acc-line); }
.wv-pick.on {
  border-color: var(--acc);
  background: color-mix(in srgb, var(--acc) 9%, var(--surface));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 12%, transparent);
}
.wv-pick.on b { color: color-mix(in srgb, var(--acc) 74%, var(--fg)); }
.wv-pick[data-k="conj"].on { border-color: var(--ok); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 14%, transparent); }
.wv-pick[data-k="conj"].on b { color: color-mix(in srgb, var(--ok) 78%, var(--fg)); }
.wv-pick[data-k="bad"].on { border-color: var(--bad); box-shadow: 0 0 0 3px color-mix(in srgb, var(--bad) 14%, transparent); }
.wv-pick[data-k="bad"].on b { color: var(--bad); }
.wv-pick[data-k="bad"] { border-style: dashed; }

.wv-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; color: var(--fg-2); }
.wv-judge.is-ok { color: var(--ok); }
.wv-judge.is-adv { color: color-mix(in srgb, var(--acc) 82%, var(--fg-2)); }
.wv-judge.is-bad { color: var(--bad); }
.wv-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }
.wv-data { display: none; }


/* ---- 20. 请 it 站个位：头重脚轻怎么治 ----
   原句和改后的句子在**同一个盒子**里切换（不是并排两行），
   所以长主语"飞过去"和 it"落下来"都被看见。下面那条重心尺是这组件的核心：
   16% → 50% 就是"头重脚轻"被治好的全过程。 */
.ip-cn { margin-bottom: 10px; font-size: 12.6px; color: var(--fg-3); line-height: 1.65; }

.ip-sent {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 7px;
  padding: 18px 20px; border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
  font-family: var(--serif); font-size: 17.5px; line-height: 1.8; color: var(--fg);
  transition: border-color .34s, background .34s;
}
.ip-sent.is-moved {
  border-color: color-mix(in srgb, var(--ok) 42%, transparent);
  background: color-mix(in srgb, var(--ok) 5%, var(--surface));
}
/* 第 ① 步：长主语搬走了、it 还没来 —— 主语位置是空的，句子不成立 */
.ip-sent.is-hole {
  border-color: color-mix(in srgb, var(--bad) 50%, transparent);
  background: color-mix(in srgb, var(--bad) 5%, var(--surface));
}
.ip-hole {
  display: none; padding: 2px 12px; border-radius: 7px;
  border: 1.5px dashed color-mix(in srgb, var(--bad) 62%, transparent);
  background: color-mix(in srgb, var(--bad) 9%, transparent);
  color: color-mix(in srgb, var(--bad) 85%, var(--fg));
  font-size: 15px; font-weight: 700;
  animation: ipHoleIn .38s cubic-bezier(.2,.9,.3,1);
}
@keyframes ipHoleIn {
  from { transform: scale(.8); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

/* 长主语：橙色，因为它是"太重"的那一块 */
.ip-heavy {
  display: inline-block; padding: 2px 9px; border-radius: 7px;
  background: color-mix(in srgb, #E8933A 16%, transparent);
  color: color-mix(in srgb, #C4671B 82%, var(--fg));
  will-change: transform;
}
/* 占位的 it：虚线 + 淡色 —— 它不是真主语，只是个座位 */
.ip-it {
  display: none; padding: 2px 10px; border-radius: 7px;
  border: 1.5px dashed color-mix(in srgb, var(--ok) 62%, transparent);
  background: color-mix(in srgb, var(--ok) 10%, transparent);
  color: color-mix(in srgb, var(--ok) 78%, var(--fg));
  animation: ipDrop .44s cubic-bezier(.2, .9, .3, 1) both;
}
@keyframes ipDrop {
  0% { opacity: 0; transform: translateY(-14px) scale(.85); }
  70% { opacity: 1; transform: translateY(2px) scale(1); }
  100% { opacity: 1; transform: none; }
}
.ip-pred { color: var(--fg-2); }

/* 重心尺：一条横线 + 一个会滑动的点 */
.ip-balance {
  position: relative; height: 30px; margin: 14px 0 4px;
  border-radius: 8px;
  background: linear-gradient(90deg,
    color-mix(in srgb, #E8933A 14%, transparent),
    transparent 45%,
    transparent 55%,
    color-mix(in srgb, var(--ok) 12%, transparent));
}
.ip-balance::before {
  content: ''; position: absolute; left: 8px; right: 8px; top: 50%;
  height: 1px; transform: translateY(-50%);
  background: color-mix(in srgb, var(--line-2) 80%, transparent);
}
.ip-dot {
  position: absolute; top: 50%; left: 16%;
  width: 13px; height: 13px; border-radius: 50%;
  transform: translate(-50%, -50%);
  background: var(--fg);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--fg) 12%, transparent);
  transition: left .6s cubic-bezier(.2, .9, .3, 1), background .4s, box-shadow .4s;
}
.ip-sent.is-moved ~ .ip-balance .ip-dot {
  background: var(--ok);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--ok) 18%, transparent);
}
.ip-lbl {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  font-style: normal; font-size: 11px; letter-spacing: .02em; color: var(--fg-3);
}

.ip-bar { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
.ip-go {
  padding: 8px 18px; border-radius: 10px; cursor: pointer; font: inherit;
  font-size: 13px; font-weight: 700; color: #fff;
  border: 1px solid color-mix(in srgb, var(--ok) 78%, #000);
  background: linear-gradient(180deg, color-mix(in srgb, var(--ok) 88%, #fff), var(--ok));
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 30%, transparent),
              0 4px 0 color-mix(in srgb, var(--ok) 45%, #000);
  transition: filter .2s, transform .12s;
}
.ip-go:hover { filter: brightness(1.06); }
.ip-go:active { transform: translateY(3px); }

.ip-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; color: var(--fg-2); line-height: 1.6; }
.ip-judge.is-ok { color: var(--ok); }
.ip-judge.is-bad { color: var(--bad); }
.ip-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }


/* ---- 21. 名词后面是谁：位置一样，身份完全不同 ----
   五个句子里"跟在名词后面"的那一块用同一种框标出来，
   但配色按成分变 —— 让人看见"位置不能决定身份"。 */
.af-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }
.af-tab {
  padding: 6px 15px; border-radius: 8px; cursor: pointer; font: inherit;
  font-size: 12.4px; font-weight: 640; color: var(--fg-3);
  border: 1px solid color-mix(in srgb, var(--line-2) 60%, transparent);
  background: transparent;
  transition: background .2s, color .2s, border-color .2s;
}
.af-tab:hover { color: var(--fg-2); border-color: var(--acc-line); }
.af-tab.on {
  background: color-mix(in srgb, var(--acc) 10%, var(--surface));
  border-color: color-mix(in srgb, var(--acc) 45%, transparent);
  color: color-mix(in srgb, var(--acc) 78%, var(--fg));
}

.af-sent {
  padding: 16px 18px; border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
  font-family: var(--serif); font-size: 16.5px; line-height: 1.75; color: var(--fg);
  word-break: break-word;
}
.af-mid {
  padding: 2px 7px; border-radius: 7px;
  border: 1.5px solid transparent;
  transition: background .28s, border-color .28s, color .28s;
}
/* 每一种成分一套颜色 —— 位置相同，颜色不同 */
.af-sent[data-role="定语"]   .af-mid { background: color-mix(in srgb, #E8933A 16%, transparent); border-color: color-mix(in srgb, #E8933A 52%, transparent); color: color-mix(in srgb, #C4671B 84%, var(--fg)); }
.af-sent[data-role="谓语"]   .af-mid { background: color-mix(in srgb, #12B8A6 16%, transparent); border-color: color-mix(in srgb, #12B8A6 52%, transparent); color: color-mix(in srgb, #0E8A72 84%, var(--fg)); }
.af-sent[data-role="插入语"] .af-mid { background: color-mix(in srgb, #9268E8 15%, transparent); border-color: color-mix(in srgb, #9268E8 50%, transparent); color: color-mix(in srgb, #7A52D0 84%, var(--fg)); }
.af-sent[data-role="状语"]   .af-mid { background: color-mix(in srgb, #4E8BFF 15%, transparent); border-color: color-mix(in srgb, #4E8BFF 50%, transparent); color: color-mix(in srgb, #2563EB 84%, var(--fg)); }
.af-sent[data-role="同位语"] .af-mid { background: color-mix(in srgb, #E2574C 14%, transparent); border-color: color-mix(in srgb, #E2574C 48%, transparent); color: color-mix(in srgb, #C43A30 84%, var(--fg)); }
.af-pre, .af-post { color: var(--fg-2); }

.af-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; color: var(--fg); }
.af-judge.is-on { color: var(--acc); }
.af-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }
.af-data { display: none; }

/* ---- 22. 把定语切出去：切完主干一眼就出来 ----
   切走的定语不只变灰，还会缩进 + 挂一条左边虚线：缩进表示"它从属于前面的名词"，
   嵌套的那一层再缩进一格 —— 从属关系是靠位移表达的，不是靠文字。 */
.ct-cn { margin-bottom: 10px; font-size: 12.6px; color: var(--fg-3); line-height: 1.65; }

.ct-sent {
  padding: 16px 18px; border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
  font-family: var(--serif); font-size: 16.5px; line-height: 2.1; color: var(--fg);
  word-break: break-word;
  transition: border-color .34s, background .34s;
}
.ct-ck {
  display: inline-block;
  padding: 1px 5px; border-radius: 6px;
  transition: opacity .42s, background .34s, color .34s, transform .42s, margin .42s, border-color .34s;
}
.ct-ck[data-role="main"] {
  background: color-mix(in srgb, var(--acc) 12%, transparent);
  color: color-mix(in srgb, var(--acc) 82%, var(--fg));
  font-weight: 600;
}
.ct-ck[data-role="adv"] { color: var(--fg-2); }

/* 切走之后：定语变灰、缩进、左侧挂一条虚线。
   ★ 按「块自己」的 class 走，不按容器 —— 两刀要分先后来切，容器只能是"切过没有"。 */
.ct-ck.is-cut {
  display: block;
  margin-left: 22px; margin-top: 4px;
  padding: 3px 10px;
  background: color-mix(in srgb, var(--fg) 4%, transparent);
  border-left: 2px dashed color-mix(in srgb, var(--fg-3) 55%, transparent);
  border-radius: 0 7px 7px 0;
  color: color-mix(in srgb, var(--fg-3) 92%, transparent);
  font-size: 15px;
}
.ct-ck[data-role="attr2"].is-cut { margin-left: 44px; }   /* 嵌套的那层再缩一格 */
.ct-sent.has-cut { background: color-mix(in srgb, var(--acc) 4%, var(--surface)); border-color: color-mix(in srgb, var(--acc) 34%, transparent); }

.ct-bar { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
.ct-go {
  padding: 8px 18px; border-radius: 10px; cursor: pointer; font: inherit;
  font-size: 13px; font-weight: 700; color: #fff;
  border: 1px solid color-mix(in srgb, var(--acc) 80%, #000);
  background: linear-gradient(180deg, color-mix(in srgb, var(--acc) 92%, #fff), var(--acc));
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 30%, transparent),
              0 4px 0 color-mix(in srgb, var(--acc) 45%, #000);
  transition: filter .2s, transform .12s;
}
.ct-go:hover { filter: brightness(1.06); }
.ct-go:active { transform: translateY(3px); }

.ct-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; color: var(--fg-2); line-height: 1.6; }
.ct-judge.is-ok { color: var(--ok); }
.ct-judge.is-half { color: var(--warn); }
.ct-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }
.ct-data { display: none; }


/* ---- 23. 状语站在哪儿：一块状语，三个位置 ----
   状语块用蓝色，它移动时其余文字原地不动。标点跟着位置变，
   所以"句首要逗号、句中两边逗号、句末不加逗号"是看出来的，不是背出来的。 */
.ps-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }
.ps-tab {
  padding: 6px 15px; border-radius: 8px; cursor: pointer; font: inherit;
  font-size: 12.4px; font-weight: 640; color: var(--fg-3);
  border: 1px solid color-mix(in srgb, var(--line-2) 60%, transparent);
  background: transparent;
  transition: background .2s, color .2s, border-color .2s;
}
.ps-tab:hover { color: var(--fg-2); border-color: var(--acc-line); }
.ps-tab.on {
  background: color-mix(in srgb, var(--acc) 10%, var(--surface));
  border-color: color-mix(in srgb, var(--acc) 45%, transparent);
  color: color-mix(in srgb, var(--acc) 78%, var(--fg));
}

.ps-sent {
  padding: 16px 18px; border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .035);
  font-family: var(--serif); font-size: 16.5px; line-height: 1.8; color: var(--fg);
  word-break: break-word;
}
.ps-adv {
  /* 必须 inline-block：transform 对 display:inline 的盒子完全不生效。
     之前写成 inline ⇒ FLIP 从上线起就是跳变（采样 8 帧全落在终点）。 */
  display: inline-block; padding: 2px 0; border-radius: 6px;
  background: color-mix(in srgb, #4E8BFF 15%, transparent);
  color: color-mix(in srgb, #2563EB 82%, var(--fg));
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
  will-change: transform;
}
.ps-head, .ps-tail { color: var(--fg-2); }
.ps-cn { margin-top: 10px; font-size: 12.6px; color: var(--fg-3); line-height: 1.65; }

.ps-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; color: var(--ok); line-height: 1.6; }
.ps-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }
.ps-data { display: none; }

/* ---- 24. 谁修饰谁：形容词只盯名词，副词谁都能照顾 ----
   每行是一句话，句子里的修饰语带下划波浪，右边写着「X 修饰 Y」。
   两组切换时 Y 的种类立刻换一批 —— 这就是形容词和副词的全部差别。 */
.md-tabs {
  display: inline-flex; padding: 3px; gap: 2px; margin-bottom: 14px;
  border-radius: 11px;
  background: color-mix(in srgb, var(--fg) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--line-2) 55%, transparent);
}
.md-tab {
  padding: 6px 16px; border-radius: 8px; cursor: pointer; font: inherit;
  font-size: 12.6px; font-weight: 640; color: var(--fg-3);
  border: 0; background: transparent;
  transition: background .22s, color .22s, box-shadow .22s;
}
.md-tab:hover { color: var(--fg-2); }
.md-tab.on {
  background: var(--surface); color: var(--fg);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12), 0 2px 8px -4px rgba(0, 0, 0, .3);
}

.md-rows { display: flex; flex-direction: column; gap: 7px; }
.md-row {
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  padding: 10px 14px; border-radius: 10px; cursor: pointer; font: inherit;
  text-align: left; font-family: var(--serif); font-size: 15.5px; line-height: 1.55;
  border: 1px solid color-mix(in srgb, var(--line-2) 62%, transparent);
  background: var(--surface); color: var(--fg);
  transition: border-color .22s, background .22s, box-shadow .22s, transform .2s;
}
.md-row:hover { transform: translateX(2px); border-color: var(--acc-line); }
.md-row.on {
  border-color: color-mix(in srgb, var(--acc) 48%, transparent);
  background: color-mix(in srgb, var(--acc) 7%, var(--surface));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 10%, transparent);
}
.md-w {
  font-style: normal; padding: 1px 5px; border-radius: 5px;
  background: color-mix(in srgb, #4E8BFF 15%, transparent);
  color: color-mix(in srgb, #2563EB 82%, var(--fg));
}
.md-rel {
  font-family: var(--font); font-size: 11.5px; letter-spacing: .02em; color: var(--fg-3);
}
.md-rel i {
  font-style: normal; padding: 0 3px; color: color-mix(in srgb, #E8933A 82%, var(--fg-2));
}
.md-row.on .md-rel { color: var(--fg-2); }

.md-judge { margin-top: 16px; font-size: 13.8px; font-weight: 720; color: var(--ok); }
.md-why { margin-top: 9px; font-size: 13px; color: var(--fg-2); line-height: 1.78; }
.md-data { display: none; }

/* ============================================================
   7.23 分词的两个公式：位置决定性质
   两块互换位置用 FLIP 真飞；规律条与结论标签同时翻。
   ============================================================ */
.pf-tabs { display: flex; gap: 8px; margin: 2px 0 10px; flex-wrap: wrap; }
.pf-tab {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 2px;
  align-items: flex-start; text-align: left; font-family: inherit;
  padding: 9px 13px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--fg-2);
  cursor: pointer; transition: border-color .22s, background .22s, color .22s, transform .16s;
}
.pf-tab b { font-size: 13.5px; font-weight: 660; color: var(--fg); letter-spacing: .01em; }
.pf-tab span { font-size: 11.5px; color: var(--fg-3); letter-spacing: .02em; }
.pf-tab:hover { border-color: var(--acc-line); }
.pf-tab.on { border-color: var(--acc-line); background: var(--acc-soft); }
.pf-tab.on b { color: var(--acc); }
.pf-tab.on span { color: var(--fg-2); }
.pf-tab:active { transform: scale(.985); }

.pf-rule { display: flex; gap: 8px; margin: 0 0 13px; flex-wrap: wrap; }
.pf-r {
  font-size: 12px; letter-spacing: .02em; color: var(--fg-3);
  padding: 4px 11px; border-radius: 999px; border: 1px dashed var(--line-2);
  transition: color .26s, border-color .26s, background .26s;
}
.pf-r.on {
  color: var(--acc); border-style: solid; border-color: var(--acc-line);
  background: var(--acc-soft); font-weight: 620;
}

.pf-stage {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 0;
  padding: 19px 20px; border-radius: var(--r-md);
  background: var(--surface-2); border: 1px solid var(--line);
  margin-bottom: 11px;
}
.pf-blk {
  font-size: 19px; line-height: 1.55; border-radius: 8px; padding: 2px 7px;
  will-change: transform;
}
.pf-cls { color: var(--acc); background: var(--acc-soft); font-weight: 640; }
.pf-main { color: var(--fg); }
/* 两块之间放一个真实的空格节点：否则复制/朗读得到的是 years,I know（视觉有 gap，文本没空格） */
.pf-sep { flex: 0 0 10px; }

.pf-cn { font-size: 13.5px; color: var(--fg-2); margin: 0 0 11px; padding-left: 2px; }
.pf-verdict { display: flex; align-items: center; gap: 9px; margin-bottom: 10px; }
.pf-v {
  font-size: 12px; font-weight: 660; letter-spacing: .04em;
  padding: 2px 10px; border-radius: 999px;
  background: var(--acc); color: #fff;
}
.pf-vask { font-size: 13px; color: var(--fg-2); }
.pf-note { font-size: 13.4px; line-height: 1.78; color: var(--fg-2); }
.pf-note strong { color: var(--fg); }
.pf-data { display: none; }

/* ============================================================
   7.24 六问定位：判据只有一个 —— 它在回答哪个问题
   选对，短语飞进那一格的槽；六次之后六格自己长成一张对照表。
   ============================================================ */
.q6-top {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 11.5px; letter-spacing: .04em; color: var(--fg-3);
  margin: 2px 0 9px;
}
.q6-stage {
  display: flex; align-items: center; justify-content: center;
  padding: 22px 12px; min-height: 78px; margin-bottom: 13px;
  border-radius: var(--r-md); background: var(--surface-2);
  border: 1px solid var(--line);
}
.q6-ph {
  font-size: 22px; font-weight: 660; letter-spacing: .01em; color: var(--fg);
  will-change: transform; transform-origin: center center;
}
.q6-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 9px; margin-bottom: 12px;
}
.q6-cell { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.q6-q {
  width: 100%; padding: 9px 8px; font-family: inherit; font-size: 13px;
  border-radius: var(--r-sm); border: 1px solid var(--line-2);
  background: var(--surface); color: var(--fg-2); cursor: pointer;
  transition: border-color .2s, color .2s, background .2s, transform .14s;
}
.q6-q:hover { border-color: var(--acc-line); color: var(--fg); }
.q6-q:active { transform: scale(.975); }
.q6-q.is-ok {
  border-color: var(--ok); color: var(--ok); font-weight: 620;
  background: color-mix(in srgb, var(--ok) 11%, transparent);
}
.q6-q.is-bad { border-color: var(--bad); color: var(--bad); }

.q6-slot {
  min-height: 31px; display: flex; align-items: center; justify-content: center;
  border-radius: 8px; border: 1px dashed var(--line-2);
  font-size: 11.5px; color: var(--fg-3); padding: 2px 4px;
  transition: border-color .24s;
}
.q6-slot i { font-style: normal; opacity: .45; }
.q6-cell.solved .q6-slot { border-style: solid; border-color: var(--ok); }
.q6-chip {
  font-size: 12.5px; font-weight: 640; color: var(--ok); line-height: 1.3;
  animation: q6pop .38s cubic-bezier(.2,.9,.3,1);
}
@keyframes q6pop {
  from { transform: scale(.6); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}
.q6-cell.shake { animation: q6shake .34s ease; }
@keyframes q6shake {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-4px); }
  75%      { transform: translateX(4px); }
}

.q6-fb {
  font-size: 13.2px; line-height: 1.72; color: var(--fg-2);
  padding: 10px 13px; min-height: 46px; margin-bottom: 11px;
  border-radius: var(--r-sm); background: var(--surface-2);
  border: 1px solid var(--line);
  transition: border-color .24s, color .24s;
}
.q6-fb.is-ok {
  border-color: color-mix(in srgb, var(--ok) 42%, var(--line));
  color: var(--fg);
}
.q6-fb.is-bad {
  border-color: color-mix(in srgb, var(--bad) 42%, var(--line));
  color: var(--fg);
}
.q6-fb strong { color: var(--fg); }
.q6-acts { display: flex; gap: 8px; }
.q6-next {
  font-family: inherit; font-size: 13px; font-weight: 620;
  padding: 9px 18px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--acc-line); background: var(--acc-soft); color: var(--acc);
  transition: opacity .2s, transform .14s, background .2s;
}
.q6-next:disabled { opacity: .40; cursor: default; }
.q6-next:not(:disabled):hover { border-color: var(--acc); }
.q6-next:not(:disabled):active { transform: scale(.97); }
.q6-data { display: none; }

@media (max-width: 640px) {
  .q6-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .q6-ph { font-size: 19px; }
  .pf-tab { flex: 1 1 100%; }
  .pf-blk { font-size: 17px; }
}

/* ============================================================
   7.25 when / while / as：区别全在两个动作的长短上
   条的长度就是动词的"延续性"—— 切换时让条自己伸、缩、挪。
   ============================================================ */
.tw-tabs { display: flex; gap: 8px; margin: 2px 0 12px; flex-wrap: wrap; }
.tw-tab {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 2px;
  align-items: flex-start; text-align: left; font-family: inherit;
  padding: 9px 13px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--fg-2);
  cursor: pointer; transition: border-color .22s, background .22s, transform .16s;
}
.tw-tab b {
  font-family: var(--mono); font-size: 14px; font-weight: 640; color: var(--fg);
  letter-spacing: .01em;
}
.tw-tab span { font-size: 11.5px; color: var(--fg-3); letter-spacing: .01em; }
.tw-tab:hover { border-color: var(--acc-line); }
.tw-tab.on { border-color: var(--acc-line); background: var(--acc-soft); }
.tw-tab.on b { color: var(--acc); }
.tw-tab:active { transform: scale(.985); }

.tw-axis {
  display: grid; grid-template-columns: 42px auto minmax(150px, 1fr);
  column-gap: 10px; row-gap: 0; align-items: center;
  padding: 13px 16px 11px; border-radius: var(--r-md);
  background: var(--surface-2); border: 1px solid var(--line); margin-bottom: 12px;
}
/* 每行用 display:contents 把三个格子交给同一个 grid —— 否则两行的轴宽不一样，两条条根本没法比 */
.tw-row { display: contents; }
.tw-scale { display: contents; }
.tw-who { font-size: 11px; letter-spacing: .05em; color: var(--fg-3); }
.tw-txt {
  font-family: var(--serif); font-size: 14.5px; color: var(--fg-2); max-width: 270px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tw-track {
  position: relative; height: 16px; margin: 5px 0; border-radius: 999px;
  background: color-mix(in srgb, var(--fg) 5%, transparent);
}
.tw-bar {
  position: absolute; top: 0; height: 16px; border-radius: 999px;
  transition: left .52s cubic-bezier(.22,1,.36,1),
              width .52s cubic-bezier(.22,1,.36,1),
              background .30s ease;
}
.tw-row[data-row="0"] .tw-bar { background: color-mix(in srgb, #4E8BFF 80%, transparent); }
.tw-row[data-row="1"] .tw-bar { background: color-mix(in srgb, #E8933A 84%, transparent); }
.tw-axis.is-sync .tw-bar { background: color-mix(in srgb, var(--ok) 84%, transparent); }
.tw-bar.is-dot { box-shadow: 0 0 0 3px color-mix(in srgb, var(--fg) 9%, transparent); }

.tw-dim {
  grid-column: 3; display: flex; justify-content: space-between;
  margin-top: 2px; font-size: 10.5px; color: var(--fg-3); letter-spacing: .03em;
}
.tw-dim b { font-weight: 520; }

.tw-en { font-family: var(--serif); font-size: 15.5px; color: var(--fg); line-height: 1.7; margin-bottom: 4px; }
.tw-cn { font-size: 13px; color: var(--fg-3); margin-bottom: 10px; }
.tw-note { font-size: 13.4px; line-height: 1.78; color: var(--fg-2); }
.tw-note strong { color: var(--fg); }
.tw-data { display: none; }

/* ============================================================
   7.26 状语从句 → 分词短语：三步
   句子拆成六块摆着不动；每步只让该走的块收缩消失、该变的动词换形。
   用户看到的是同一句话在变短，不是换了一句话。
   ============================================================ */
.st3-cn { font-size: 13px; color: var(--fg-3); margin-bottom: 10px; }
.st3-sent {
  display: flex; flex-wrap: wrap; align-items: baseline;
  padding: 18px 20px; border-radius: var(--r-md);
  background: var(--surface-2); border: 1px solid var(--line);
  font-family: var(--serif); font-size: 18.5px; line-height: 1.8; color: var(--fg);
  margin-bottom: 13px;
}
.st3-ck {
  display: inline-block; white-space: nowrap;
  /* 宽度走 CSS 变量：内联写 width 会盖掉 .gone 的 width:0，块就抽不走 */
  width: var(--w, auto);
  padding: 2px 4px; margin-right: 2px; border-radius: 7px;
  overflow: hidden;
  transition: width .44s cubic-bezier(.22,1,.36,1),
              padding .44s cubic-bezier(.22,1,.36,1),
              margin .44s cubic-bezier(.22,1,.36,1),
              opacity .26s ease, transform .44s cubic-bezier(.22,1,.36,1),
              background .3s, color .3s;
}
.st3-ck.gone {
  width: 0; padding-left: 0; padding-right: 0; margin-right: 0;
  opacity: 0; transform: translateY(-6px) scale(.9);
}
.st3-ck.hl {
  background: color-mix(in srgb, var(--ok) 16%, transparent);
  color: color-mix(in srgb, var(--ok) 86%, var(--fg));
}
.st3-verb { color: var(--fg); }
.st3-ck.morph {
  color: var(--acc); font-weight: 660;
  animation: st3morph .72s ease;
}
@keyframes st3morph {
  0%   { background: color-mix(in srgb, var(--acc) 48%, transparent); }
  100% { background: transparent; }
}

.st3-steps { display: flex; flex-direction: column; gap: 7px; margin-bottom: 13px; }
.st3-step {
  display: flex; align-items: center; gap: 10px; width: 100%;
  text-align: left; font-family: inherit; font-size: 13.2px;
  padding: 9px 13px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--surface); color: var(--fg-2);
  cursor: pointer; transition: border-color .2s, background .2s, color .2s;
}
.st3-step:hover { border-color: var(--acc-line); color: var(--fg); }
.st3-step.on {
  border-color: var(--acc-line); background: var(--acc-soft); color: var(--fg);
}
.st3-n {
  flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11.5px; font-weight: 700;
  background: color-mix(in srgb, var(--fg) 10%, transparent); color: var(--fg-2);
  transition: background .2s, color .2s;
}
.st3-step.on .st3-n { background: var(--acc); color: #fff; }
.st3-a { min-width: 0; }

.st3-verdict {
  font-size: 13.6px; font-weight: 640; color: var(--ok); line-height: 1.65;
  margin-bottom: 8px;
}
.st3-note { font-size: 13.2px; line-height: 1.78; color: var(--fg-2); }
.st3-note strong { color: var(--fg); }
.st3-data { display: none; }

@media (max-width: 640px) {
  .tw-tab { flex: 1 1 100%; }
  .tw-row, .tw-scale { grid-template-columns: 42px minmax(0, 1fr); }
  .tw-axis { grid-template-columns: 38px minmax(0, 1fr); }
  .tw-track, .tw-dim { grid-column: 1 / -1; }
  .tw-txt { grid-column: 2; }
  .tw-txt { font-size: 13.5px; }
  .st3-sent { font-size: 17px; padding: 15px 15px; }
  .st3-ck { font-size: 17px; }
}

/* ============================================================
   7.27 三把筛子找状语
   三条判据都是"初筛"，各自会被同一类东西骗到 —— 所以让它们各自亮一次。
   ============================================================ */
.sv-sieves {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px; margin: 2px 0 12px;
}
.sv-sieve {
  display: flex; flex-direction: column; gap: 3px;
  text-align: left; font-family: inherit;
  padding: 10px 12px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--fg-2);
  cursor: pointer; transition: border-color .2s, background .2s, transform .14s;
}
.sv-sieve b { font-size: 13px; font-weight: 640; color: var(--fg); letter-spacing: .01em; }
.sv-sieve span { font-size: 11.5px; color: var(--fg-3); line-height: 1.45; }
.sv-sieve:hover { border-color: var(--acc-line); }
.sv-sieve.on { border-color: var(--acc-line); background: var(--acc-soft); }
.sv-sieve.on b { color: var(--acc); }
.sv-sieve:active { transform: scale(.985); }

.sv-sent {
  display: flex; flex-wrap: wrap; align-items: baseline;
  padding: 18px 20px; border-radius: var(--r-md);
  background: var(--surface-2); border: 1px solid var(--line);
  font-family: var(--serif); font-size: 18px; line-height: 1.85; color: var(--fg);
  margin-bottom: 12px;
}
.sv-ck {
  display: inline-block; padding: 2px 5px; margin-right: 3px;
  border-radius: 7px; border: 1px solid transparent; cursor: pointer;
  transition: background .24s, border-color .24s, color .24s, opacity .3s;
}
.sv-ck:hover { background: color-mix(in srgb, var(--fg) 6%, transparent); }
.sv-ck.hit {
  border-color: color-mix(in srgb, #E8933A 68%, transparent);
  background: color-mix(in srgb, #E8933A 13%, transparent);
}
.sv-ck.on {
  border-color: var(--acc); background: var(--acc-soft); color: var(--acc);
}
.sv-ck.is-adv {
  border-color: color-mix(in srgb, var(--ok) 68%, transparent);
  background: color-mix(in srgb, var(--ok) 14%, transparent);
  color: color-mix(in srgb, var(--ok) 88%, var(--fg));
}
.sv-ck.no { opacity: .44; }
.sv-ck.is-adv { animation: svpop .48s cubic-bezier(.2,.9,.3,1); }
@keyframes svpop {
  from { transform: scale(.94); }
  to   { transform: scale(1); }
}

.sv-fb {
  font-size: 13.2px; line-height: 1.72; color: var(--fg-2);
  padding: 10px 13px; min-height: 48px; margin-bottom: 11px;
  border-radius: var(--r-sm); background: var(--surface-2);
  border: 1px solid var(--line);
  transition: border-color .24s, color .24s;
}
.sv-fb.is-hit { border-color: color-mix(in srgb, #E8933A 40%, var(--line)); color: var(--fg); }
.sv-fb.is-ck { border-color: var(--acc-line); color: var(--fg); }
.sv-fb.is-ans { border-color: color-mix(in srgb, var(--ok) 44%, var(--line)); color: var(--fg); }
.sv-fb strong { color: var(--fg); }

.sv-acts { display: flex; gap: 8px; margin-bottom: 11px; }
.sv-go {
  font-family: inherit; font-size: 13px; font-weight: 620;
  padding: 9px 18px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--acc-line); background: var(--acc-soft); color: var(--acc);
  transition: opacity .2s, transform .14s, border-color .2s;
}
.sv-go:disabled { opacity: .40; cursor: default; }
.sv-go:not(:disabled):hover { border-color: var(--acc); }
.sv-go:not(:disabled):active { transform: scale(.97); }

.sv-cn { font-size: 12.6px; color: var(--fg-3); line-height: 1.72; margin-bottom: 10px; }
.sv-data { display: none; }

@media (max-width: 640px) {
  .sv-sieves { grid-template-columns: 1fr; }
  .sv-sent { font-size: 16.5px; padding: 15px 15px; }
  .sv-ck { margin-right: 2px; }
}

/* ============================================================
   7.28 四步扫一个长难句
   颜色就是成分类型：主语蓝 / 谓语绿 / 宾语紫 / 状语橙 / 定语与同位语青。
   四步走完按一下，主干浮出来、化妆品沉下去 —— 结构层次靠明暗说话。
   ============================================================ */
.sc-steps {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 7px; margin: 2px 0 12px;
}
.sc-step {
  display: flex; align-items: center; gap: 8px;
  text-align: left; font-family: inherit; font-size: 12.5px;
  padding: 9px 10px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--fg-2);
  cursor: pointer; transition: border-color .2s, background .2s, color .2s, transform .14s;
}
.sc-step:hover { border-color: var(--acc-line); }
.sc-step.on { border-color: var(--acc-line); background: var(--acc-soft); color: var(--fg); }
.sc-step:active { transform: scale(.985); }
.sc-n {
  flex: 0 0 auto; width: 19px; height: 19px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700;
  background: color-mix(in srgb, var(--fg) 10%, transparent); color: var(--fg-2);
  transition: background .2s, color .2s;
}
.sc-step.on .sc-n { background: var(--acc); color: #fff; }

.sc-sent {
  display: flex; flex-wrap: wrap; align-items: baseline;
  padding: 18px 20px; border-radius: var(--r-md);
  background: var(--surface-2); border: 1px solid var(--line);
  font-family: var(--serif); font-size: 17.5px; line-height: 1.9; color: var(--fg);
  margin-bottom: 12px;
}
.sc-ck {
  display: inline-block; padding: 2px 5px; margin-right: 3px;
  border-radius: 7px; border: 1px solid transparent; cursor: pointer;
  color: var(--fg);
  transition: background .34s ease, color .34s ease,
              border-color .34s ease, opacity .5s ease;
}
.sc-ck:hover { background: color-mix(in srgb, var(--fg) 6%, transparent); }

/* 找到之后按成分上色 —— 颜色本身就是判据，不用另外标注 */
.sc-ck[data-role="subj"].found {
  background: color-mix(in srgb, #4E8BFF 18%, transparent);
  color: color-mix(in srgb, #4E8BFF 88%, var(--fg));
}
.sc-ck[data-role="verb"].found {
  background: color-mix(in srgb, var(--ok) 20%, transparent);
  color: color-mix(in srgb, var(--ok) 90%, var(--fg));
  font-weight: 640;
}
.sc-ck[data-role="obj"].found {
  background: color-mix(in srgb, #A46BFF 18%, transparent);
  color: color-mix(in srgb, #A46BFF 86%, var(--fg));
}
.sc-ck[data-role="adv"].found, .sc-ck[data-role="advc"].found {
  background: color-mix(in srgb, #E8933A 16%, transparent);
  color: color-mix(in srgb, #C4671B 84%, var(--fg));
}
.sc-ck[data-role="attr"].found, .sc-ck[data-role="appos"].found {
  background: color-mix(in srgb, #22B5C3 16%, transparent);
  color: color-mix(in srgb, #1599A6 86%, var(--fg));
}

.sc-ck.on { border-color: var(--acc); }
.sc-ck.ghost { opacity: .30; }

.sc-fb {
  font-size: 13.2px; line-height: 1.72; color: var(--fg-2);
  padding: 10px 13px; min-height: 50px; margin-bottom: 11px;
  border-radius: var(--r-sm); background: var(--surface-2);
  border: 1px solid var(--line);
  transition: border-color .24s, color .24s;
}
.sc-fb.is-step, .sc-fb.is-ck { border-color: var(--acc-line); color: var(--fg); }
.sc-fb.is-done { border-color: color-mix(in srgb, var(--ok) 44%, var(--line)); color: var(--fg); }
.sc-fb strong { color: var(--fg); }

.sc-acts { display: flex; gap: 8px; margin-bottom: 11px; }
.sc-go {
  font-family: inherit; font-size: 13px; font-weight: 620;
  padding: 9px 18px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--acc-line); background: var(--acc-soft); color: var(--acc);
  transition: opacity .2s, transform .14s, border-color .2s;
}
.sc-go:disabled { opacity: .40; cursor: default; }
.sc-go:not(:disabled):hover { border-color: var(--acc); }
.sc-go:not(:disabled):active { transform: scale(.97); }

.sc-cn { font-size: 12.6px; color: var(--fg-3); line-height: 1.72; margin-bottom: 10px; }
.sc-data { display: none; }

@media (max-width: 640px) {
  .sc-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sc-sent { font-size: 16px; padding: 15px 15px; }
  .sc-ck { margin-right: 2px; }
}

/* ============================================================
   7.29 点兵闪卡
   答案默认折叠：展开用 grid-template-rows 0fr→1fr，
   不用 max-height（上限远大于内容时会前重后轻，看着像瞬开）。
   ============================================================ */
.dr-tabs { display: flex; align-items: center; gap: 6px; margin: 2px 0 12px; flex-wrap: wrap; }
.dr-tab {
  width: 30px; height: 30px; border-radius: 9px;
  font-family: inherit; font-size: 12.5px; font-weight: 620;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--fg-2);
  cursor: pointer; transition: border-color .2s, background .2s, color .2s, transform .14s;
}
.dr-tab:hover { border-color: var(--acc-line); }
.dr-tab:active { transform: scale(.94); }
.dr-tab.on { border-color: var(--acc); background: var(--acc-soft); color: var(--acc); }
.dr-tab.ok { border-color: color-mix(in srgb, var(--ok) 62%, transparent); color: var(--ok); }
.dr-tab.mid { border-color: color-mix(in srgb, var(--warn) 62%, transparent); color: var(--warn); }
.dr-tab.bad { border-color: color-mix(in srgb, var(--bad) 58%, transparent); color: var(--bad); }
.dr-tab.ok.on, .dr-tab.mid.on, .dr-tab.bad.on {
  background: color-mix(in srgb, currentColor 14%, transparent);
}
/* 当前题必须和「这题我标了什么色」区分开：加一圈蓝环，颜色留给标记 */
.dr-tab.on { box-shadow: 0 0 0 2px color-mix(in srgb, var(--acc) 40%, transparent); }
.dr-prog { margin-left: auto; font-size: 11.5px; letter-spacing: .03em; color: var(--fg-3); }
.dr-prog b { color: var(--fg); font-weight: 640; }

.dr-q {
  font-family: var(--serif); font-size: 16.5px; line-height: 1.8; color: var(--fg);
  padding: 18px 20px; border-radius: var(--r-md);
  background: var(--surface-2); border: 1px solid var(--line);
  margin-bottom: 11px;
}

.dr-ans {
  display: grid; grid-template-rows: 0fr; opacity: 0; margin-bottom: 0;
  transition: grid-template-rows .44s cubic-bezier(.22,1,.36,1),
              opacity .30s ease, margin-bottom .44s cubic-bezier(.22,1,.36,1);
}
.dr-ans.on { grid-template-rows: 1fr; opacity: 1; margin-bottom: 11px; }
.dr-ans-inner { overflow: hidden; min-height: 0; }

.dr-en {
  font-family: var(--serif); font-size: 16px; line-height: 1.75;
  color: color-mix(in srgb, var(--ok) 88%, var(--fg));
  padding: 12px 14px; border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--ok) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--ok) 30%, transparent);
}
.dr-alt {
  margin-top: 7px; font-family: var(--serif); font-size: 13px;
  line-height: 1.7; color: var(--fg-3);
}
.dr-note { margin-top: 9px; font-size: 13.2px; line-height: 1.75; color: var(--fg-2); }
.dr-note strong { color: var(--fg); }

.dr-acts { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 11px; }
.dr-show {
  font-family: inherit; font-size: 13px; font-weight: 620;
  padding: 9px 18px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--acc-line); background: var(--acc-soft); color: var(--acc);
  transition: border-color .2s, transform .14s;
}
.dr-show:hover { border-color: var(--acc); }
.dr-show:active { transform: scale(.97); }
.dr-grade { display: flex; gap: 6px; }
.dr-g {
  font-family: inherit; font-size: 12px; padding: 7px 12px; border-radius: 999px;
  border: 1px solid var(--line-2); background: transparent; color: var(--fg-3);
  cursor: pointer; transition: border-color .18s, color .18s, background .18s;
}
.dr-g:hover { color: var(--fg); }
.dr-g[data-drg="ok"].on {
  border-color: var(--ok); color: var(--ok);
  background: color-mix(in srgb, var(--ok) 12%, transparent);
}
.dr-g[data-drg="mid"].on {
  border-color: var(--warn); color: var(--warn);
  background: color-mix(in srgb, var(--warn) 12%, transparent);
}
.dr-g[data-drg="bad"].on {
  border-color: var(--bad); color: var(--bad);
  background: color-mix(in srgb, var(--bad) 12%, transparent);
}

.dr-nav { display: flex; gap: 8px; margin-bottom: 10px; }
.dr-prev, .dr-next {
  font-family: inherit; font-size: 12.5px; padding: 8px 15px; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--fg-2);
  cursor: pointer; transition: border-color .18s, color .18s;
}
.dr-prev:disabled, .dr-next:disabled { opacity: .35; cursor: default; }
.dr-prev:not(:disabled):hover, .dr-next:not(:disabled):hover {
  border-color: var(--acc-line); color: var(--fg);
}
.dr-data { display: none; }

@media (max-width: 640px) {
  .dr-q { font-size: 15px; padding: 15px 15px; }
  .dr-en { font-size: 14.5px; }
  .dr-grade { width: 100%; }
  .dr-g { flex: 1 1 0; text-align: center; padding: 7px 6px; }
}

/* ============================================================
   点词查义：贴在被点单词正下方的小卡片
   fixed 定位 + 高 z-index（要盖过 sticky 顶栏），出现时轻微下落
   ============================================================ */
.wd-card {
  position: fixed; left: 0; top: 0; z-index: 300;
  display: none; max-width: min(320px, calc(100vw - 24px));
  padding: 9px 13px 10px;
  border-radius: 12px;
  background: var(--surface);
  border: 1px solid var(--line-2);
  box-shadow: 0 8px 28px -10px rgba(0, 0, 0, .55), 0 2px 6px rgba(0, 0, 0, .18);
  backdrop-filter: blur(10px);
  font-size: 13px; line-height: 1.6;
  animation: wdIn .16s ease both;
}
.wd-card.on { display: block; }
@keyframes wdIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.wd-w {
  font-family: var(--serif); font-size: 15px; font-weight: 660;
  color: var(--fg); letter-spacing: .01em;
}
.wd-p {
  margin-left: 7px; font-size: 12px; font-style: normal;
  color: var(--fg-3); letter-spacing: .02em;
}
.wd-d {
  display: block; margin-top: 3px;
  color: var(--fg-2); font-size: 12.8px; line-height: 1.62;
  word-break: break-word;
}
.wd-card.is-loading .wd-d { color: var(--fg-3); }

/* 被点中的那个词：荧光绿的字 + 一圈绿色光晕（"荧光笔划上去"的观感），依然不铺底色。
   ::highlight() 支持 text-shadow，这就是能做发光的原因；几何一点没动，所以点击不会跳。 */
::highlight(wd-hit) {
  color: var(--wdglow);
  background-color: transparent;
  -webkit-text-stroke: .35px currentColor;
  text-shadow:
    0 0 5px color-mix(in srgb, var(--wdglow) 60%, transparent),
    0 0 12px color-mix(in srgb, var(--wdglow) 30%, transparent);
}
/* 鼠标悬停的那个词：只把字变深绿 —— 不铺底色、不放大、不位移，所以绝不会跳 */
::highlight(wd-hover) {
  color: var(--wdgreen);
  background-color: transparent;
}
/* 光标变小手 —— 只加在"词所在的那个块"上，离开正文就撤掉 */
.is-word-hover,
.is-word-hover * { cursor: pointer; }

/* ---------- 点词设置面板 ---------- */
.wd-pop {
  position: fixed; left: 0; top: 0; z-index: 320;
  display: none; width: 232px;
  padding: 12px 14px 11px;
  border-radius: 12px;
  background: var(--surface);
  border: 1px solid var(--line-2);
  box-shadow: 0 10px 32px -12px rgba(0, 0, 0, .55), 0 2px 6px rgba(0, 0, 0, .18);
  animation: wdIn .16s ease both;
}
.wd-pop.on { display: block; }
.wp-t {
  font-size: 12px; font-weight: 660; color: var(--fg);
  letter-spacing: .04em; margin-bottom: 9px;
}
.wp-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 6px 0; cursor: pointer;
  font-size: 12.8px; color: var(--fg-2);
}
.wp-row:hover { color: var(--fg); }
.wp-row input { position: absolute; opacity: 0; width: 0; height: 0; }
.wp-sw {
  position: relative; flex: 0 0 auto;
  width: 34px; height: 20px; border-radius: 999px;
  background: color-mix(in srgb, var(--fg) 16%, transparent);
  transition: background .2s;
}
.wp-sw::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 16px; height: 16px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .3);
  transition: transform .2s;
}
.wp-row input:checked + .wp-sw { background: var(--acc); }
.wp-row input:checked + .wp-sw::after { transform: translateX(14px); }
.wp-row input:focus-visible + .wp-sw { outline: 2px solid var(--acc-line); outline-offset: 2px; }
/* 口音：分段控件（不是开关 —— 二选一，两个都要看得见） */
.wp-segrow { cursor: default; }
.wp-segrow:hover { color: var(--fg-2); }
.wp-seg {
  display: inline-flex; gap: 0; padding: 2px; border-radius: 8px;
  background: color-mix(in srgb, var(--fg) 10%, transparent);
}
.wp-seg button {
  -webkit-appearance: none; appearance: none;
  border: 0; margin: 0; background: transparent; cursor: pointer;
  padding: 3px 10px; border-radius: 6px;
  font-family: inherit; font-size: 11.5px; line-height: 1.5;
  color: var(--fg-3); transition: background .16s, color .16s;
}
.wp-seg button:hover { color: var(--fg); }
.wp-seg button.on {
  background: color-mix(in srgb, var(--acc) 26%, var(--surface));
  color: var(--fg); font-weight: 620;
}
.wp-seg button:focus-visible { outline: 2px solid var(--acc-line); outline-offset: 1px; }
.wp-hint {
  margin-top: 8px; padding-top: 8px;
  border-top: 1px solid var(--line);
  font-size: 11.5px; line-height: 1.6; color: var(--fg-3);
}


