/* ==== main.css ==== */
/* ============================================
   高中知识点复习系统 - 主样式 v6.0
   Linear 暗调科技风 · 统一设计系统
   ============================================

   ## CSS 命名规范

   全项目采用 BEM-like 前缀约定：

   | 前缀  | 用途         | 示例                     |
   |-------|-------------|--------------------------|
   | mod-  | 模块卡片/通用  | .mod-card, .mod-back-btn |
   | ov-   | 概览页面      | .ov-expanded, .ovc-item  |
   | mn-   | 数学笔记      | .mn-card, .mn-review-page|
   | eb-   | 错题本        | .eb-item, .eb-filter     |
   | eng-  | 英语模块      | .eng-reader, .eng-shelf  |
   | dv-   | 公式推导      | .dv-step, .dv-warn       |

   通用组件（跨页面复用）不加前缀：.card, .btn, .nav-btn, .overlay, .toast

   修饰符用 -- 分隔：.item-card--folder, .filter-chip.active
   子元素用 __ 分隔（可选）：.mod-card__inner

   新增样式时请遵循此前缀约定，保持全项目一致性。

   ## v6.0 设计原则（Linear 暗调科技风）
   - 暗色优先：近黑分层背景，视觉层次由「边框 + 背景明度差」表达
   - 细边框：1px、低透明度，hover 提亮
   - 小圆角：4-12px，胶囊仅用于 chip/导航按钮
   - 快速动效：100-200ms，曲线 cubic-bezier(0.25,0.46,0.45,0.94)
   - 无大面积毛玻璃：仅顶部导航与 overlay 保留轻微 blur

   ============================================ */

/* ===== 1. Design Tokens（亮色主题：中性冷灰） ===== */
:root {
  color-scheme: light;

  /* ===== 表面色分层（透明 UI 的基础） =====
     每个表面色都有两个变量：
       --x-solid  真实的不透明颜色（永不改变，是"底"）
       --x        实际使用的颜色，默认等于 solid
     启用壁纸时，`html.has-wallpaper` 只需重定义 --x 为半透明版本，
     solid 那份仍然留在原地供 color-mix 引用 —— 不用在两个文件里各维护一套颜色。
     ⚠ 不要在别处直接写死颜色：改色只改 solid。 */
  --bg-primary-solid: #fbfbfc;
  --bg-secondary-solid: #ffffff;
  --bg-tertiary-solid: #f4f5f6;
  --surface-solid: #ffffff;
  --surface-strong-solid: #ffffff;

  --bg-primary: var(--bg-primary-solid);
  --bg-secondary: var(--bg-secondary-solid);
  --bg-tertiary: var(--bg-tertiary-solid);
  --bg-hover: #eef0f2;
  --bg-active: #e4e6e9;

  --surface: var(--surface-solid);
  --surface-strong: var(--surface-strong-solid);
  --surface-border: rgba(0, 0, 0, 0.08);

  --text-primary: #16181d;
  --text-secondary: #5c5f66;
  /* #8b8e96 only reached 3.03:1 on the light surfaces — below AA for the small
     labels this token carries across most pages. Darkened to clear 4.5:1. */
  --text-tertiary: #656d79;
  --text-inverse: #ffffff;

  --accent: #4c56c0;
  --accent-hover: #3f48a8;
  --accent-dark: #353d90;
  --accent-light: rgba(76, 86, 192, 0.08);
  --accent-subtle: rgba(76, 86, 192, 0.15);
  --accent-rgb: 76, 86, 192;

  --success: #2da44e;
  --success-light: rgba(45, 164, 78, 0.09);
  --warning: #bf8700;
  --warning-light: rgba(191, 135, 0, 0.09);
  --danger: #d1352c;
  --danger-light: rgba(209, 53, 44, 0.08);

  --border: rgba(0, 0, 0, 0.08);
  --border-light: rgba(0, 0, 0, 0.05);
  --border-hover: rgba(0, 0, 0, 0.16);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.05);
  --shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.07);
  --shadow-xl: 0 8px 24px rgba(0, 0, 0, 0.1);
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-card-hover: 0 3px 10px rgba(0, 0, 0, 0.07);

  --code-bg: #16181d;
  --code-text: #e8eaed;

  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 32px;
  --space-2xl: 52px;
  --space-3xl: 72px;

  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-xl: 10px;
  --radius-2xl: 12px;
  --radius-full: 9999px;

  --transition-fast: 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --transition-base: 130ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --transition-normal: 160ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --transition-slow: 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);

  --nav-height: 52px;
  --max-width: 1120px;
  --sidebar-width: 280px;

  /* Typography scale */
  --fs-xs: 0.75rem;
  --fs-sm: 0.82rem;
  --fs-md: 0.9rem;
  --fs-lg: 1.05rem;
  --fs-xl: 1.25rem;
  --fs-2xl: 1.6rem;
  --lh-tight: 1.3;
  --lh-normal: 1.55;
  --lh-relaxed: 1.75;

  /* Elevation aliases (map to shadow tokens) */
  --elevation-1: var(--shadow-sm);
  --elevation-2: var(--shadow-md);
  --elevation-3: var(--shadow-lg);
  --elevation-4: var(--shadow-xl);

  /* Accent active/pressed state + focus ring */
  --accent-active: var(--accent-dark);
  --focus-ring: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent);
}

/* ===== 2. Dark Theme Tokens（默认主题：近黑分层） ===== */
[data-theme="dark"] {
  color-scheme: dark;

  /* 表面色分层（见 :root 的说明）；改色只改 solid。 */
  --bg-primary-solid: #08090a;
  --bg-secondary-solid: #101113;
  --bg-tertiary-solid: #17181b;
  --surface-solid: #101113;
  --surface-strong-solid: #141518;

  --bg-primary: var(--bg-primary-solid);
  --bg-secondary: var(--bg-secondary-solid);
  --bg-tertiary: var(--bg-tertiary-solid);
  --bg-hover: #1c1e21;
  --bg-active: #24262a;

  --surface: var(--surface-solid);
  --surface-strong: var(--surface-strong-solid);
  --surface-border: rgba(255, 255, 255, 0.08);

  --text-primary: #eeeff1;
  --text-secondary: #9a9ca3;
  /* #6f7178 sat at 3.97:1 on the dark surfaces — below AA for the small labels
     this token is used for across most pages. Lightened (not darkened: the
     dark theme needs a lighter tertiary) to clear 4.5:1. */
  --text-tertiary: #8b8f98;

  --accent: #5e6ad2;
  --accent-hover: #6e79d6;
  --accent-dark: #7c86dd;
  --accent-light: rgba(94, 106, 210, 0.12);
  --accent-subtle: rgba(94, 106, 210, 0.22);
  --accent-rgb: 94, 106, 210;

  --success: #4cb782;
  --success-light: rgba(76, 183, 130, 0.12);
  --warning: #d9a344;
  --warning-light: rgba(217, 163, 68, 0.12);
  --danger: #eb5757;
  --danger-light: rgba(235, 87, 87, 0.1);

  --border: rgba(255, 255, 255, 0.08);
  --border-light: rgba(255, 255, 255, 0.05);
  --border-hover: rgba(255, 255, 255, 0.16);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 4px 14px rgba(0, 0, 0, 0.45);
  --shadow-xl: 0 12px 32px rgba(0, 0, 0, 0.55);
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-card-hover: 0 4px 12px rgba(0, 0, 0, 0.45);

  --code-bg: #141518;
}

/* ===== 2.5 Page transition + Global UX utilities ===== */
@keyframes pageEnter {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
#page-container {
  animation: pageEnter .16s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
  will-change: opacity, transform;
}

@keyframes cardFadeUp {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.stagger > * { animation: cardFadeUp .2s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; }
.stagger > *:nth-child(1)  { animation-delay: .015s; }
.stagger > *:nth-child(2)  { animation-delay: .03s; }
.stagger > *:nth-child(3)  { animation-delay: .045s; }
.stagger > *:nth-child(4)  { animation-delay: .06s; }
.stagger > *:nth-child(5)  { animation-delay: .075s; }
.stagger > *:nth-child(6)  { animation-delay: .09s; }
.stagger > *:nth-child(7)  { animation-delay: .105s; }
.stagger > *:nth-child(8)  { animation-delay: .12s; }
.stagger > *:nth-child(n+9){ animation-delay: .135s; }

html { scroll-behavior: smooth; }

/* Back to top button */
.back-to-top {
  position: fixed; bottom: 24px; right: 24px; z-index: 900;
  width: 40px; height: 40px; border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: var(--surface-strong);
  color: var(--text-secondary);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  box-shadow: var(--shadow-md);
  transition: opacity .15s, transform .15s, color .15s, border-color .15s;
}
.back-to-top:hover { color: var(--accent); border-color: var(--border-hover); transform: translateY(-2px); }
.back-to-top.hidden { opacity: 0; pointer-events: none; transform: translateY(6px); }

/* Toast icon styles */
.toast { display: flex; align-items: center; gap: 10px; }
.toast .toast-icon {
  width: 18px; height: 18px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  font-size: 11px; font-weight: 700;
}
.toast.success .toast-icon { background: var(--success); color: #fff; }
.toast.error   .toast-icon { background: var(--danger);  color: #fff; }
.toast.warning .toast-icon { background: var(--warning); color: #fff; }
.toast.info    .toast-icon { background: var(--accent);  color: #fff; }
.toast.success .toast-icon::before { content: '✓'; }
.toast.error   .toast-icon::before { content: '✕'; }
.toast.warning .toast-icon::before { content: '!'; }
.toast.info    .toast-icon::before { content: 'i'; font-style: italic; }

/* Nav button — active route indicator */
.nav-btn.is-active {
  color: var(--nav-active-ink, var(--accent));
  background: var(--accent-light);
  border-color: var(--accent-subtle);
}
.nav-btn.is-active svg { color: var(--nav-active-ink, var(--accent)); }

/* Keyboard shortcut hint（Linear 式 kbd） */
.nav-kbd {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 18px; padding: 0 5px;
  font-size: 10px; font-weight: 600; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  color: var(--text-tertiary);
  background: var(--bg-tertiary);
  border: 1px solid var(--border);
  border-bottom-width: 2px;
  border-radius: 4px;
  margin-left: 4px;
  line-height: 1;
}
@media (max-width: 600px) { .nav-kbd { display: none; } }

/* Skeleton shimmer */
@keyframes shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}
.skeleton-shimmer {
  background: linear-gradient(90deg, var(--bg-tertiary) 25%, var(--bg-hover) 50%, var(--bg-tertiary) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
  border-radius: var(--radius-md);
}

/* ===== 3. Reset & Base ===== */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  -webkit-tap-highlight-color: transparent;
}

body {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
    "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
    "Noto Sans SC", sans-serif;
  background-color: var(--bg-primary);
  color: var(--text-primary);
  line-height: 1.55;
  min-height: 100vh;
  overflow-x: hidden;
  transition: background var(--transition-base), color var(--transition-base);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  letter-spacing: -0.01em;
}

/* 顶部极淡单色辉光（替代旧版彩色光斑） */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  background: radial-gradient(ellipse 900px 420px at 50% -8%, rgba(var(--accent-rgb), 0.04) 0%, transparent 60%);
  pointer-events: none;
  z-index: 0;
}

[data-theme="dark"] body::before {
  background: radial-gradient(ellipse 900px 420px at 50% -8%, rgba(var(--accent-rgb), 0.07) 0%, transparent 60%);
}

#app { position: relative; z-index: 1; }

@supports (padding-bottom: env(safe-area-inset-bottom)) {
  body { padding-bottom: env(safe-area-inset-bottom); }
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); }
img { max-width: 100%; display: block; }

::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.15); border-radius: 3px; }
[data-theme="dark"] ::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); }
::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.25); }
[data-theme="dark"] ::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.2); }
::-webkit-scrollbar-corner { background: transparent; }

::selection { background: rgba(var(--accent-rgb), 0.25); color: var(--text-primary); }

/* ===== 4. Layout / Nav ===== */
#nprogress {
  position: fixed; top: 0; left: 0; width: 0; height: 2px;
  z-index: 9999; pointer-events: none; transition: none;
}
#nprogress.loading { width: 70%; transition: width 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94); }
#nprogress.done { width: 100%; opacity: 0; transition: width 0.15s ease, opacity 0.25s ease 0.1s; }
.nprogress-bar { height: 100%; background: var(--accent); border-radius: 0 1px 1px 0; box-shadow: 0 0 8px rgba(var(--accent-rgb), 0.6); }

#top-nav {
  position: fixed; top: 0; left: 0; right: 0; height: var(--nav-height);
  background: color-mix(in srgb, var(--bg-primary) 85%, transparent);
  border-bottom: 1px solid var(--border);
  z-index: 100;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: border-color var(--transition-base), background var(--transition-base);
  contain: layout style;
}
#top-nav.scrolled {
  border-bottom-color: var(--border-hover);
  background: color-mix(in srgb, var(--bg-primary) 92%, transparent);
}
[data-theme="dark"] #top-nav.scrolled {
  border-bottom-color: rgba(255,255,255,0.1);
}

.nav-inner {
  max-width: var(--max-width); margin: 0 auto; height: 100%;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--space-lg);
}

.nav-logo {
  display: flex; align-items: center; gap: 10px;
  color: var(--text-primary); font-weight: 600; font-size: 1rem;
  text-decoration: none; letter-spacing: -0.02em;
}
.logo-icon {
  display: flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: var(--radius-md);
  background: var(--accent); color: white; padding: 0;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.12);
}
.logo-icon svg { width: 15px; height: 15px; color: white; }

.nav-actions { display: flex; align-items: center; gap: var(--space-sm); }

.nav-btn {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 12px; border: 1px solid var(--border);
  border-radius: var(--radius-md); background: var(--bg-secondary);
  color: var(--text-secondary); cursor: pointer;
  font-size: 0.82rem; font-weight: 500;
  transition: all var(--transition-fast);
}
.nav-btn:hover { background: var(--bg-hover); color: var(--text-primary); border-color: var(--border-hover); }
.nav-btn:active { background: var(--bg-active); }
.nav-btn:focus-visible, .nav-logo:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.nav-btn .btn-label { display: none; }

[data-theme="light"] .icon-moon { display: none; }
[data-theme="dark"] .icon-sun { display: none; }

#page-container {
  max-width: var(--max-width); margin: 0 auto;
  padding: calc(var(--nav-height) + var(--space-xl)) var(--space-lg) var(--space-2xl);
  min-height: 100vh;
  contain: layout style; position: relative;
}
/* ov-fullwidth：取消 transform 动画与 will-change，
   否则 #page-container 会成为 position:fixed 后代（阅读器底栏/译·记按钮等）的包含块，
   导致这些元素锚定到文档底部而非视口 */
#page-container.ov-fullwidth { max-width: none; contain: unset; animation: none; will-change: auto; }

/* ===== 5. Buttons ===== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-sm);
  padding: 8px 18px; border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--bg-secondary); color: var(--text-primary);
  font-size: 0.85rem; font-weight: 500; cursor: pointer;
  transition: all var(--transition-fast); white-space: nowrap; user-select: none;
  letter-spacing: -0.01em; position: relative; overflow: hidden;
}
.btn:hover { background: var(--bg-hover); border-color: var(--border-hover); }
.btn:active { background: var(--bg-active); transition-duration: 50ms; }
.btn:disabled { opacity: 0.36; cursor: not-allowed; }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.btn-primary { background: var(--accent); color: var(--text-inverse); border-color: transparent; box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 1px 2px rgba(0,0,0,0.15); }
.btn-primary:hover { background: var(--accent-hover); border-color: transparent; }
.btn-primary:active { background: var(--accent-active); }
.btn-success { background: var(--success); color: white; border-color: transparent; box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 1px 2px rgba(0,0,0,0.15); }
.btn-success:hover { background: color-mix(in srgb, var(--success) 88%, #000); border-color: transparent; }
.btn-danger { background: var(--danger); color: white; border-color: transparent; box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 1px 2px rgba(0,0,0,0.15); }
.btn-danger:hover { background: color-mix(in srgb, var(--danger) 88%, #000); border-color: transparent; }
.btn-ghost { background: transparent; border: 1px solid var(--border); color: var(--text-secondary); }
.btn-ghost:hover { background: var(--bg-hover); color: var(--text-primary); }
.btn-sm { padding: 6px 12px; font-size: 0.8rem; border-radius: var(--radius-md); }
.btn-xs { padding: 2px 8px; font-size: 0.75rem; opacity: 0.7; }
.btn-xs:hover { opacity: 1; }
.btn svg { width: 18px; height: 18px; flex-shrink: 0; }

/* NOTE: the former .btn-icon-* data-URI rules were removed — no module ever
   used those classes, and their hardcoded light-grey stroke (#9ca3af) was
   invisible against the light theme's white buttons. Inline SVG icons from
   js/core/icons.js are the single icon path now. */

.back-btn, .mod-back-btn {
  width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer;
  transition: all var(--transition-fast); flex-shrink: 0;
}
.back-btn:hover, .mod-back-btn:hover { background: var(--bg-hover); color: var(--text-primary); border-color: var(--border-hover); }
.back-btn:active, .mod-back-btn:active { background: var(--bg-active); }
.mod-back-btn svg { width: 18px; height: 18px; }

/* ===== 5a. Focus-visible (keyboard a11y) ===== */
.subject-card:focus-visible, .mod-card:focus-visible, .bk-card:focus-visible, .ch-card:focus-visible,
.ch-file-node:focus-visible, .ch-folder-header:focus-visible, .item-card:focus-visible, .filter-chip:focus-visible,
.wrong-tab:focus-visible, .wrong-filter-btn:focus-visible, .wrong-group-btn:focus-visible, .wrong-item:focus-visible,
.list-btn:focus-visible, .list-item:focus-visible, .list-group__header:focus-visible,
.mn-card:focus-visible, .mn-note-card:focus-visible, .mn-tab:focus-visible, .mn-nav-btn:focus-visible, .mn-act:focus-visible,
.mn-filter-chip:focus-visible,
.shortcut-item:focus-visible,
.quiz-scope-item:focus-visible, .quiz-scope-chapter-item:focus-visible,
.modal-close:focus-visible, .settings-close:focus-visible,
.back-btn:focus-visible, .mod-back-btn:focus-visible, .fc-first-btn:focus-visible, .fc-list-btn:focus-visible,
.wi-action-btn:focus-visible, .list-item__act:focus-visible, .ov-action-btn:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
/* Rounded focus ring for card-like surfaces */
.subject-card:focus-visible, .mod-card:focus-visible, .bk-card:focus-visible, .ch-card:focus-visible,
.item-card:focus-visible, .mn-card:focus-visible, .mn-note-card:focus-visible,
.wrong-item:focus-visible, .list-item:focus-visible { border-radius: var(--radius-lg); }

/* ===== 6. Overlay / Modal / Toast ===== */
.overlay {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 18vh; background: rgba(0,0,0,0.45);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  animation: overlayIn 0.15s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
[data-theme="dark"] .overlay { background: rgba(0,0,0,0.6); }
.overlay.hidden { display: none; }
@keyframes overlayIn { from { opacity: 0; } to { opacity: 1; } }
body.modal-open { overflow: hidden; }

.modal-dialog, .settings-dialog {
  width: 90%; max-width: 620px;
  background: var(--surface-strong); border-radius: var(--radius-2xl);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-xl);
  overflow: hidden; animation: slideIn 0.15s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.modal-dialog { max-height: 85vh; display: flex; flex-direction: column; }
@keyframes slideIn { from { opacity: 0; transform: translateY(4px) scale(0.99); } to { opacity: 1; transform: translateY(0) scale(1); } }

.filter-chip { padding: 5px 14px; border: 1px solid var(--border); border-radius: var(--radius-full); background: transparent; color: var(--text-secondary); font-size: 0.78rem; font-weight: 500; cursor: pointer; transition: all var(--transition-fast); }
.filter-chip:hover { background: var(--bg-hover); color: var(--text-primary); border-color: var(--border-hover); }
.filter-chip.active { background: var(--rd-blue-strong, var(--accent)); color: var(--text-inverse); border-color: transparent; box-shadow: inset 0 1px 0 rgba(255,255,255,0.1); }

.search-highlight { background: color-mix(in srgb, var(--warning) 30%, transparent); color: var(--text-primary); padding: 1px 3px; border-radius: 3px; font-weight: 600; }

.modal-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-lg) var(--space-xl); border-bottom: 1px solid var(--border); background: transparent; }
.modal-header h3 { font-size: 1rem; font-weight: 600; color: var(--text-primary); letter-spacing: -0.02em; }
.modal-close { width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; border: none; background: var(--bg-tertiary); font-size: 1.1rem; color: var(--text-tertiary); cursor: pointer; border-radius: var(--radius-md); transition: all var(--transition-fast); }
.modal-close:hover { background: var(--bg-active); color: var(--text-primary); }
.modal-body { padding: var(--space-xl); overflow-y: auto; }

#toast-container { position: fixed; bottom: var(--space-xl); right: var(--space-xl); z-index: 300; display: flex; flex-direction: column; gap: var(--space-sm); }
.toast { padding: 11px 18px; background: var(--surface-strong); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); font-size: 0.85rem; font-weight: 500; color: var(--text-primary); animation: toastIn 0.15s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; display: flex; align-items: center; gap: var(--space-sm); letter-spacing: -0.01em; }
.toast.success { border-left: 3px solid var(--success); }
.toast.error { border-left: 3px solid var(--danger); }
.toast.warning { border-left: 3px solid var(--warning); }
.toast.info { border-left: 3px solid var(--accent); }
@keyframes toastIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes toastOut { from { opacity: 1; } to { opacity: 0; transform: translateY(6px); } }
.toast.toast-exit { animation: toastOut 0.15s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards; }

/* Settings dialog */
.settings-dialog { max-width: 420px; }
.settings-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-lg) var(--space-xl); border-bottom: 1px solid var(--border); }
.settings-header h3 { font-size: 1rem; font-weight: 600; color: var(--text-primary); }
.settings-close { width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; border: none; background: var(--bg-tertiary); color: var(--text-tertiary); cursor: pointer; border-radius: var(--radius-md); transition: all var(--transition-fast); }
.settings-close:hover { background: var(--bg-active); color: var(--text-primary); }
.settings-body { padding: var(--space-xl); }
.settings-desc { font-size: 0.85rem; color: var(--text-secondary); margin-bottom: var(--space-md); }
.settings-label { display: block; font-size: 0.85rem; font-weight: 600; color: var(--text-primary); margin-bottom: 8px; }
.settings-hint { font-size: 0.78rem; color: var(--text-tertiary); margin-top: var(--space-sm); }
.settings-actions { display: flex; gap: var(--space-sm); margin-top: var(--space-lg); padding-top: var(--space-md); border-top: 1px solid var(--border); }
.settings-result { margin-top: var(--space-md); padding: var(--space-sm) var(--space-md); border-radius: var(--radius-md); font-size: 0.82rem; }
.settings-result.success { background: var(--success-light); color: var(--success); }
.settings-result.error { background: var(--danger-light); color: var(--danger); }
.settings-result.hidden { display: none; }

/* ===== 7. Image viewer ===== */
.image-viewer-overlay { position: fixed; inset: 0; z-index: 500; background: rgba(0,0,0,0.88); display: flex; align-items: center; justify-content: center; animation: overlayIn 0.12s ease; cursor: zoom-out; padding: var(--space-xl); }
.image-viewer-overlay img { max-width: 95%; max-height: 90vh; border-radius: var(--radius-md); box-shadow: 0 0 60px rgba(0,0,0,0.5); object-fit: contain; animation: imageZoomIn 0.15s cubic-bezier(0.25, 0.46, 0.45, 0.94); }
@keyframes imageZoomIn { from { transform: scale(0.96); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* ===== 8. Ripple ===== */
.ripple-container, .ripple-host { position: relative; overflow: hidden; }
.ripple { position: absolute; border-radius: 50%; background: rgba(0,0,0,0.04); transform: scale(0); animation: rippleExpand 0.3s ease-out forwards; pointer-events: none; }
[data-theme="dark"] .ripple { background: rgba(255,255,255,0.05); }
@keyframes rippleExpand { to { transform: scale(4); opacity: 0; } }

/* ===== 9. Skeleton ===== */
.skeleton { background: linear-gradient(90deg, var(--bg-tertiary) 25%, color-mix(in srgb, var(--bg-tertiary) 60%, var(--bg-hover)) 50%, var(--bg-tertiary) 75%); background-size: 400% 100%; animation: skeletonPulse 1s ease-in-out infinite; border-radius: var(--radius-sm); }
@keyframes skeletonPulse { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }
.skeleton-card { padding: var(--space-2xl) var(--space-xl); min-height: 200px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-md); border-radius: var(--radius-xl); background: var(--bg-secondary); border: 1px solid var(--border); }
.skeleton-icon { width: 64px; height: 64px; border-radius: var(--radius-xl); }
.skeleton-title { width: 80px; height: 24px; }
.skeleton-text { width: 120px; height: 14px; }
.skeleton-chapter { flex-direction: row; justify-content: space-between; align-items: center; min-height: auto; padding: var(--space-md) var(--space-lg); gap: var(--space-sm); }
.skeleton-flashcard { width: 100%; max-width: 840px; min-height: 260px; align-items: flex-start; padding: var(--space-2xl); border-radius: var(--radius-2xl); gap: var(--space-lg); }
.skeleton-circle-lg { width: 72px; height: 72px; border-radius: var(--radius-2xl); margin: 0 auto var(--space-md); }
.skeleton-text-md { width: 60px; height: 20px; border-radius: var(--radius-md); margin: 0 auto var(--space-sm); }
.skeleton-text-sm { width: 120px; height: 14px; border-radius: var(--radius-full); margin: 0 auto; }
.skeleton-subject-card { pointer-events: none; background: var(--bg-secondary) !important; border: 1px solid var(--border) !important; }

/* ===== 10. Forms ===== */
.form-group { margin-bottom: var(--space-md); }
.form-group label { display: block; font-size: 0.85rem; font-weight: 600; color: var(--text-primary); margin-bottom: 8px; letter-spacing: 0.01em; }
.form-group input, .form-group textarea, .form-group select { width: 100%; padding: 10px 14px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--bg-primary); color: var(--text-primary); font-size: 0.9rem; font-family: inherit; transition: border-color var(--transition-fast), box-shadow var(--transition-fast); }
.form-group input:focus, .form-group textarea:focus, .form-group select:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }
.form-group input::placeholder, .form-group textarea::placeholder { color: var(--text-tertiary); opacity: 0.8; }
.form-group textarea { min-height: 100px; resize: vertical; line-height: 1.6; }
.form-actions { display: flex; gap: var(--space-sm); justify-content: flex-end; margin-top: var(--space-lg); padding-top: var(--space-md); border-top: 1px solid var(--border-light); }

.textarea-toolbar { display: flex; gap: 6px; margin-bottom: 6px; padding: 6px 8px; background: var(--bg-tertiary); border-radius: var(--radius-md); border: 1px solid var(--border); }

/* generic inputs */
input[type="text"], input[type="number"], input[type="email"], input[type="password"], textarea, select {
  border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-secondary); color: var(--text-primary); font-family: inherit; transition: border-color var(--transition-fast); }
input:focus, textarea:focus, select:focus { border-color: var(--accent); outline: none; box-shadow: var(--focus-ring); }

/* ===== 11. Empty State ===== */
.empty-state { text-align: center; padding: var(--space-3xl) var(--space-lg); color: var(--text-tertiary); }
.empty-icon-wrap { width: 120px; height: 100px; margin: 0 auto var(--space-xl); animation: emptyFloat 2.5s ease-in-out infinite; opacity: 0.8; }
.empty-icon-wrap svg { width: 100%; height: 100%; }
@keyframes emptyFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
.empty-state .empty-icon { font-size: 4rem; margin-bottom: var(--space-lg); animation: emptyBounce 2s ease-in-out infinite; display: inline-block; }
@keyframes emptyBounce { 0%, 100% { transform: translateY(0) scale(1); } 50% { transform: translateY(-4px) scale(1.02); } }
.empty-state h3 { font-size: 1.15rem; font-weight: 700; color: var(--text-secondary); margin-bottom: var(--space-xs); }
.empty-state p { font-size: 0.92rem; line-height: 1.6; opacity: 0.8; }

/* ===== 12. Page Header ===== */
.page-header { margin-bottom: var(--space-xl); }
.page-header h1 { font-size: 1.6rem; font-weight: 700; margin-bottom: var(--space-xs); letter-spacing: -0.02em; display: flex; align-items: center; gap: var(--space-sm); }
.header-icon { width: 26px; height: 26px; flex-shrink: 0; }
.page-header p { color: var(--text-secondary); font-size: 0.95rem; }
.page-title-row { display: flex; align-items: center; gap: var(--space-md); margin-bottom: var(--space-lg); }

/* ===== 23. Global Table ===== */
table { width: 100%; border-collapse: collapse; margin: var(--space-sm) 0 var(--space-md); }
th, td { border: 1px solid var(--border); padding: 8px 12px; text-align: left; font-size: 0.88rem; }
th { background: var(--bg-tertiary); font-weight: 600; }
tr:nth-child(even) { background: var(--bg-tertiary); }
code { background: var(--bg-tertiary); padding: 2px 6px; border-radius: 4px; font-size: 0.85em; }
pre { background: var(--code-bg); color: var(--code-text); padding: var(--space-md); border-radius: var(--radius-md); border: 1px solid var(--border); overflow-x: auto; margin-bottom: var(--space-md); }

/* ===== 24. KaTeX ===== */
.katex-display { margin: var(--space-sm) 0; overflow-x: auto; }

/* ===== 24a. Perf: skip layout/paint of offscreen items on long lists ===== */
.wrong-item, .list-item, .rv-item, .mn-card {
  content-visibility: auto;
  contain-intrinsic-size: auto 96px;
}

/* ===== 25. Animations ===== */
@keyframes fadeIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
@keyframes skeletonShimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

/* ===== 29. Reduced Motion / Print ===== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
  html { scroll-behavior: auto; }
  /* 折叠区靠 max-height 过渡做展开动画；减动效时必须解除高度限制，
     否则过渡被压成 0.01ms 后内容会被永久裁掉。 */
  .ov-group-children,
  .retree-docs,
  .retree-groups,
  .ch-folder-children { transition: none !important; max-height: none !important; }
  #nprogress { transition: none !important; }
}
@media print {
  .subject-card, .chapter-card, .bk-card, .module-card, .review-card, .modal-dialog, .settings-dialog, .toast, .sidebar, .toolbar, .editor-wrapper, .preview-area, pre, table, .hero-stats, .home-shortcuts, .btn, .nav-btn, .back-btn, .shortcut-item, .hero-badge, .filter-chip, .badge, .progress-bar, input[type="text"], input[type="number"], input[type="email"], input[type="password"], textarea, select, code { background: white !important; backdrop-filter: none !important; -webkit-backdrop-filter: none !important; border: 1px solid #ccc !important; box-shadow: none !important; }
  body::before { display: none !important; }
  .ovc-chapter-wrap { page-break-before: always; }
  .ovc-chapter-wrap:first-child { page-break-before: auto; }
  .ovc-chapter-title { margin-top: 0; padding-top: 20px; }
  .ovc-chapter-wrap:first-child > .ovc-chapter-title { padding-top: 0; }
}

/* Math Notes (.mn-*) styles moved to css/pages/math-notes.css */

/* ===== Utility Classes ===== */
/* NOTE: canonical .btn-sm / .btn-ghost / .btn-primary live in section 5 (Buttons) and use
   design tokens (var(--accent)). Linear 风格下 primary hover 不做位移，仅提亮背景。 */

/* ===== 网站设置：比例缩放 / 壁纸入口 ===== */
#modal-overlay:has(.site-settings) { align-items: center; padding: 16px; }
#modal-overlay .site-settings {
  width: 480px;
  display: flex;
  flex-direction: column;
}
/* CSS zoom 会缩放 vh 长度；弹窗按实际可用高度限制，关闭按钮始终可达。
   同样约束设置内打开的壁纸编辑器，不让它在高比例/手机上超出视口。 */
html[data-site-scale] #modal-overlay .settings-dialog {
  max-width: calc(100% - 16px);
  max-height: calc(100dvh / var(--site-zoom, 1) - 32px);
}
#modal-overlay.wp-previewing { padding: 16px; }
.site-settings .settings-header { flex-shrink: 0; gap: 12px; }
#modal-overlay .site-settings-body {
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 24px;
}
.site-settings-section + .site-settings-section { border-top: 1px solid var(--border); padding-top: 20px; }
.site-settings-section h4 { font-size: .9rem; color: var(--text-primary); margin-bottom: 8px; }
.site-settings-hint { color: var(--text-secondary); font-size: .8rem; line-height: 1.7; margin-bottom: 14px; }
.site-scale-controls { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.site-scale-controls [data-site-scale="in"], .site-scale-controls [data-site-scale="out"] { padding: 8px 10px; }
#site-scale-value { min-width: 62px; text-align: center; font-weight: 650; font-variant-numeric: tabular-nums; }
.site-scale-label { display: block; font-size: .76rem; color: var(--text-secondary); margin-bottom: 6px; }
#site-scale-range { display: block; width: 100%; min-width: 0; height: 28px; accent-color: var(--accent); }
.site-scale-presets { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.site-scale-presets [aria-pressed="true"] { color: var(--nav-active-ink, var(--accent)); border-color: var(--accent); background: var(--accent-light); }
.site-settings button:focus-visible, #site-scale-range:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* 缩放是屏幕偏好，不改变纸张打印比例。 */
@media print { html { zoom: 1 !important; } }
/* ==== pages/home.css ==== */
/* ============================================
   Home page (.home-*, .subject-card*, .hero-*)
   Extracted from main.css. Load order matters (see index.html).
   v6.0 Linear 暗调科技风
   ============================================ */

/* ===== 13. Home Page ===== */
.home-page { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: calc(100vh - var(--nav-height) - var(--space-2xl) * 2); text-align: center; position: relative; overflow: hidden; padding: var(--space-xl) var(--space-lg); }
.home-hero { position: relative; z-index: 2; margin-bottom: var(--space-3xl); }
.hero-badge { display: inline-flex; align-items: center; gap: var(--space-sm); padding: 5px 14px; background: var(--accent-light); border: 1px solid var(--accent-subtle); border-radius: var(--radius-full); font-size: 0.78rem; font-weight: 500; color: var(--accent); margin-bottom: var(--space-xl); animation: fadeIn 0.3s cubic-bezier(0.25,0.46,0.45,0.94) both; }
.hero-badge svg { width: 14px; height: 14px; color: var(--warning); }
.hero-title { font-size: clamp(2.4rem, 6vw, 3.8rem); font-weight: 700; line-height: 1.08; letter-spacing: -0.04em; margin-bottom: var(--space-md); animation: fadeIn 0.35s cubic-bezier(0.25,0.46,0.45,0.94) 0.04s both; }
.title-text { color: var(--text-primary); display: inline; }
.title-highlight { display: inline; background: linear-gradient(120deg, var(--accent) 0%, #8b93e8 60%, #b3b9f0 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
.hero-subtitle { font-size: clamp(1rem, 2vw, 1.2rem); color: var(--text-secondary); margin-bottom: var(--space-2xl); font-weight: 400; animation: fadeIn 0.35s cubic-bezier(0.25,0.46,0.45,0.94) 0.08s both; }
.hero-stats { display: flex; align-items: center; justify-content: center; gap: var(--space-xl); padding: var(--space-lg) var(--space-2xl); background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-2xl); box-shadow: var(--shadow-sm); animation: fadeIn 0.35s cubic-bezier(0.25,0.46,0.45,0.94) 0.12s both; }
.stat-item { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 70px; }
.stat-number { font-size: 1.8rem; font-weight: 700; color: var(--accent); line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.stat-label { font-size: 0.78rem; color: var(--text-tertiary); font-weight: 500; text-transform: uppercase; letter-spacing: 0.5px; }
.stat-divider { width: 1px; height: 36px; background: var(--border); }
.home-cards-section { position: relative; z-index: 2; width: 100%; max-width: 720px; animation: fadeIn 0.35s cubic-bezier(0.25,0.46,0.45,0.94) 0.16s both; }
.section-label { display: flex; align-items: center; justify-content: center; gap: var(--space-md); margin-bottom: var(--space-xl); }
.label-line { height: 1px; width: 60px; background: linear-gradient(90deg, transparent, var(--border-hover), transparent); }
.label-text { font-size: 0.88rem; font-weight: 600; color: var(--text-tertiary); text-transform: uppercase; letter-spacing: 2px; }
.subject-card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-lg); }
.subject-card { position: relative; border-radius: var(--radius-2xl); overflow: hidden; cursor: pointer; transition: all var(--transition-normal); contain: layout style; background: var(--bg-secondary); border: 1px solid var(--border); box-shadow: var(--shadow-card); }
.subject-card::before { display: none; }
.subject-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-card-hover); border-color: color-mix(in srgb, var(--card-color) 35%, var(--border)); }
.subject-card:active { transform: translateY(-1px); transition-duration: 50ms; }
.card-chem { --card-color: #d97706; --card-light: rgba(217,119,6,0.1); --card-glow: rgba(217,119,6,0.18); }
.card-bio { --card-color: #16a34a; --card-light: rgba(22,163,74,0.1); --card-glow: rgba(22,163,74,0.18); }
.card-eng { --card-color: #2563eb; --card-light: rgba(37,99,235,0.1); --card-glow: rgba(37,99,235,0.18); }
.card-chn { --card-color: #8b5cf6; --card-light: rgba(139,92,246,0.1); --card-glow: rgba(139,92,246,0.18); }
.card-math { --card-color: #2563eb; --card-light: rgba(37,99,235,0.1); --card-glow: rgba(37,99,235,0.18); }
.card-phy { --card-color: #0891b2; --card-light: rgba(8,145,178,0.1); --card-glow: rgba(8,145,178,0.18); }
[data-theme="dark"] .card-chem { --card-color: #e8963a; }
[data-theme="dark"] .card-bio { --card-color: #3fbf6f; }
[data-theme="dark"] .card-eng { --card-color: #5b8def; }
[data-theme="dark"] .card-chn { --card-color: #a78bfa; }
[data-theme="dark"] .card-math { --card-color: #5b8def; }
[data-theme="dark"] .card-phy { --card-color: #38bdd8; }
.card-glow { display: none; }
.card-content { position: relative; z-index: 1; padding: var(--space-2xl) var(--space-xl); display: flex; flex-direction: column; align-items: center; gap: var(--space-md); min-height: 220px; }
.card-icon-wrapper { width: 68px; height: 68px; border-radius: var(--radius-xl); display: flex; align-items: center; justify-content: center; transition: all var(--transition-normal); border: 1px solid color-mix(in srgb, var(--card-color) 22%, transparent); background: color-mix(in srgb, var(--card-color) 10%, var(--bg-tertiary)); }
.card-icon-wrapper svg { width: 44px; height: 44px; }
.card-icon-text { font-size: 2rem; font-weight: 800; font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; line-height: 1; }
.chem-icon .card-icon-text, .bio-icon .card-icon-text, .eng-icon .card-icon-text,
.chn-icon .card-icon-text, .math-icon .card-icon-text, .phy-icon .card-icon-text { color: var(--card-color); }
.subject-card:hover .card-icon-wrapper { border-color: color-mix(in srgb, var(--card-color) 40%, transparent); background: color-mix(in srgb, var(--card-color) 16%, var(--bg-tertiary)); box-shadow: 0 0 20px var(--card-glow); }
.card-title { font-size: 1.5rem; font-weight: 700; color: var(--text-primary); margin: 0; transition: color var(--transition-base); letter-spacing: -0.02em; }
.subject-card:hover .card-title { color: var(--card-color); }
.card-desc { font-size: 0.9rem; color: var(--text-secondary); margin: 0; line-height: 1.5; }
.card-arrow { width: 34px; height: 34px; border-radius: var(--radius-md); background: var(--card-light); display: flex; align-items: center; justify-content: center; transition: all var(--transition-fast); margin-top: auto; opacity: 0.6; }
.card-arrow svg { width: 18px; height: 18px; color: var(--card-color); transition: transform var(--transition-normal); }
.subject-card:hover .card-arrow { opacity: 1; background: var(--card-color); }
.subject-card:hover .card-arrow svg { color: white; transform: translateX(3px); }
.card-particles { display: none; }
.home-shortcuts { position: relative; z-index: 2; display: flex; align-items: center; justify-content: center; gap: var(--space-md); margin-top: var(--space-2xl); padding: var(--space-lg) var(--space-xl); background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-2xl); max-width: 560px; width: 100%; animation: fadeIn 0.35s cubic-bezier(0.25,0.46,0.45,0.94) 0.2s both; box-shadow: var(--shadow-sm); }
.shortcut-item { display: flex; flex-direction: column; align-items: center; gap: var(--space-xs); padding: var(--space-md) var(--space-lg); border-radius: var(--radius-lg); cursor: pointer; transition: all var(--transition-base); flex: 1; max-width: 120px; }
.shortcut-item:hover { background: var(--bg-tertiary); transform: translateY(-2px); }
.shortcut-icon { width: 44px; height: 44px; border-radius: var(--radius-lg); display: flex; align-items: center; justify-content: center; transition: all var(--transition-base); border: 1px solid color-mix(in srgb, currentColor 22%, transparent); }
.shortcut-icon svg { width: 22px; height: 22px; }
.shortcut-item:hover .shortcut-icon { transform: scale(1.06); box-shadow: 0 0 14px color-mix(in srgb, currentColor 22%, transparent); }
.shortcut-item span { font-size: 0.78rem; font-weight: 500; color: var(--text-secondary); white-space: nowrap; }
.review-icon { background: color-mix(in srgb, #3b82f6 12%, var(--bg-tertiary)); color: #3b82f6; }
.quiz-icon { background: color-mix(in srgb, #f59e0b 12%, var(--bg-tertiary)); color: #f59e0b; }
.wrong-icon { background: color-mix(in srgb, #ef4444 12%, var(--bg-tertiary)); color: #ef4444; }
[data-theme="dark"] .review-icon { color: #6ca0f8; }
[data-theme="dark"] .quiz-icon { color: #f7b955; }
[data-theme="dark"] .wrong-icon { color: #f47069; }
/* ==== pages/modules.css ==== */
/* ============================================
   Subject modules page (.mod-*)
   Extracted from main.css. Load order matters (see index.html).
   v6.0 Linear 暗调科技风
   ============================================ */

/* ===== 14. Modules Page ===== */
.modules-page { position: relative; min-height: calc(100vh - var(--nav-height) - var(--space-2xl)); }
.modules-bg-dots { position: absolute; inset: 0; background-image: radial-gradient(circle, color-mix(in srgb, var(--text-tertiary) 14%, transparent) 1px, transparent 1px); background-size: 28px 28px; opacity: 0.3; pointer-events: none; }
.mod-header { display: flex; align-items: center; gap: var(--space-lg); margin-bottom: var(--space-xl); position: relative; z-index: 2; animation: fadeIn 0.2s cubic-bezier(0.25,0.46,0.45,0.94) both; }
.mod-title-block { display: flex; flex-direction: column; gap: var(--space-xs); }
.mod-subject-badge { display: inline-flex; align-items: center; gap: var(--space-sm); padding: var(--space-xs) var(--space-lg); background: var(--ml); border: 1px solid color-mix(in srgb, var(--mc) 25%, transparent); border-radius: var(--radius-full); width: fit-content; }
.mod-badge-icon { font-size: 1.2rem; line-height: 1; }
.mod-badge-text { font-size: 1.35rem; font-weight: 700; color: var(--mc, var(--text-primary)); letter-spacing: -0.02em; }
.mod-subtitle { font-size: 0.9rem; color: var(--text-tertiary); margin: 0; padding-left: var(--space-md); }
.mod-stats-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-md); margin-bottom: var(--space-2xl); position: relative; z-index: 2; animation: fadeIn 0.2s cubic-bezier(0.25,0.46,0.45,0.94) 0.03s both; }
.mod-stat { display: flex; align-items: center; gap: var(--space-md); padding: var(--space-lg) var(--space-xl); background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-xl); transition: all var(--transition-base); cursor: default; overflow: hidden; position: relative; }
.mod-stat::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px; background: var(--ms-color); opacity: 0.8; }
.mod-stat:hover { transform: translateY(-2px); box-shadow: 0 0 18px color-mix(in srgb, var(--ms-color) 10%, transparent); border-color: color-mix(in srgb, var(--ms-color) 30%, var(--border)); }
.mod-stat-icon { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; background: var(--ms-bg); border: 1px solid color-mix(in srgb, var(--ms-color) 20%, transparent); border-radius: var(--radius-lg); flex-shrink: 0; color: var(--ms-color); }
.mod-stat-icon svg { width: 22px; height: 22px; }
.mod-stat-body { display: flex; flex-direction: column; gap: 2px; }
.mod-stat-num { font-size: 1.65rem; font-weight: 700; color: var(--ms-color); line-height: 1.15; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.mod-stat-lbl { font-size: 0.75rem; color: var(--text-tertiary); font-weight: 500; letter-spacing: 0.3px; }
.mod-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-lg); position: relative; z-index: 2; animation: fadeIn 0.2s cubic-bezier(0.25,0.46,0.45,0.94) 0.06s both; }
.mod-card { position: relative; border-radius: var(--radius-xl); overflow: hidden; cursor: pointer; transition: all var(--transition-base); contain: layout style; animation: fadeIn 0.2s cubic-bezier(0.25,0.46,0.45,0.94) both; background: var(--bg-secondary); border: 1px solid var(--border); }
.mod-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-card-hover); border-color: color-mix(in srgb, var(--cci, var(--accent)) 30%, var(--border)); }
.mod-card:active { transform: translateY(-1px); }
.mod-card-inner { position: relative; z-index: 1; display: flex; align-items: center; gap: var(--space-lg); padding: var(--space-lg) var(--space-xl); min-height: 108px; }
.mod-card-icon-wrap { width: 50px; height: 50px; display: flex; align-items: center; justify-content: center; background: var(--ccb, rgba(59,130,246,0.08)); border: 1px solid color-mix(in srgb, var(--cci, #3b82f6) 20%, transparent); border-radius: var(--radius-lg); flex-shrink: 0; transition: all var(--transition-base); }
.mod-card-icon-wrap svg { width: 24px; height: 24px; stroke: var(--cci, #3b82f6); transition: all var(--transition-base); }
.mod-card:hover .mod-card-icon-wrap { border-color: color-mix(in srgb, var(--cci, #3b82f6) 40%, transparent); box-shadow: 0 0 16px color-mix(in srgb, var(--cci, #3b82f6) 15%, transparent); }
.mod-card-info { flex: 1; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.mod-card-info h3 { font-size: 1.1rem; font-weight: 600; color: var(--text-primary); margin: 0; transition: color var(--transition-base); letter-spacing: -0.01em; }
.mod-card:hover .mod-card-info h3 { color: var(--cci, var(--accent)); }
.mod-card-info p { font-size: 0.82rem; color: var(--text-tertiary); margin: 0; line-height: 1.4; }
.mod-card-arrow { width: 32px; height: 32px; border-radius: var(--radius-md); background: var(--bg-tertiary); display: flex; align-items: center; justify-content: center; flex-shrink: 0; transition: all var(--transition-base); opacity: 0.4; }
.mod-card-arrow svg { width: 16px; height: 16px; color: var(--cci, var(--accent)); transition: transform var(--transition-normal); }
.mod-card:hover .mod-card-arrow { opacity: 1; background: var(--cci, var(--accent)); }
.mod-card:hover .mod-card-arrow svg { color: white; transform: translateX(3px); }
.mod-secondary-tools { position: relative; z-index: 2; margin-top: var(--space-2xl); border-top: 1px solid var(--border); padding-top: var(--space-lg); }
.mod-secondary-tools summary { cursor: pointer; color: var(--text-secondary); font-size: .86rem; user-select: none; }
.mod-secondary-tools summary span { display: inline-flex; min-width: 20px; height: 20px; align-items: center; justify-content: center; margin-left: 4px; border-radius: 50%; background: var(--bg-tertiary); color: var(--text-tertiary); font-size: .72rem; }
.mod-secondary-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin-top: var(--space-md); }
.mod-secondary-item { display: grid; grid-template-columns: 28px minmax(0, 1fr) 18px; grid-template-rows: auto auto; align-items: center; column-gap: 8px; padding: 10px 12px; text-align: left; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; font: inherit; }
.mod-secondary-item:hover { border-color: var(--border-hover); color: var(--text-primary); }
.mod-secondary-item > span { grid-row: 1 / span 2; display: grid; place-items: center; color: var(--text-tertiary); }
.mod-secondary-item > span svg { width: 19px; height: 19px; }
.mod-secondary-item strong { min-width: 0; color: inherit; font-size: .82rem; font-weight: 600; }
.mod-secondary-item small { min-width: 0; overflow: hidden; color: var(--text-tertiary); font-size: .7rem; text-overflow: ellipsis; white-space: nowrap; }
.mod-secondary-item > svg { grid-column: 3; grid-row: 1 / span 2; width: 15px; height: 15px; color: var(--text-tertiary); }

@media (max-width: 640px) {
  .mod-header { align-items: flex-start; flex-wrap: wrap; gap: 12px; }
  .mod-title-block { min-width: 0; flex: 1 1 calc(100% - 56px); }
  .mod-grid { grid-template-columns: 1fr; }
  .mod-card-inner { padding: 16px; min-height: 96px; }
  .mod-secondary-list { grid-template-columns: 1fr; }
}
/* ==== pages/review.css ==== */
/* ============================================
   Review / Book-Chapter / Quiz (.bk-* .ch-* .fc-* .review-* .quiz-* .qz-*)
   Extracted from main.css. Load order matters (see index.html).
   ============================================ */

/* ===== 15. Book/Chapter Selection ===== */
.books-page, .ch-page, .fc-page { position: relative; min-height: calc(100vh - var(--nav-height) - var(--space-2xl)); }
.bk-header { display: flex; align-items: center; gap: var(--space-lg); margin-bottom: var(--space-xl); position: relative; z-index: 2; animation: fadeIn 0.3s ease both; }
.bk-title-block { flex: 1; display: flex; flex-direction: column; gap: var(--space-xs); }
.bk-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-lg); position: relative; z-index: 2; animation: fadeIn 0.25s ease 0.06s both; }
.bk-card { position: relative; border-radius: var(--radius-2xl); overflow: hidden; cursor: pointer; transition: all var(--transition-base); contain: layout style; animation: fadeIn 0.2s ease both; background: var(--bg-secondary); }
.bk-card::before { content: ''; position: absolute; inset: 0; border-radius: inherit; border: 1px solid var(--border); pointer-events: none; z-index: 3; transition: border-color 0.22s ease; }
.bk-card-glow { position: absolute; top: 50%; left: 50%; width: 140%; height: 140%; transform: translate(-50%,-50%) scale(0.8); background: radial-gradient(circle, var(--bki-glow, rgba(0,0,0,0.08)) 0%, transparent 60%); opacity: 0; transition: all 0.15s ease; pointer-events: none; z-index: 0; }
.bk-card:hover .bk-card-glow { opacity: 1; transform: translate(-50%,-50%) scale(1.15); }
.bk-card-inner { position: relative; z-index: 1; display: flex; align-items: center; gap: var(--space-lg); padding: var(--space-xl); min-height: 100px; background: var(--bg-secondary); }
.bk-icon-wrap { width: 52px; height: 52px; display: flex; align-items: center; justify-content: center; background: var(--bki-bg, rgba(59,130,246,0.08)); border-radius: var(--radius-lg); flex-shrink: 0; transition: all var(--transition-base); border: 1px solid color-mix(in srgb, var(--bki-color, #3b82f6) 15%, transparent); }
.bk-icon-wrap svg { width: 24px; height: 24px; stroke: var(--bki-color, #3b82f6); }
.bk-card:hover .bk-icon-wrap { background: color-mix(in srgb, var(--bki-color, #3b82f6) 12%, transparent); border-color: color-mix(in srgb, var(--bki-color, #3b82f6) 35%, transparent); box-shadow: 0 0 16px var(--bki-glow, rgba(59,130,246,0.15)); }
.bk-info { flex: 1; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.bk-info h3 { font-size: 1.05rem; font-weight: 700; color: var(--text-primary); margin: 0; transition: color 0.18s; }
.bk-card:hover .bk-info h3 { color: var(--bki-color, var(--accent)); }
.bk-info p { font-size: 0.82rem; color: var(--text-tertiary); margin: 0; line-height: 1.35; }
.bk-progress { height: 4px; background: var(--bg-active); border-radius: var(--radius-full); overflow: hidden; margin-top: 4px; width: 100%; }
.bk-progress-bar { height: 100%; border-radius: var(--radius-full); transition: width 0.35s cubic-bezier(0.4,0,0.2,1); }
.bk-arrow { width: 34px; height: 34px; border-radius: var(--radius-full); background: var(--bki-bg, rgba(59,130,246,0.06)); display: flex; align-items: center; justify-content: center; flex-shrink: 0; transition: all 0.12s ease; opacity: 0.45; }
.bk-arrow svg { width: 16px; height: 16px; color: var(--bki-color, var(--accent)); transition: transform 0.35s; }
.bk-card:hover .bk-arrow { opacity: 1; background: var(--bki-color, var(--accent)); box-shadow: 0 4px 14px var(--bki-glow, rgba(59,130,246,0.2)); }
.bk-card:hover .bk-arrow svg { color: white; transform: translateX(3px); }
.bk-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-card-hover); }
.bk-card:hover::before { border-color: color-mix(in srgb, var(--bki-color, var(--accent)) 35%, var(--border)); }
.bk-card:active { transform: translateY(-1px); }
.bk-skeleton { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-sm); pointer-events: none; }
.bk-skeleton .skeleton-circle-lg { width: 48px; height: 48px; margin-bottom: var(--space-xs); }
.bk-skeleton .skeleton-text-md { width: 80px; height: 16px; }
.bk-skeleton .skeleton-text-sm { width: 60px; height: 12px; }
.ch-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-lg); position: relative; z-index: 2; animation: fadeIn 0.25s ease 0.06s both; }
.ch-card { position: relative; border-radius: var(--radius-2xl); overflow: hidden; cursor: pointer; transition: all var(--transition-base); contain: layout style; animation: fadeIn 0.2s ease both; }
.ch-card::before { content: ''; position: absolute; inset: 0; border-radius: inherit; border: 1px solid var(--border); pointer-events: none; z-index: 3; transition: border-color 0.22s ease; }
.ch-card-glow { position: absolute; top: 50%; left: 50%; width: 140%; height: 140%; transform: translate(-50%,-50%) scale(0.8); background: radial-gradient(circle, rgba(99,102,241,0.05) 0%, transparent 60%); opacity: 0; transition: all 0.15s ease; pointer-events: none; z-index: 0; }
.ch-card:hover .ch-card-glow { opacity: 1; transform: translate(-50%,-50%) scale(1.15); }
.ch-card-inner { position: relative; z-index: 1; display: flex; flex-direction: column; gap: var(--space-sm); padding: var(--space-xl); min-height: 110px; background: var(--bg-secondary); }
.ch-top-row { display: flex; align-items: center; gap: var(--space-md); }
.ch-num { font-size: 1.35rem; font-weight: 800; color: var(--cn-color, #3b82f6); line-height: 1; flex-shrink: 0; opacity: 0.7; transition: opacity 0.3s; }
.ch-card:hover .ch-num { opacity: 1; }
.ch-name { font-size: 1rem; font-weight: 700; color: var(--text-primary); margin: 0; transition: color 0.18s; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ch-card:hover .ch-name { color: var(--ch-color, var(--accent)); }
.ch-arrow { width: 18px; height: 18px; flex-shrink: 0; transition: transform 0.2s ease; }
.ch-card:hover .ch-arrow { transform: translateX(3px); }
.ch-meta-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-md); }
.ch-count { font-size: 0.82rem; color: var(--text-tertiary); }
.ch-pct { font-size: 0.78rem; font-weight: 600; }
.ch-card-download-btn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: var(--radius-full); border: none; background: var(--bg-tertiary); color: var(--text-tertiary); cursor: pointer; transition: all 0.12s ease; padding: 0; flex-shrink: 0; }
.ch-card-download-btn:hover { background: #0ea5e9; color: #fff; transform: scale(1.1); box-shadow: 0 2px 8px rgba(14,165,233,0.3); }
.ch-download-btn { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: var(--radius-full); border: none; background: transparent; color: var(--text-tertiary); cursor: pointer; transition: all 0.12s ease; padding: 0; flex-shrink: 0; }
.ch-download-btn:hover { background: rgba(14,165,233,0.15); color: #0ea5e9; }
.ch-progress { height: 5px; background: var(--bg-active); border-radius: var(--radius-full); overflow: hidden; margin-top: var(--space-xs); }
.ch-progress-bar { height: 100%; border-radius: var(--radius-full); transition: width 0.35s cubic-bezier(0.4,0,0.2,1); }
.ch-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-card-hover); }
.ch-card:hover::before { border-color: color-mix(in srgb, var(--ch-color, var(--accent)) 35%, var(--border)); }
.ch-card:active { transform: translateY(-1px); }
.ch-skeleton { display: flex; flex-direction: column; gap: var(--space-sm); pointer-events: none; }
.ch-skeleton .skeleton-text-md { width: 60%; height: 16px; }
.ch-skeleton .skeleton-text-sm { width: 40%; height: 12px; }
.ch-skeleton .skeleton-bar { width: 100%; height: 5px; border-radius: var(--radius-full); }
.ch-tree { display: flex; flex-direction: column; gap: var(--space-sm); position: relative; z-index: 2; animation: fadeIn 0.25s ease 0.06s both; }
.ch-tree-node { position: relative; border-radius: var(--radius-xl); overflow: hidden; transition: all 0.18s ease; contain: layout style; }
.ch-folder-node { background: var(--bg-secondary); border: 1px solid var(--border); cursor: pointer; }
.ch-folder-header { display: flex; align-items: center; gap: var(--space-md); padding: var(--space-lg) var(--space-xl); transition: all 0.18s ease; }
.ch-folder-node:hover .ch-folder-header { background: color-mix(in srgb, var(--ch-color, #6366f1) 5%, transparent); }
.ch-folder-icon { width: 24px; height: 24px; flex-shrink: 0; transition: transform 0.18s ease; }
.ch-folder-name { font-size: 1rem; font-weight: 700; color: var(--text-primary); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ch-folder-count { font-size: 0.82rem; color: var(--text-tertiary); flex-shrink: 0; }
.ch-folder-arrow { width: 18px; height: 18px; flex-shrink: 0; transition: transform 0.2s ease; }
.ch-folder-children { display: flex; flex-direction: column; gap: var(--space-xs); padding-left: var(--tree-indent, 24px); border-left: 2px solid color-mix(in srgb, var(--ch-color, #6366f1) 20%, transparent); margin-left: calc(var(--space-lg) + 12px); transition: all 0.2s cubic-bezier(0.4,0,0.2,1); overflow: hidden; }
.ch-folder-children.collapsed { max-height: 0 !important; opacity: 0; margin-top: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0; }
.ch-file-node { background: var(--bg-secondary); border: 1px solid transparent; cursor: pointer; margin: 2px 0; transition: all 0.15s ease; }
.ch-file-node:hover { border-color: color-mix(in srgb, var(--ch-color, #3b82f6) 30%, transparent); background: color-mix(in srgb, var(--ch-color, #3b82f6) 4%, var(--bg-secondary)); transform: translateX(4px); }
.ch-file-inner { display: flex; align-items: center; gap: var(--space-md); padding: var(--space-md) var(--space-xl); }
.ch-file-bullet { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; box-shadow: 0 0 8px currentColor; }
.ch-file-name { font-size: 0.95rem; font-weight: 600; color: var(--text-primary); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; transition: color 0.15s ease; }
.ch-file-node:hover .ch-file-name { color: var(--ch-color, #3b82f6); }
.ch-file-meta { display: flex; align-items: center; gap: var(--space-md); flex-shrink: 0; font-size: 0.78rem; }
.ch-file-meta .ch-count { color: var(--text-tertiary); }
.ch-file-meta .ch-pct { font-weight: 600; }
.ch-file-node .ch-progress { height: 3px; margin: 0; background: var(--bg-active); }
.item-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; padding: 16px 20px; }
.item-card { position: relative; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-xl); overflow: hidden; cursor: pointer; transition: transform var(--transition-base), box-shadow var(--transition-base), border-color var(--transition-base); isolation: isolate; }
.item-card::before { content: ''; position: absolute; inset: 0; background: radial-gradient(circle at top right, color-mix(in srgb, var(--ic-color, #3b82f6) 10%, transparent), transparent 60%); opacity: 0; transition: opacity var(--transition-normal); pointer-events: none; z-index: 0; }
.item-card::after { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: var(--ic-color, #3b82f6); opacity: 0.75; z-index: 2; }
.item-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-card-hover); border-color: color-mix(in srgb, var(--ic-color, #3b82f6) 35%, var(--border)); }
.item-card:hover::before { opacity: 1; }
.item-card:active { transform: translateY(-1px); transition-duration: 0.08s; }
.item-card__inner { display: flex; align-items: stretch; min-height: 88px; position: relative; z-index: 1; }
.item-card__accent { width: 0; flex-shrink: 0; background: var(--ic-color, #3b82f6); border-radius: 0; }
.item-card__body { flex: 1; min-width: 0; padding: 16px 18px 14px; display: flex; flex-direction: column; justify-content: center; gap: 6px; }
.item-card__title { font-size: 0.98rem; font-weight: 600; color: var(--text-primary); line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; transition: color 0.2s; letter-spacing: -0.01em; }
.item-card:hover .item-card__title { color: var(--ic-color, var(--accent)); }
.item-card__meta { font-size: 0.78rem; color: var(--text-tertiary); line-height: 1.3; display: flex; align-items: center; gap: 6px; }
.item-card__progress { height: 5px; background: var(--bg-active); border-radius: 3px; overflow: hidden; margin-top: 4px; position: relative; }
.item-card__progress-fill { height: 100%; border-radius: 3px; background: linear-gradient(90deg, var(--ic-color, #3b82f6), color-mix(in srgb, var(--ic-color, #3b82f6) 55%, #22c55e)); transition: width 0.5s cubic-bezier(0.4,0,0.2,1); position: relative; box-shadow: 0 0 6px color-mix(in srgb, var(--ic-color, #3b82f6) 40%, transparent); }
.item-card__progress-fill::after { content: ''; position: absolute; top: 0; right: 0; bottom: 0; width: 16px; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.5)); border-radius: 3px; animation: progressShimmer 1.4s ease-in-out infinite; }
.item-card[data-complete="true"] .item-card__progress-fill { background: linear-gradient(90deg, #10b981, #34d399); box-shadow: 0 0 8px rgba(16,185,129,0.45); }
.item-card--folder { --ic-color: #8b5cf6; }
.item-card--folder::after { background: linear-gradient(90deg, #8b5cf6, #a78bfa); }
.item-card--folder .item-card__progress, .item-card--folder .item-card__meta-folder { display: none; }
.item-card--tree { margin-left: calc(var(--ic-depth, 0) * 20px); }
.item-card__ring { position: relative; width: 44px; height: 44px; flex-shrink: 0; align-self: center; margin-right: 16px; display: flex; align-items: center; justify-content: center; }
.ring-svg { width: 100%; height: 100%; transform: rotate(-90deg); overflow: visible; }
.ring-svg .ring-bg { fill: none; stroke: var(--bg-active); stroke-width: 3.5; }
.ring-svg .ring-fg { fill: none; stroke: var(--ic-color, #3b82f6); stroke-width: 3.5; stroke-linecap: round; transition: stroke-dashoffset 0.6s cubic-bezier(0.4,0,0.2,1); filter: drop-shadow(0 0 3px color-mix(in srgb, var(--ic-color, #3b82f6) 50%, transparent)); }
.ring-text { position: absolute; font-size: 0.68rem; font-weight: 700; color: var(--ic-color, #3b82f6); letter-spacing: -0.02em; }
.ring-icon { position: absolute; font-size: 1rem; filter: saturate(0.9); }
.item-card[data-complete="true"] .ring-svg .ring-fg { stroke: #10b981; filter: drop-shadow(0 0 4px rgba(16,185,129,0.5)); }
.item-card[data-complete="true"] .ring-text { color: #10b981; }
.item-card[data-complete="true"] .ring-text::after { content: ' \2713'; }
.item-card--folder .ring-svg { display: none; }
.item-card--folder .ring-icon { font-size: 1.4rem; }

/* ===== 16. Flashcard / Review ===== */
.fc-container { display: flex; flex-direction: column; align-items: center; gap: var(--space-xl); position: relative; z-index: 2; animation: fadeIn 0.25s ease 0.06s both; }
.fc-chapter-name { display: flex; align-items: center; gap: 6px; padding: 5px 12px; background: var(--bg-tertiary); border-radius: var(--radius-full); font-size: 0.82rem; font-weight: 500; color: var(--text-secondary); width: fit-content; max-width: 100%; overflow: hidden; margin-top: 4px; }
.fc-chapter-name-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fc-progress-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fc-progress-wrap { position: relative; z-index: 2; margin-bottom: var(--space-xl); animation: fadeIn 0.25s ease 0.04s both; }
.fc-progress-bar { width: 100%; height: 8px; background: var(--bg-tertiary); border-radius: var(--radius-full); overflow: hidden; box-shadow: inset 0 1px 3px rgba(0,0,0,0.08); position: relative; }
.fc-progress-fill { height: 100%; width: 0%; background: linear-gradient(90deg, var(--accent), var(--accent-hover)); border-radius: var(--radius-full); transition: width 0.45s cubic-bezier(0.4,0,0.2,1); position: relative; box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 40%, transparent); }
.fc-progress-fill::after { content: ''; position: absolute; top: 0; right: 0; bottom: 0; width: 30px; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.5)); border-radius: var(--radius-full); animation: progressShimmer 1.2s ease-in-out infinite; }
.fc-progress-bar.complete .fc-progress-fill { background: linear-gradient(90deg, #10b981, #34d399); box-shadow: 0 0 12px rgba(16,185,129,0.5); animation: progressPulse 0.6s ease; }
@keyframes progressPulse { 0% { transform: scaleX(1); } 50% { transform: scaleX(1.015); } 100% { transform: scaleX(1); } }
.fc-first-btn, .fc-list-btn, .fc-icon-btn { display: inline-flex; align-items: center; gap: 4px; padding: 3px 10px; font-size: 0.75rem; font-weight: 600; color: var(--text-tertiary); cursor: pointer; border: 1px solid var(--border); border-radius: var(--radius-full); background: var(--bg-secondary); transition: all 0.15s ease; }
.fc-first-btn:hover { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); background: var(--accent-light); }
.fc-list-btn { margin-left: 6px; }
.fc-list-btn:hover { color: #06b6d4; border-color: color-mix(in srgb, #06b6d4 40%, transparent); background: rgba(6,182,212,0.06); }
.fc-icon-btn { margin-left: 6px; }
.fc-icon-btn:hover { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); background: var(--accent-light); }
.fc-skeleton { width: 100%; max-width: 820px; display: flex; flex-direction: column; gap: var(--space-md); padding: var(--space-2xl); border-radius: var(--radius-2xl); background: var(--bg-secondary); border: 1px solid var(--border); pointer-events: none; }
.flashcard-header-row { display: flex; align-items: center; gap: var(--space-sm); }
#flashcard-progress-text { display: inline-flex; align-items: center; gap: 8px; padding: 4px 14px; background: var(--bg-tertiary); border-radius: var(--radius-full); font-size: 0.85rem !important; color: var(--text-secondary) !important; font-weight: 500; border: 1px solid var(--border); }
#flashcard-progress-text::before { content: '\1F4CA'; font-size: 0.8rem; }
.flashcard-first-btn { display: inline-flex; align-items: center; gap: 4px; padding: 4px 10px !important; font-size: 0.78rem !important; border-radius: var(--radius-full) !important; transition: all var(--transition-fast); }
.flashcard-first-btn:hover { background: var(--accent-light) !important; color: var(--accent) !important; border-color: var(--accent) !important; }
.flashcard-first-btn svg { flex-shrink: 0; }
.flashcard-progress-bar { width: 100%; max-width: 820px; height: 5px; background: var(--bg-tertiary); border-radius: var(--radius-full); overflow: hidden; box-shadow: inset 0 1px 2px rgba(0,0,0,0.06); }
.flashcard-progress-fill { height: 100%; width: 0%; background: linear-gradient(90deg, var(--accent), var(--accent-hover)); border-radius: var(--radius-full); transition: width 0.35s cubic-bezier(0.4,0,0.2,1); position: relative; }
.flashcard-progress-fill::after { content: ''; position: absolute; top: 0; right: 0; bottom: 0; width: 20px; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4)); border-radius: var(--radius-full); animation: progressShimmer 0.9s ease-in-out infinite; }
@keyframes progressShimmer { 0%, 100% { opacity: 0; } 50% { opacity: 1; } }
.review-card { width: 100%; max-width: 840px; background: var(--bg-secondary); border-radius: var(--radius-2xl); overflow: hidden; transition: all var(--transition-base); position: relative; border: 1px solid var(--border); box-shadow: var(--shadow-card); }
.review-card::before, .review-card::after { display: none; }
.review-card > * { position: relative; z-index: 1; }
.review-card .review-card-question, .review-card .review-card-answer { position: relative; z-index: 1; background: transparent; }
.review-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-card-hover); }
.review-card-tap .review-card-question { position: relative; }
.review-card-tap .review-card-question::before, .review-card-tap .review-card-question::after { content: ''; position: absolute; top: 0; bottom: 0; width: 50%; pointer-events: none; opacity: 0; transition: opacity var(--transition-fast); z-index: 1; }
.review-card-tap .review-card-question::before { left: 0; background: linear-gradient(90deg, rgba(var(--accent-rgb),0.05), transparent 70%); border-radius: var(--radius-2xl) 0 0 0; }
.review-card-tap .review-card-question::after { right: 0; background: linear-gradient(-90deg, rgba(var(--accent-rgb),0.05), transparent 70%); border-radius: 0 var(--radius-2xl) 0 0; }
.review-card-tap:hover .review-card-question::before, .review-card-tap:hover .review-card-question::after { opacity: 1; }
.review-card-tap .review-card-question > * { position: relative; z-index: 2; }
.card-hint-left, .card-hint-right { display: none !important; position: absolute; top: 50%; transform: translateY(-50%); width: 28px; height: 28px; align-items: center; justify-content: center; z-index: 3; pointer-events: none; opacity: 0.6; transition: opacity var(--transition-fast); }
.card-hint-left { left: 12px; }
.card-hint-right { right: 12px; }
.card-hint-left svg, .card-hint-right svg { width: 18px; height: 18px; stroke: var(--accent); stroke-width: 2.5; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.review-card-question { padding: var(--space-2xl) var(--space-2xl) var(--space-xl); position: relative; background: transparent; }
.review-card-label { display: inline-flex; align-items: center; gap: 6px; font-size: 0.75rem; letter-spacing: 0.02em; font-weight: 500; color: var(--accent); margin-bottom: var(--space-lg); padding: 5px 14px; background: var(--accent-light); border: 1px solid var(--accent-subtle); border-radius: var(--radius-full); position: relative; }
.review-card-label::before { content: ''; width: 6px; height: 6px; background: var(--accent); border-radius: 50%; opacity: 0.6; }
.review-card-answer .review-card-label { color: var(--success); background: var(--success-light); border-color: color-mix(in srgb, var(--success) 20%, transparent); }
.review-card-answer .review-card-label::before { background: var(--success); }
.review-card-content { font-size: 1.2rem; line-height: 1.7; color: var(--text-primary); font-weight: 400; letter-spacing: -0.01em; }
.review-card-content table { font-size: 0.92rem; margin: var(--space-sm) 0; border-collapse: collapse; }
.review-card-content table th, .review-card-content table td { padding: 8px 14px; border: 1px solid var(--border); }
.review-card-content table th { background: var(--bg-tertiary); font-weight: 600; }
.review-card-answer { border-top: 1px solid var(--border); position: relative; }
.review-card-toggle { width: 100%; padding: 14px var(--space-2xl); border: none; border-top: 1px solid var(--border); background: var(--bg-tertiary); color: var(--accent); font-size: 0.88rem; font-weight: 500; cursor: pointer; transition: background var(--transition-base), color var(--transition-base); position: relative; overflow: hidden; letter-spacing: -0.01em; display: flex; align-items: center; justify-content: center; gap: 6px; }
.toggle-icon { display: inline-flex; width: 16px; height: 16px; flex-shrink: 0; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235e6ad2' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.062 11.062c-.625.875-.625 2.062 0 2.938l.563.75a10.05 10.05 0 008.375 4.5h2c3.313 0 6.375-1.563 8.375-4.5l.563-.75c.625-.876.625-2.063 0-2.938l-.563-.75A10.05 10.05 0 0013 5.75h-2A10.05 10.05 0 002.625 10.312z'/%3E%3Ccircle cx='12' cy='12.5' r='3'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: center; background-size: contain; }
.toggle-icon-up { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235e6ad2' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='18 15 12 9 6 15'/%3E%3C/svg%3E") !important; }
.review-card-toggle::after { content: ''; position: absolute; bottom: 0; left: 25%; right: 25%; height: 2px; background: var(--accent); opacity: 0.3; border-radius: var(--radius-full); }
.review-card-toggle:hover { background: var(--bg-hover); color: var(--accent-hover); }
.review-card-toggle:hover::after { opacity: 0.6; }
.review-card-answer-body { max-height: 0; overflow: hidden; transition: max-height 0.2s cubic-bezier(0.25,0.1,0.25,1), padding 0.18s, opacity 0.15s; opacity: 0; padding: 0 var(--space-2xl); }
.review-card-answer.expanded .review-card-answer-body { max-height: 5000px; padding: var(--space-2xl); opacity: 1; background: var(--bg-tertiary); border-top: 1px solid var(--border); transition: max-height 0.2s cubic-bezier(0.25,0.46,0.45,0.94), padding 0.18s, opacity 0.16s; }
.no-transition, .no-transition * { transition: none !important; animation: none !important; }
.review-card-answer.expanded .review-card-toggle::after { display: none; }
.review-card-explanation { margin-top: var(--space-lg); padding: var(--space-lg) var(--space-xl); background: color-mix(in srgb, #f59e0b 6%, transparent); border: 1px solid color-mix(in srgb, #f59e0b 15%, var(--border)); border-left: 3px solid #f59e0b; border-radius: var(--radius-lg); position: relative; }
.review-card-explanation strong { color: #d97706; font-weight: 700; font-size: 0.88rem; text-transform: uppercase; letter-spacing: 1px; }
[data-theme="dark"] .review-card-explanation strong { color: #ffd60a; }
[data-theme="dark"] .review-card-answer .review-card-label { color: #30d158; }
.flashcard-actions { display: flex; flex-direction: column; gap: var(--space-md); justify-content: center; align-items: center; width: 100%; max-width: 720px; padding: var(--space-lg) 0 0; }
.flashcard-nav { display: flex; gap: var(--space-md); align-items: center; justify-content: center; }
.flashcard-nav-main { gap: var(--space-sm); }
.flashcard-nav-actions { gap: var(--space-md); }
.flashcard-container { display: flex; flex-direction: column; align-items: center; gap: var(--space-xl); }
.rv-list-container { max-width: 860px !important; width: 100%; margin: 0 auto; }
.rv-list-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 20px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-lg) var(--radius-lg) 0 0; border-bottom: none; }
.rv-list-title { font-size: 0.95rem; font-weight: 700; color: var(--text-primary); display: flex; align-items: center; gap: 8px; }
.rv-list-title::before { content: ''; display: inline-block; width: 4px; height: 18px; border-radius: 2px; background: linear-gradient(to bottom, #06b6d4, #8b5cf6); }
.rv-list-count { font-size: 0.78rem; color: var(--text-tertiary); background: var(--bg-tertiary); padding: 2px 10px; border-radius: var(--radius-full); }
.rv-list-body { display: flex; flex-direction: column; border: 1px solid var(--border); border-top: none; border-radius: 0 0 var(--radius-lg) var(--radius-lg); overflow: hidden; }
.rv-item { padding: 18px 20px; background: var(--bg-secondary); border-bottom: 1px solid var(--border-light); cursor: pointer; transition: background var(--transition-fast); position: relative; }
.rv-item:last-child { border-bottom: none; border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
.rv-item:hover { background: var(--bg-hover); }
.rv-item-answered { background: var(--success-light); }
.rv-item-answered:hover { background: rgba(16,185,129,0.12); }
.rv-item-header { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.rv-item-num { font-size: 0.8rem; font-weight: 700; color: #06b6d4; background: rgba(6,182,212,0.08); padding: 1px 8px; border-radius: var(--radius-full); }
.rv-item-badge { font-size: 0.7rem; font-weight: 600; color: var(--success); background: var(--success-light); padding: 1px 8px; border-radius: var(--radius-full); }
.rv-item-body { display: flex; flex-direction: column; gap: 8px; }
.rv-item-q, .rv-item-a { font-size: 0.9rem; line-height: 1.65; color: var(--text-primary); }
.rv-item-q strong, .rv-item-a strong { color: var(--accent); margin-right: 4px; }
.rv-exp { font-size: 0.85rem; line-height: 1.65; color: var(--text-secondary); padding: 10px 14px; background: var(--bg-tertiary); border-radius: var(--radius-md); margin-top: 2px; border-left: 3px solid var(--accent); }
.rv-exp strong { color: var(--accent); }

/* ===== 17. Quiz Mode ===== */
.quiz-page { display: block; min-height: calc(100vh - var(--nav-height) - var(--space-lg)); width: 100%; }
.quiz-page--scope { display: flex; flex-direction: column; min-height: calc(100vh - var(--nav-height) - var(--space-lg)); padding-bottom: calc(70px + env(safe-area-inset-bottom, 0px)); }
.quiz-page-inner { flex: 1; width: 100%; }
.quiz-page .bk-header { padding: 0 var(--space-lg); margin-bottom: var(--space-md); }
.quiz-container { max-width: 100%; width: 100%; margin: 0; padding: 0; }
.quiz-toolbar { display: flex; align-items: center; gap: 8px; padding: 0 var(--space-lg) var(--space-md); position: relative; z-index: 2; }
.quiz-scope-listwrap { position: relative; z-index: 2; padding-bottom: var(--space-xl); }
.quiz-active-wrap { padding: 0 var(--space-lg); max-width: 800px; margin: 0 auto; width: 100%; }
.quiz-bottom-bar { position: fixed; left: 0; right: 0; bottom: 0; padding: var(--space-md) var(--space-lg) calc(var(--space-lg) + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--border); background: var(--surface-strong); z-index: 100; backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
.quiz-progress { display: flex; align-items: center; gap: var(--space-md); margin-bottom: var(--space-lg); }
.quiz-progress-bar { flex: 1; height: 6px; background: var(--bg-tertiary); border-radius: var(--radius-full); overflow: hidden; }
.quiz-progress-fill { height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-hover)); border-radius: var(--radius-full); transition: width 0.3s cubic-bezier(0.4,0,0.2,1); }
.quiz-progress-text { display: inline-flex; align-items: center; gap: 6px; font-size: 0.82rem; font-weight: 500; color: var(--text-secondary); padding: 4px 14px; background: var(--bg-tertiary); border-radius: var(--radius-full); border: 1px solid var(--border); white-space: nowrap; }
.quiz-progress-text::before { content: '\1F3B2'; font-size: 0.75rem; }
.quiz-scope-panel { display: contents; }
.quiz-scope-title { display: none; }
.quiz-scope-count { margin-left: auto; font-size: 0.8rem; color: var(--text-tertiary); font-weight: 500; padding: 4px 12px; background: var(--bg-tertiary); border-radius: var(--radius-full); }
.quiz-scope-list { padding: 0; }
.quiz-scope-book { margin-bottom: 0; border-radius: 0; border: none; border-bottom: 1px solid var(--border-light); transition: background var(--transition-fast); }
.quiz-scope-book:hover { border-color: var(--border-light); background: color-mix(in srgb, var(--accent) 3%, transparent); }
.quiz-scope-book-header { display: flex; align-items: center; gap: 10px; padding: 12px var(--space-lg); cursor: pointer; user-select: none; border-radius: 0; transition: background var(--transition-fast); min-height: 48px; }
.quiz-scope-book-header:hover { background: color-mix(in srgb, var(--accent) 4%, transparent); }
.quiz-scope-group { border: none; border-radius: 0; margin-bottom: 0; background: transparent; overflow: hidden; transition: all 0.18s ease; border-bottom: 1px solid var(--border-light); }
.quiz-scope-group:hover { border-color: var(--border-light); background: color-mix(in srgb, var(--accent) 2%, transparent); }
.quiz-scope-group-header { display: flex; align-items: center; gap: 12px; padding: 12px var(--space-lg); cursor: pointer; user-select: none; background: color-mix(in srgb, var(--bg-tertiary) 60%, transparent); transition: background 0.15s ease; min-height: 48px; }
.quiz-scope-group-header:hover { background: color-mix(in srgb, var(--accent) 5%, var(--bg-tertiary)); }
.quiz-scope-group-children { padding: 0; max-height: 2000px; overflow: hidden; transition: max-height 0.25s cubic-bezier(0.4,0,0.2,1), opacity 0.18s ease, padding 0.2s ease; }
.quiz-scope-group.collapsed .quiz-scope-group-children { max-height: 0 !important; opacity: 0; }
.quiz-scope-group.collapsed .quiz-toggle-arrow svg { transform: rotate(-90deg); }
.quiz-scope-book.collapsed .quiz-scope-chapters { max-height: 0 !important; opacity: 0; }
.quiz-scope-book.collapsed .quiz-toggle-arrow svg { transform: rotate(-90deg); }
.quiz-scope-chapters { padding: 0; max-height: 2000px; overflow: hidden; transition: max-height 0.22s cubic-bezier(0.4,0,0.2,1), opacity 0.15s ease, padding 0.18s ease; }
.quiz-scope-chapters .quiz-scope-chapter-item { padding-left: calc(var(--space-lg) + 36px); background: color-mix(in srgb, var(--bg-tertiary) 30%, transparent); }
.quiz-scope-children { padding: 0; max-height: 2000px; overflow: hidden; transition: max-height 0.25s cubic-bezier(0.4,0,0.2,1), opacity 0.18s ease, padding 0.2s ease; }
.quiz-scope-children > .quiz-scope-group > .quiz-scope-group-header, .quiz-scope-children > .quiz-scope-book > .quiz-scope-book-header { padding-left: calc(var(--space-lg) + 28px); }
.quiz-scope-group.collapsed .quiz-scope-children { max-height: 0 !important; opacity: 0; }
.quiz-scope-item, .quiz-scope-chapter-item { display: flex; align-items: center; gap: 12px; padding: 11px var(--space-lg); border-radius: 0; cursor: pointer; user-select: none; transition: background var(--transition-fast); min-height: 48px; border-bottom: 1px solid color-mix(in srgb, var(--border) 50%, transparent); }
.quiz-scope-item:hover, .quiz-scope-chapter-item:hover { background: color-mix(in srgb, var(--accent) 4%, transparent); }
.quiz-item-icon { display: flex; align-items: center; flex-shrink: 0; }
.quiz-item-name { font-size: 0.9rem; font-weight: 500; color: var(--text-primary); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.quiz-item-count { font-size: 0.75rem; color: var(--text-tertiary); flex-shrink: 0; }
.quiz-item-ring { position: relative; width: 36px; height: 36px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; margin-left: 4px; }
.quiz-ring-svg { width: 100%; height: 100%; transform: rotate(-90deg); overflow: visible; }
.quiz-ring-svg .quiz-ring-bg { fill: none; stroke: var(--bg-active); stroke-width: 3.5; }
.quiz-ring-svg .quiz-ring-fg { fill: none; stroke: var(--ic-color, #3b82f6); stroke-width: 3.5; stroke-linecap: round; transition: stroke-dashoffset 0.6s cubic-bezier(0.4,0,0.2,1); filter: drop-shadow(0 0 2px color-mix(in srgb, var(--ic-color, #3b82f6) 50%, transparent)); }
.quiz-ring-text { position: absolute; font-size: 0.6rem; font-weight: 700; color: var(--ic-color, #3b82f6); letter-spacing: -0.02em; }
.quiz-ring-text.complete { color: #10b981; }
.quiz-item-ring:has(.quiz-ring-text.complete) .quiz-ring-fg { stroke: #10b981; filter: drop-shadow(0 0 3px rgba(16,185,129,0.5)); }
.quiz-toggle-arrow { display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: var(--radius-sm); cursor: pointer; flex-shrink: 0; color: var(--text-tertiary); transition: all 0.2s ease; }
.quiz-toggle-arrow svg { width: 14px; height: 14px; transition: transform 0.2s cubic-bezier(0.4,0,0.2,1); }
.quiz-toggle-arrow:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); color: var(--accent); }
.quiz-toggle-spacer { width: 24px; height: 24px; flex-shrink: 0; }
.quiz-scope-tag { font-size: 0.75rem; background: color-mix(in srgb, var(--accent) 8%, var(--bg-tertiary)); border-color: color-mix(in srgb, var(--accent) 20%, var(--border)); color: var(--accent); }
.quiz-scope-tag::before { content: none; }
.quiz-scope-footer { display: none; }
.btn-quiz-start { padding: 14px 32px; font-size: 1rem; font-weight: 600; border-radius: var(--radius-lg); display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; max-width: 400px; margin: 0 auto; }
.btn-quiz-start svg { width: 20px; height: 20px; flex-shrink: 0; }
.quiz-card-hint svg { width: 20px; height: 20px; flex-shrink: 0; }
.btn-quiz-start:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-quiz-start:not(:disabled):hover { transform: translateY(-1px); box-shadow: 0 4px 16px color-mix(in srgb, var(--accent) 30%, transparent); }
.quiz-input-area { margin-top: var(--space-lg); }
.quiz-input-area textarea { width: 100%; min-height: 120px; padding: var(--space-md); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-secondary); color: var(--text-primary); font-size: 0.95rem; line-height: 1.6; resize: vertical; transition: border-color var(--transition-fast); }
.quiz-input-area textarea:focus { outline: none; border-color: var(--accent); }
.quiz-check { width: 20px; height: 20px; border-radius: 6px; border: 2px solid var(--border-hover); background: transparent; flex-shrink: 0; cursor: pointer; position: relative; transition: all 0.15s cubic-bezier(0.25,0.1,0.25,1); user-select: none; -webkit-user-select: none; touch-action: none; }
.quiz-check::after { content: ''; position: absolute; top: 3px; left: 5px; width: 5px; height: 9px; border: 2px solid white; border-top: none; border-left: none; transform: rotate(45deg) scale(0); transition: transform 0.12s cubic-bezier(0.25,0.46,0.45,0.94); }
.quiz-check.checked { background: var(--accent); border-color: var(--accent); box-shadow: 0 1px 4px rgba(var(--accent-rgb), 0.25); }
.quiz-check.checked::after { transform: rotate(45deg) scale(1); }
.quiz-check.partial { background: var(--accent); border-color: var(--accent); opacity: 0.6; }
.quiz-check.partial::after { content: ''; top: 50%; left: 50%; width: 8px; height: 2px; border: none; border-radius: 1px; background: white; transform: translate(-50%, -50%) scale(1); }
.quiz-check:hover { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.1); }
.quiz-check-sm { width: 17px; height: 17px; border-radius: 5px; }
.quiz-check-sm::after { top: 2px; left: 4px; width: 4px; height: 7px; }

/* ===== 31. Quiz Mode UI Redesign ===== */

/* -- Selected state in scope list (CSS :has) -- */
.quiz-scope-item:has(.quiz-check.checked){background:color-mix(in srgb,var(--accent) 5%,var(--bg-secondary));border-left:2.5px solid var(--accent)}
.quiz-scope-chapter-item:has(.quiz-check.checked){background:color-mix(in srgb,var(--accent) 5%,var(--bg-secondary))}
.quiz-scope-book:has(>.quiz-scope-book-header>.quiz-check.checked){background:color-mix(in srgb,var(--accent) 3%,var(--bg-secondary))}
.quiz-scope-group:has(>.quiz-scope-group-header>.quiz-check.checked){background:color-mix(in srgb,var(--accent) 3%,var(--bg-secondary))}
.quiz-scope-item:has(.quiz-check.partial){border-left:2.5px solid color-mix(in srgb,var(--accent) 50%,transparent)}

/* -- Improved start bar -- */
.quiz-bottom-bar{box-shadow:0 -6px 24px rgba(0,0,0,0.12)}
.btn-quiz-start{border-radius:var(--radius-lg) !important;background:var(--accent) !important;box-shadow:inset 0 1px 0 rgba(255,255,255,0.08),0 2px 12px rgba(var(--accent-rgb),0.25) !important;letter-spacing:-0.01em}
.btn-quiz-start:not(:disabled):hover{transform:translateY(-1px);background:var(--accent-hover) !important;box-shadow:inset 0 1px 0 rgba(255,255,255,0.08),0 4px 16px rgba(var(--accent-rgb),0.32) !important}
.btn-quiz-start:disabled{background:var(--bg-tertiary) !important;box-shadow:none !important;color:var(--text-tertiary) !important}

/* -- Quiz question wrapper -- */
.qz-question-wrap{padding:0 var(--space-lg) var(--space-2xl);max-width:820px;margin:0 auto;animation:fadeIn 0.25s ease both}
.qz-meta-row{display:flex;align-items:center;gap:8px;margin-bottom:var(--space-lg);flex-wrap:wrap}
.qz-count-pill{display:inline-flex;align-items:baseline;gap:2px;padding:4px 12px;background:var(--accent);color:white;border-radius:var(--radius-full);font-size:0.78rem;font-weight:500;flex-shrink:0;letter-spacing:0.01em}
.qz-count-pill strong{font-size:1rem;font-weight:800;line-height:1}
.qz-origin{font-size:0.8rem;color:var(--text-secondary);font-weight:500;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.qz-scope-badge{display:inline-flex;align-items:center;gap:4px;font-size:0.72rem;color:var(--text-tertiary);background:var(--bg-tertiary);padding:3px 10px;border-radius:var(--radius-full);border:1px solid var(--border);flex-shrink:0;max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* -- Quiz action buttons -- */
.qz-actions{display:flex;gap:12px;margin-top:var(--space-lg)}
.qz-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:15px 20px;border:none;border-radius:var(--radius-lg);font-size:0.95rem;font-weight:600;cursor:pointer;transition:all var(--transition-base);letter-spacing:-0.01em}
.qz-btn--wrong{background:var(--danger-light);color:var(--danger);border:1px solid color-mix(in srgb,var(--danger) 20%,transparent);flex:1}
.qz-btn--wrong:hover{background:var(--danger);color:white;transform:translateY(-1px);box-shadow:0 2px 10px color-mix(in srgb,var(--danger) 25%,transparent)}
.qz-btn--next{background:var(--accent);color:white;flex:2;box-shadow:inset 0 1px 0 rgba(255,255,255,0.08),0 2px 8px rgba(var(--accent-rgb),0.2)}
.qz-btn--next:hover{background:var(--accent-hover);transform:translateY(-1px);box-shadow:inset 0 1px 0 rgba(255,255,255,0.08),0 4px 14px rgba(var(--accent-rgb),0.28)}

/* Quiz page inner max-width for desktop */
.quiz-page-inner{max-width:860px;margin-left:auto;margin-right:auto}

/* ===== 32. Chinese active-recall practice ===== */
.chn-recall-page{min-height:calc(100vh - var(--nav-height) - var(--space-lg));padding-bottom:var(--space-2xl)}
.chn-recall-header{padding:0 var(--space-lg);margin-bottom:var(--space-lg)}
.chn-recall-loading{max-width:820px;margin:14vh auto 0;padding:32px;text-align:center;color:var(--text-secondary)}
.chn-recall-toolbar{display:flex;align-items:center;gap:10px;max-width:820px;margin:0 auto var(--space-sm);padding:0 var(--space-lg);font-size:.8rem;color:var(--text-secondary);flex-wrap:wrap}
.chn-recall-count{font-weight:700;color:var(--accent);background:var(--accent-light);border-radius:var(--radius-full);padding:4px 10px}
.chn-recall-score{font-weight:600}
.chn-recall-origin{margin-left:auto;max-width:42%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-tertiary)}
.chn-recall-progress{height:6px;max-width:820px;margin:0 auto var(--space-xl);background:var(--bg-tertiary);border-radius:var(--radius-full);overflow:hidden}
.chn-recall-progress span{display:block;height:100%;background:linear-gradient(90deg,#0891b2,#22c55e);border-radius:inherit;transition:width .3s ease}
.chn-recall-card{max-width:820px;margin:0 auto;padding:clamp(22px,4vw,40px);border:1px solid var(--border);border-radius:var(--radius-xl);background:var(--bg-secondary);box-shadow:var(--shadow-card);animation:fadeIn .25s ease both}
.chn-recall-label{font-size:.76rem;font-weight:700;letter-spacing:.04em;color:var(--accent);margin-bottom:var(--space-md)}
.chn-recall-question{font-size:clamp(1.1rem,2.2vw,1.45rem);line-height:1.75;color:var(--text-primary);font-weight:600}
.chn-recall-prompt{margin:var(--space-lg) 0 var(--space-sm);font-size:.85rem;color:var(--text-tertiary)}
.chn-recall-options{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
.chn-recall-options-loading{display:flex;align-items:center;gap:10px;min-height:136px;padding:24px 20px;border:1px dashed color-mix(in srgb,var(--accent) 35%,var(--border));border-radius:var(--radius-lg);background:color-mix(in srgb,var(--accent) 4%,var(--bg-primary));color:var(--text-secondary);flex-wrap:wrap}
.chn-recall-options-loading strong{color:var(--text-primary);font-size:.95rem}
.chn-recall-options-loading>span:last-child{width:100%;padding-left:30px;font-size:.82rem;color:var(--text-tertiary)}
.chn-recall-spinner{width:20px;height:20px;border:2px solid color-mix(in srgb,var(--accent) 22%,transparent);border-top-color:var(--accent);border-radius:50%;animation:chnRecallSpin .8s linear infinite;flex:0 0 20px}
@keyframes chnRecallSpin{to{transform:rotate(360deg)}}
.chn-recall-generation-failure{padding:20px;border:1px solid color-mix(in srgb,var(--danger) 34%,var(--border));border-radius:var(--radius-lg);background:color-mix(in srgb,var(--danger) 5%,var(--bg-primary))}
.chn-recall-failure-heading{display:flex;align-items:flex-start;gap:11px;color:var(--danger)}
.chn-recall-failure-heading strong,.chn-recall-failure-heading span{display:block}
.chn-recall-failure-heading span{margin-top:4px;font-size:.84rem;color:var(--text-secondary)}
.chn-recall-failure-mark{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;flex:0 0 24px;border-radius:50%;background:var(--danger);color:#fff;font-weight:800}
.chn-recall-failure-message{margin:14px 0 0;padding:10px 12px;border-left:3px solid var(--danger);background:color-mix(in srgb,var(--danger) 7%,transparent);color:var(--text-secondary);font-size:.82rem;line-height:1.55;overflow-wrap:anywhere}
.chn-recall-failure-actions{display:flex;gap:9px;flex-wrap:wrap;margin-top:16px}
.chn-recall-failure-actions .btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:38px}
.chn-recall-failure-actions svg{width:16px;height:16px}
.chn-recall-maintenance{margin-top:16px;padding-top:15px;border-top:1px solid color-mix(in srgb,var(--danger) 18%,var(--border))}
.chn-recall-diagnostic-loading{display:flex;align-items:center;gap:9px;color:var(--text-secondary);font-size:.82rem}
.chn-recall-diagnostic-loading .chn-recall-spinner{width:16px;height:16px;flex-basis:16px}
.chn-recall-diagnostic-error{margin:0;color:var(--danger);font-size:.82rem;overflow-wrap:anywhere}
.chn-recall-diagnostic-list{display:grid;gap:7px;margin:0;font-size:.8rem}
.chn-recall-diagnostic-meta{margin-bottom:12px}
.chn-recall-diagnostic-list>div{display:flex;justify-content:space-between;gap:15px;padding-bottom:6px;border-bottom:1px solid var(--border)}
.chn-recall-diagnostic-list dt{color:var(--text-tertiary)}
.chn-recall-diagnostic-list dd{margin:0;color:var(--text-primary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;text-align:right;overflow-wrap:anywhere}
.chn-recall-diagnostic-note{margin:12px 0 0;color:var(--text-tertiary);font-size:.76rem;line-height:1.55}
.chn-recall-lobby{max-width:900px;margin:0 auto;display:grid;gap:16px}
.chn-recall-lobby-hero{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:28px 30px;border:1px solid var(--border);border-radius:var(--radius-xl);background:var(--bg-secondary);box-shadow:var(--shadow-card)}
.chn-recall-lobby-kicker{display:block;color:var(--rd-blue, var(--accent));font-size:.75rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase}
.chn-recall-lobby-hero h1{margin:7px 0 8px;color:var(--text-primary);font-size:clamp(1.45rem,3vw,2rem);line-height:1.25}
.chn-recall-lobby-hero p{max-width:600px;margin:0;color:var(--text-secondary);font-size:.9rem;line-height:1.65}
.chn-recall-create-set{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-width:148px;min-height:44px;flex:0 0 auto}
.chn-recall-create-set svg{width:17px;height:17px}
.chn-recall-lobby-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}
.chn-recall-lobby-stats>div{padding:16px 17px;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--bg-secondary)}
.chn-recall-lobby-stats span,.chn-recall-lobby-stats strong{display:block}
.chn-recall-lobby-stats span{font-size:.76rem;color:var(--text-tertiary)}
.chn-recall-lobby-stats strong{margin-top:7px;color:var(--text-primary);font-size:1.35rem}
.chn-recall-preparation{padding:18px 20px;border:1px solid color-mix(in srgb,var(--accent) 28%,var(--border));border-radius:var(--radius-xl);background:color-mix(in srgb,var(--accent) 4%,var(--bg-secondary))}
.chn-recall-preparation-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;color:var(--text-primary)}
.chn-recall-preparation-head strong:first-child,.chn-recall-preparation-head span{display:block}
.chn-recall-preparation-head span{margin-top:5px;color:var(--text-tertiary);font-size:.78rem;font-weight:400}
.chn-recall-preparation-head>strong:last-child{color:var(--accent);font-size:1.05rem}
.chn-recall-preparation-bar{height:8px;margin-top:14px;border-radius:var(--radius-full);background:var(--bg-tertiary);overflow:hidden}
.chn-recall-preparation-bar span{display:block;height:100%;border-radius:inherit;background:linear-gradient(90deg,#0891b2,#22c55e);transition:width .25s ease}
.chn-recall-preparation p{margin:10px 0 0;color:var(--text-secondary);font-size:.8rem;line-height:1.55}
.chn-recall-preparation-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:13px}
.chn-recall-preparation-actions .btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:36px}
.chn-recall-preparation-actions svg{width:16px;height:16px}
.chn-recall-history{padding:20px;border:1px solid var(--border);border-radius:var(--radius-xl);background:var(--bg-secondary)}
.chn-recall-section-heading{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}
.chn-recall-section-heading h2{margin:0;color:var(--text-primary);font-size:1.05rem}
.chn-recall-section-heading span{display:block;margin-top:4px;color:var(--text-tertiary);font-size:.78rem}
.chn-recall-history-item{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:14px;padding:13px 0;border-top:1px solid var(--border)}
.chn-recall-history-actions{display:flex;align-items:center;gap:6px}
.chn-recall-history-item-main strong,.chn-recall-history-item-main span,.chn-recall-history-score strong,.chn-recall-history-score span{display:block}
.chn-recall-history-item-main strong{color:var(--text-primary);font-size:.88rem}
.chn-recall-history-item-main span{margin-top:4px;color:var(--text-tertiary);font-size:.76rem}
.chn-recall-history-score{text-align:right;min-width:60px}
.chn-recall-history-score strong{color:var(--text-primary);font-size:.9rem}
.chn-recall-history-score span{margin-top:4px;color:var(--accent);font-size:.75rem;font-weight:700}
.chn-recall-history-score strong.is-failed{color:var(--danger)}
.chn-recall-history-item .btn,.chn-recall-history-detail-head .btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:32px;padding:6px 9px;font-size:.78rem}
.chn-recall-history-item .btn svg,.chn-recall-history-detail-head .btn svg{width:15px;height:15px}
.chn-recall-history-item .btn.is-danger{color:var(--danger)}
.chn-recall-history-empty{margin:0;padding:14px 0;color:var(--text-tertiary);font-size:.84rem}
.chn-recall-history-detail{padding:20px;border:1px solid color-mix(in srgb,var(--accent) 26%,var(--border));border-radius:var(--radius-xl);background:color-mix(in srgb,var(--accent) 3%,var(--bg-secondary))}
.chn-recall-history-detail-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:8px;color:var(--text-primary)}
.chn-recall-history-questions{display:grid;gap:8px}
.chn-recall-history-question{padding:12px 13px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--bg-secondary)}
.chn-recall-history-question-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;color:var(--text-primary);font-size:.83rem;line-height:1.5}
.chn-recall-history-question-head span{flex:0 0 auto;color:var(--text-tertiary);font-size:.75rem}
.chn-recall-history-question.is-correct .chn-recall-history-question-head span{color:var(--success)}
.chn-recall-history-question.is-wrong .chn-recall-history-question-head span{color:var(--danger)}
.chn-recall-history-question-meta{display:flex;flex-wrap:wrap;gap:5px 16px;margin-top:7px;color:var(--text-tertiary);font-size:.76rem;line-height:1.5}
.chn-recall-ask-trigger{display:inline-flex;align-items:center;gap:7px;margin-top:var(--space-lg)}
.chn-recall-ask-trigger svg,.chn-recall-ask-close svg,.chn-recall-ask-actions svg,.chn-recall-ask-error svg{width:16px;height:16px}
.chn-recall-ask{margin-top:var(--space-lg);padding:16px;border:1px solid color-mix(in srgb,var(--accent) 30%,var(--border));border-radius:var(--radius-lg);background:color-mix(in srgb,var(--accent) 4%,var(--bg-primary))}
.chn-recall-ask-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.chn-recall-ask-header strong,.chn-recall-ask-header span{display:block}
.chn-recall-ask-header strong{color:var(--text-primary)}
.chn-recall-ask-header span{margin-top:4px;font-size:.78rem;color:var(--text-tertiary);font-weight:400}
.chn-recall-ask-close{width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;padding:0;flex:0 0 32px}
.chn-recall-ask-hint{margin:12px 0 0;color:var(--text-secondary);font-size:.84rem;line-height:1.6}
.chn-recall-ask-messages{display:grid;gap:10px;margin-top:13px}
.chn-recall-ask-message{display:flex;align-items:flex-start;gap:8px;font-size:.84rem;line-height:1.65}
.chn-recall-ask-message-role{display:inline-flex;align-items:center;justify-content:center;min-width:38px;padding:2px 6px;border-radius:var(--radius-full);font-size:.7rem;font-weight:700;background:var(--bg-tertiary);color:var(--text-secondary)}
.chn-recall-ask-message.is-user .chn-recall-ask-message-role{background:color-mix(in srgb,var(--accent) 14%,var(--bg-tertiary));color:var(--accent)}
.chn-recall-ask-message-body{min-width:0;flex:1;color:var(--text-primary);overflow-wrap:anywhere}
.chn-recall-ask-message.is-user .chn-recall-ask-message-body{color:var(--text-secondary)}
.chn-recall-ask-status{display:flex;align-items:center;gap:8px;margin-top:12px;color:var(--accent);font-size:.8rem}
.chn-recall-ask-status .chn-recall-spinner{width:16px;height:16px;flex-basis:16px}
.chn-recall-ask-error{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:12px;padding:9px 10px;border-left:3px solid var(--danger);background:color-mix(in srgb,var(--danger) 6%,transparent);color:var(--danger);font-size:.8rem;overflow-wrap:anywhere}
.chn-recall-ask-error .btn{display:inline-flex;align-items:center;gap:6px;flex:0 0 auto}
.chn-recall-ask-input{display:block;width:100%;min-height:76px;margin-top:13px;padding:10px 11px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--bg-secondary);color:var(--text-primary);font:inherit;line-height:1.6;resize:vertical}
.chn-recall-ask-input:focus{outline:2px solid color-mix(in srgb,var(--accent) 38%,transparent);outline-offset:1px;border-color:var(--accent)}
.chn-recall-ask-actions{display:flex;justify-content:flex-end;margin-top:10px}
.chn-recall-ask-actions .btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:38px}
.chn-recall-option{display:flex;align-items:flex-start;gap:12px;width:100%;min-height:66px;padding:14px 16px;text-align:left;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--bg-primary);color:var(--text-primary);cursor:pointer;transition:all .16s ease}
.chn-recall-option:hover:not(:disabled){transform:translateY(-1px);border-color:var(--accent);box-shadow:0 4px 14px color-mix(in srgb,var(--accent) 16%,transparent)}
.chn-recall-option:disabled{cursor:default}
.chn-recall-option-key{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;flex:0 0 26px;border-radius:50%;background:var(--bg-tertiary);color:var(--text-secondary);font-size:.78rem;font-weight:800}
.chn-recall-option-text{font-size:.92rem;line-height:1.55;padding-top:2px}
.chn-recall-option.is-correct{border-color:var(--success);background:var(--success-light);color:var(--success)}
.chn-recall-option.is-correct .chn-recall-option-key{background:var(--success);color:#fff}
.chn-recall-option.is-wrong{border-color:var(--danger);background:var(--danger-light);color:var(--danger)}
.chn-recall-option.is-wrong .chn-recall-option-key{background:var(--danger);color:#fff}
.chn-recall-feedback{display:flex;flex-direction:column;gap:6px;margin-top:var(--space-lg);padding:14px 16px;border-radius:var(--radius-lg);font-size:.88rem;line-height:1.6;border:1px solid var(--border)}
.chn-recall-feedback.is-correct{background:var(--success-light);border-color:color-mix(in srgb,var(--success) 25%,var(--border));color:var(--success)}
.chn-recall-feedback.is-wrong{background:var(--danger-light);border-color:color-mix(in srgb,var(--danger) 25%,var(--border));color:var(--danger)}
.chn-recall-explanation{padding-top:8px;border-top:1px solid color-mix(in srgb,currentColor 18%,transparent);color:var(--text-secondary)}
.chn-recall-next{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;margin-top:var(--space-lg);padding:13px 18px}
.chn-recall-next svg{width:16px;height:16px}
.chn-recall-summary{max-width:560px;margin:12vh auto 0;padding:42px 26px;text-align:center;border:1px solid var(--border);border-radius:var(--radius-xl);background:var(--bg-secondary);box-shadow:var(--shadow-card)}
.chn-recall-summary-icon{font-size:3rem;margin-bottom:10px}
.chn-recall-summary h2{margin:0 0 10px;color:var(--text-primary)}
.chn-recall-summary p{color:var(--text-secondary);line-height:1.7}
.chn-recall-summary p strong{font-size:1.4rem;color:var(--accent)}
.chn-recall-summary-tip{font-size:.86rem;margin:18px auto;max-width:420px}
.chn-recall-summary-actions{display:flex;justify-content:center;gap:10px;margin-top:24px}
@media (max-width:600px){
  .chn-recall-header{padding:0;margin-bottom:14px}
  .chn-recall-toolbar{padding:0;gap:7px;font-size:.74rem}
  .chn-recall-origin{order:3;width:100%;max-width:100%;margin-left:0}
  .chn-recall-options{grid-template-columns:1fr}
  .chn-recall-card{margin:0;padding:19px 14px;border-radius:16px}
  .chn-recall-question{font-size:1.04rem;line-height:1.68;overflow-wrap:anywhere}
  .chn-recall-option{min-height:62px;padding:13px 12px;gap:10px;border-radius:13px;-webkit-tap-highlight-color:transparent}
  .chn-recall-option-text{font-size:.88rem;line-height:1.52;overflow-wrap:anywhere}
  .chn-recall-options-loading{min-height:124px;padding:18px 14px}
  .chn-recall-options-loading>span:last-child{padding-left:0}
  .chn-recall-lobby{gap:12px}
  .chn-recall-lobby-hero{align-items:stretch;flex-direction:column;padding:20px 16px;gap:16px;border-radius:16px}
  .chn-recall-lobby-hero p{font-size:.84rem}
  .chn-recall-create-set{width:100%}
  .chn-recall-lobby-stats{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
  .chn-recall-lobby-stats>div{padding:13px 12px}
  .chn-recall-lobby-stats strong{font-size:1.15rem}
  .chn-recall-preparation{padding:15px 13px;border-radius:16px}
  .chn-recall-preparation-actions{justify-content:stretch}
  .chn-recall-preparation-actions .btn{width:100%}
  .chn-recall-history,.chn-recall-history-detail{padding:14px 12px;border-radius:16px}
  .chn-recall-history-item{grid-template-columns:minmax(0,1fr) auto;gap:8px}
  .chn-recall-history-score{grid-column:2;grid-row:1;min-width:50px}
  .chn-recall-history-actions{grid-column:1 / -1;display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:8px}
  .chn-recall-history-actions .btn{width:100%}
  .chn-recall-history-question-head{display:block}
  .chn-recall-history-question-head span{display:block;margin-top:4px}
  .chn-recall-generation-failure{padding:16px 13px}
  .chn-recall-failure-actions{flex-direction:column}
  .chn-recall-failure-actions .btn{width:100%}
  .chn-recall-diagnostic-list>div{display:block}
  .chn-recall-diagnostic-list dd{text-align:left;margin-top:3px}
  .chn-recall-ask{padding:14px 12px}
  .chn-recall-ask-trigger{width:100%;justify-content:center}
  .chn-recall-ask-actions .btn{width:100%}
  .chn-recall-ask-error{align-items:flex-start;flex-direction:column}
  .chn-recall-feedback{padding:12px 13px;font-size:.82rem;overflow-wrap:anywhere}
  .chn-recall-progress{margin-left:0;margin-right:0;margin-bottom:16px}
  .chn-recall-summary{margin:8vh 0 0;padding:31px 17px}
  .chn-recall-summary-actions{flex-direction:column;gap:8px}
  .chn-recall-summary-actions .btn{width:100%;justify-content:center}
}

/* ==== pages/question-bank.css ==== */
/* ===== 题库浏览工作台 ===== */
.qb-page {
  /* #6366f1 as small text only reached 4.12:1 on the light background. */
  --qb-accent: #4f46e5;
  --qb-accent-soft: color-mix(in srgb, var(--qb-accent) 11%, transparent);
  max-width: 1160px;
  min-height: calc(100vh - var(--nav-height) - 24px);
  margin: 0 auto;
  padding-bottom: 56px;
}

.qb-header {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin: 0 auto 24px;
}

.qb-heading { min-width: 0; flex: 1; }
.qb-eyebrow, .qb-toolbar-kicker {
  display: flex;
  align-items: center;
  gap: 7px;
  color: var(--qb-accent);
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .16em;
}
.qb-eyebrow-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--qb-accent); box-shadow: 0 0 0 5px var(--qb-accent-soft); }
.qb-title-line { display: flex; align-items: center; gap: 13px; margin-top: 9px; }
.qb-subject-icon {
  display: grid;
  place-items: center;
  flex: 0 0 46px;
  width: 46px;
  height: 46px;
  border-radius: 14px;
  color: var(--qb-accent);
  background: var(--qb-accent-soft);
  border: 1px solid color-mix(in srgb, var(--qb-accent) 24%, var(--border));
  font-size: 1.25rem;
  font-weight: 800;
}
.qb-title-line h1 { margin: 0; color: var(--text-primary); font-size: clamp(1.45rem, 3vw, 2rem); letter-spacing: -.035em; }
.qb-title-line p { margin: 5px 0 0; color: var(--text-tertiary); font-size: .86rem; line-height: 1.6; }

.qb-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin-bottom: 18px; }
.qb-stat {
  position: relative;
  min-height: 104px;
  padding: 16px 18px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--bg-secondary);
  box-shadow: 0 8px 24px rgba(15, 23, 42, .04);
}
.qb-stat::after { content: ''; position: absolute; width: 80px; height: 80px; right: -30px; bottom: -40px; border-radius: 50%; background: var(--qb-accent-soft); pointer-events: none; }
.qb-stat--accent { border-color: color-mix(in srgb, var(--qb-accent) 25%, var(--border)); background: linear-gradient(145deg, var(--qb-accent-soft), var(--bg-secondary) 65%); }
.qb-stat-label, .qb-stat small { display: block; color: var(--text-tertiary); font-size: .72rem; }
.qb-stat strong { display: block; margin: 7px 0 2px; color: var(--text-primary); font-size: 1.75rem; line-height: 1; letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
.qb-stat--accent strong { color: var(--qb-accent); }

.qb-toolbar {
  position: sticky;
  top: calc(var(--nav-height) + 10px);
  z-index: 4;
  margin-bottom: 16px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: 18px;
  background: color-mix(in srgb, var(--bg-secondary) 92%, transparent);
  box-shadow: 0 10px 28px rgba(15, 23, 42, .07);
  backdrop-filter: blur(16px);
}
.qb-toolbar-top { display: flex; align-items: end; justify-content: space-between; gap: 14px; margin-bottom: 12px; }
.qb-toolbar-top h2 { margin: 4px 0 0; color: var(--text-primary); font-size: 1.02rem; }
.qb-result-summary { color: var(--text-tertiary); font-size: .78rem; white-space: nowrap; }
.qb-controls { display: grid; grid-template-columns: minmax(250px, .82fr) minmax(520px, 1.65fr) 142px; gap: 9px; align-items: end; }
.qb-search { position: relative; display: flex; align-items: center; min-width: 0; }
.qb-search input, .qb-select-wrap select, .qb-scope-selects select {
  width: 100%;
  height: 44px;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--bg-primary);
  color: var(--text-primary);
  font-size: .86rem;
  outline: none;
  transition: border-color .16s ease, box-shadow .16s ease;
}
.qb-search input { padding: 0 38px 0 39px; }
.qb-search input:focus, .qb-select-wrap select:focus, .qb-scope-selects select:focus { border-color: var(--qb-accent); box-shadow: 0 0 0 3px var(--qb-accent-soft); }
.qb-control-icon { position: absolute; left: 13px; display: inline-grid; place-items: center; color: var(--text-tertiary); pointer-events: none; }
.qb-control-icon svg { width: 16px; height: 16px; }
.qb-clear { position: absolute; right: 8px; display: grid; place-items: center; width: 28px; height: 28px; border: 0; border-radius: 8px; color: var(--text-tertiary); background: transparent; cursor: pointer; }
.qb-clear:hover { color: var(--text-primary); background: var(--bg-tertiary); }
.qb-clear svg { width: 15px; height: 15px; }
.qb-select-wrap { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.qb-select-wrap > span { color: var(--text-tertiary); font-size: .69rem; }
.qb-select-wrap select { padding: 0 30px 0 12px; text-overflow: ellipsis; }
.qb-scope-controls { min-width: 0; }
.qb-scope-wrap { min-width: 0; margin: 0; padding: 0; border: 0; }
.qb-scope-wrap legend { margin-bottom: 4px; padding: 0; color: var(--text-tertiary); font-size: .69rem; }
.qb-scope-selects { display: grid; grid-template-columns: minmax(118px, .9fr) minmax(150px, 1.08fr) minmax(180px, 1.32fr); gap: 6px; min-width: 0; }
.qb-scope-selects[data-levels="2"] { grid-template-columns: minmax(140px, .8fr) minmax(210px, 1.2fr); }
.qb-scope-selects select { min-width: 0; padding: 0 30px 0 11px; text-overflow: ellipsis; }
.qb-scope-selects select:disabled { cursor: not-allowed; color: var(--text-tertiary); background: var(--bg-tertiary); opacity: .72; }

.qb-list { display: grid; gap: 11px; }
.qb-card {
  padding: 18px 20px 20px;
  border: 1px solid var(--border);
  border-radius: 17px;
  background: var(--bg-secondary);
  box-shadow: 0 7px 22px rgba(15, 23, 42, .035);
  animation: qbCardIn .24s ease both;
}
.qb-card.is-mastered { border-left: 3px solid #22c55e; }
.qb-card-meta { display: flex; align-items: center; gap: 9px; min-width: 0; margin-bottom: 15px; }
.qb-card-index { display: inline-grid; place-items: center; flex: 0 0 auto; min-width: 31px; height: 25px; padding: 0 7px; border-radius: 8px; color: var(--qb-accent); background: var(--qb-accent-soft); font-size: .72rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.qb-card-source { min-width: 0; overflow: hidden; color: var(--text-tertiary); font-size: .76rem; text-overflow: ellipsis; white-space: nowrap; }
.qb-mastered-pill { margin-left: auto; flex: 0 0 auto; padding: 4px 8px; border-radius: 999px; color: #15803d; background: rgba(34, 197, 94, .11); font-size: .68rem; font-weight: 700; }
.qb-card-section { padding: 13px 15px; border-radius: 12px; overflow-wrap: anywhere; }
.qb-card-section + .qb-card-section { margin-top: 8px; }
.qb-card-question { background: var(--bg-primary); border: 1px solid color-mix(in srgb, var(--border) 70%, transparent); }
.qb-card-answer { background: color-mix(in srgb, var(--qb-accent) 6%, var(--bg-secondary)); border: 1px solid color-mix(in srgb, var(--qb-accent) 13%, var(--border)); }
.qb-card-explanation { background: color-mix(in srgb, #f59e0b 7%, var(--bg-secondary)); border: 1px solid color-mix(in srgb, #f59e0b 13%, var(--border)); }
.qb-section-label { display: block; margin-bottom: 6px; color: var(--text-tertiary); font-size: .69rem; font-weight: 800; letter-spacing: .08em; }
.qb-card-question .qb-section-label { color: var(--qb-accent); }
.qb-content { color: var(--text-primary); font-size: .94rem; line-height: 1.78; }
.qb-content p { margin: 0 0 .55em; }
.qb-content p:last-child { margin-bottom: 0; }
.qb-content ul, .qb-content ol { margin: .3em 0; padding-left: 1.4em; }
.qb-content img { max-width: 100%; height: auto; border-radius: 8px; }
.qb-content pre, .qb-content table { max-width: 100%; overflow: auto; }
.qb-loading { display: grid; justify-items: center; gap: 8px; padding: 52px 20px; color: var(--text-tertiary); }
.qb-loading span { display: block; width: min(540px, 100%); height: 12px; border-radius: 999px; background: linear-gradient(90deg, var(--bg-tertiary), var(--bg-primary), var(--bg-tertiary)); background-size: 200% 100%; animation: qbShimmer 1.3s ease-in-out infinite; }
.qb-loading span:nth-child(2) { width: min(460px, 86%); }
.qb-loading span:nth-child(3) { width: min(380px, 70%); }
.qb-loading p { margin: 8px 0 0; font-size: .82rem; }
.qb-empty { padding: 70px 20px; text-align: center; border: 1px dashed var(--border); border-radius: 17px; color: var(--text-tertiary); background: var(--bg-secondary); }
.qb-empty-icon { display: grid; place-items: center; width: 48px; height: 48px; margin: 0 auto 12px; border-radius: 50%; color: var(--qb-accent); background: var(--qb-accent-soft); font-size: 1.6rem; }
.qb-empty h2 { margin: 0 0 7px; color: var(--text-primary); font-size: 1.05rem; }
.qb-empty p { margin: 0; font-size: .84rem; }
.qb-pagination { display: flex; justify-content: center; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 18px; }
.qb-page-btn { display: inline-grid; place-items: center; min-width: 36px; height: 36px; padding: 0 9px; border: 1px solid var(--border); border-radius: 9px; color: var(--text-secondary); background: var(--bg-secondary); cursor: pointer; font-size: .8rem; font-weight: 700; }
.qb-page-btn:hover:not(:disabled), .qb-page-btn.is-active { border-color: var(--qb-accent); color: var(--qb-accent); background: var(--qb-accent-soft); }
.qb-page-btn:disabled { cursor: not-allowed; opacity: .38; }
.qb-page-btn--arrow svg { width: 15px; height: 15px; }
.qb-page-gap { padding: 0 3px; color: var(--text-tertiary); }

@keyframes qbCardIn { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } }
@keyframes qbShimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }

@media (max-width: 1040px) {
  .qb-controls { grid-template-columns: minmax(0, 1fr) 150px; }
  .qb-search { grid-column: 1 / -1; }
}

@media (max-width: 700px) {
  .qb-scope-controls { grid-column: 1 / -1; }
}

@media (max-width: 600px) {
  .qb-page { padding-bottom: 34px; }
  .qb-header { gap: 10px; margin-bottom: 17px; }
  .qb-title-line { gap: 10px; }
  .qb-subject-icon { flex-basis: 39px; width: 39px; height: 39px; border-radius: 11px; font-size: 1.05rem; }
  .qb-title-line h1 { font-size: 1.34rem; }
  .qb-title-line p { margin-top: 3px; font-size: .78rem; line-height: 1.5; }
  .qb-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px; margin-bottom: 12px; }
  .qb-stat { min-height: 78px; padding: 11px 12px; border-radius: 13px; }
  .qb-stat strong { margin-top: 5px; font-size: 1.42rem; }
  .qb-stat-label, .qb-stat small { font-size: .65rem; }
  .qb-toolbar { position: static; margin-bottom: 12px; padding: 12px; border-radius: 14px; }
  .qb-toolbar-top { align-items: flex-start; flex-direction: column; gap: 4px; margin-bottom: 10px; }
  .qb-toolbar-top h2 { font-size: .95rem; }
  .qb-result-summary { white-space: normal; }
  .qb-controls { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
  .qb-search { grid-column: 1 / -1; }
  .qb-search input, .qb-select-wrap select, .qb-scope-selects select { height: 43px; font-size: .82rem; }
  .qb-scope-selects { grid-template-columns: 1fr 1fr; }
  .qb-scope-selects select:last-child { grid-column: 1 / -1; }
  .qb-scope-selects[data-levels="2"] { grid-template-columns: 1fr 1fr; }
  .qb-scope-selects[data-levels="2"] select:last-child { grid-column: auto; }
  .qb-card { padding: 14px 12px 13px; border-radius: 14px; }
  .qb-card-meta { margin-bottom: 11px; gap: 7px; }
  .qb-card-source { font-size: .68rem; }
  .qb-card-section { padding: 11px 12px; border-radius: 10px; }
  .qb-content { font-size: .88rem; line-height: 1.7; }
  .qb-section-label { margin-bottom: 5px; font-size: .64rem; }
  .qb-pagination { gap: 4px; margin-top: 13px; }
  .qb-page-btn { min-width: 34px; height: 34px; }
}

@media (max-width: 380px) {
  .qb-eyebrow { font-size: .59rem; }
  .qb-controls { grid-template-columns: 1fr; }
  .qb-search { grid-column: auto; }
  .qb-scope-controls { grid-column: auto; }
  .qb-scope-selects, .qb-scope-selects[data-levels="2"] { grid-template-columns: 1fr; }
  .qb-scope-selects select:last-child, .qb-scope-selects[data-levels="2"] select:last-child { grid-column: auto; }
  .qb-select-wrap select { width: 100%; }
  .qb-card-index { min-width: 28px; height: 23px; font-size: .66rem; }
  .qb-mastered-pill { font-size: .61rem; }
}

@media (prefers-reduced-motion: reduce) {
  .qb-card, .qb-loading span { animation: none; }
}
/* ==== pages/error-book.css ==== */
/* ============================================
   Error book & shared list (.wrong-* .list-* .eb-* .formula-* .mp-*)
   Extracted from main.css. Load order matters (see index.html).
   ============================================ */

/* ===== 18. Wrong/Mastered Book ===== */
.wrong-tabs { display: flex; align-items: center; gap: var(--space-xs); margin-bottom: var(--space-xl); padding: 4px; background: var(--bg-tertiary); border-radius: var(--radius-full); position: relative; z-index: 2; animation: fadeIn 0.25s ease 0.04s both; }
.wrong-tab { padding: 8px 20px; border: none; background: none; color: var(--text-tertiary); font-size: 0.85rem; font-weight: 500; cursor: pointer; border-radius: var(--radius-full); transition: all 0.18s cubic-bezier(0.25,0.46,0.45,0.94); }
.wrong-tab:hover { color: var(--text-primary); background: var(--bg-hover); }
.wrong-tab.active { background: var(--accent); color: white; font-weight: 600; box-shadow: 0 4px 14px rgba(var(--accent-rgb), 0.35); }
.wrong-tab-green.active { background: #22c55e; color: white; font-weight: 600; box-shadow: 0 4px 14px rgba(34,197,94,0.35); }
.wrong-tab-clear { margin-left: auto !important; color: var(--text-tertiary) !important; display: flex; align-items: center; gap: 6px; }
.wrong-tab-clear:hover { color: #ef4444 !important; background: rgba(239,68,68,0.08) !important; }
.wrong-stats-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-md); margin-bottom: var(--space-xl); animation: fadeIn 0.3s ease both; }
.wrong-stat-card { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-md) var(--space-sm); text-align: center; transition: all 0.2s ease; }
.wrong-stat-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.wrong-stat-num { font-size: 1.5rem; font-weight: 800; color: var(--text-primary); line-height: 1.2; margin-bottom: 4px; }
.wrong-stat-label { font-size: 0.75rem; color: var(--text-tertiary); font-weight: 500; }
.wrong-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-md); margin-bottom: var(--space-xl); animation: fadeIn 0.3s ease 0.05s both; }
.wrong-search-wrap { position: relative; flex: 1; min-width: 200px; }
.wrong-search-icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--text-tertiary); pointer-events: none; }
.wrong-search-input { width: 100%; padding: 10px 12px 10px 36px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-full); font-size: 0.85rem; color: var(--text-primary); outline: none; transition: all 0.2s ease; }
.wrong-search-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.1); }
.wrong-search-input::placeholder { color: var(--text-tertiary); }
.wrong-filters, .wrong-group-tabs { display: flex; gap: var(--space-xs); }
.wrong-filter-btn, .wrong-group-btn { padding: 7px 14px; border: 1px solid var(--border); background: var(--bg-secondary); color: var(--text-secondary); border-radius: var(--radius-full); font-size: 0.8rem; font-weight: 500; cursor: pointer; transition: all 0.18s ease; }
.wrong-filter-btn:hover, .wrong-group-btn:hover { background: var(--bg-hover); color: var(--text-primary); }
.wrong-filter-btn.active, .wrong-group-btn.active { background: var(--accent); color: white; border-color: var(--accent); box-shadow: 0 2px 8px rgba(var(--accent-rgb), 0.25); }
.mastered-stats .wrong-stat-num { color: #22c55e; }
.mastered-stats .wrong-stat-card:hover { border-color: rgba(34,197,94,0.3); }
.wrong-clear-btn, .wrong-export-btn { display: flex; align-items: center; gap: 6px; padding: 7px 14px; border: 1px solid var(--border); background: var(--bg-secondary); color: var(--text-secondary); border-radius: var(--radius-full); font-size: 0.8rem; font-weight: 500; cursor: pointer; transition: all 0.18s ease; margin-left: auto; }
.wrong-clear-btn:hover { background: rgba(239,68,68,0.06); color: #ef4444; border-color: rgba(239,68,68,0.2); }
.wrong-export-btn { background: rgba(var(--accent-rgb), 0.06); color: var(--accent); border-color: rgba(var(--accent-rgb), 0.2); }
.wrong-export-btn:hover { background: rgba(var(--accent-rgb), 0.12); }
.wrong-group { margin-bottom: var(--space-lg); animation: fadeIn 0.25s ease both; }
.wrong-group-header { display: flex; align-items: center; gap: var(--space-sm); padding: 10px var(--space-md); margin-bottom: var(--space-md); cursor: pointer; user-select: none; border-radius: var(--radius-lg); background: rgba(var(--accent-rgb), 0.04); transition: background var(--transition-fast); }
.wrong-group-header:hover { background: rgba(var(--accent-rgb), 0.07); }
.wg-color-bar { width: 4px; height: 20px; border-radius: 2px; flex-shrink: 0; }
.wg-chevron { width: 16px; height: 16px; flex-shrink: 0; color: var(--text-tertiary); transition: transform 0.2s cubic-bezier(0.4,0,0.2,1); }
.wrong-group-header h3 { font-size: 0.95rem; font-weight: 700; color: var(--text-primary); flex: 1; }
.wg-count { font-size: 0.78rem; font-weight: 700; padding: 2px 10px; border-radius: var(--radius-full); opacity: 0.8; }
.wg-collapsed .wg-items { display: none; }
.wg-collapsed .wg-chevron { transform: rotate(-90deg); }
.wrong-item { padding: var(--space-lg); background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-xl); margin-bottom: var(--space-md); transition: all 0.2s cubic-bezier(0.23,1,0.32,1); cursor: pointer; overflow: hidden; position: relative; box-shadow: var(--shadow-sm); }
.wrong-item::before { content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1.5px; background: linear-gradient(135deg, transparent 30%, var(--border), transparent 70%); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; transition: opacity 0.2s ease; pointer-events: none; z-index: 2; }
.wrong-item:hover { transform: translateY(-3px); box-shadow: 0 12px 32px -8px rgba(0,0,0,0.06); border-color: var(--border-hover); }
.wrong-item:hover::before { opacity: 1; }
.wrong-item.expanded { transform: none; box-shadow: var(--shadow-lg); border-color: var(--border-hover); }
.wrong-item.expanded::before { opacity: 1; background: linear-gradient(135deg, var(--border-hover), transparent 80%); }
.wi-mastered { --wi-accent: #22c55e; }
.wi-mastered:hover { border-color: var(--border-hover); box-shadow: 0 12px 32px -8px rgba(0,0,0,0.06); }
.wi-mastered.expanded { border-color: #22c55e; }
.wi-mastered.expanded::before { background: linear-gradient(135deg, #22c55e, transparent 80%); }
.wi-top { display: flex; align-items: flex-start; gap: var(--space-md); position: relative; z-index: 1; }
.wi-pin { color: var(--warning); font-size: 1rem; line-height: 1.6; flex-shrink: 0; margin-top: 2px; }
.wi-chevron { width: 18px; height: 18px; flex-shrink: 0; color: var(--text-tertiary); transition: transform 0.2s cubic-bezier(0.4,0,0.2,1); margin-top: 4px; opacity: 0.5; }
.wrong-item.expanded .wi-chevron { transform: rotate(180deg); opacity: 1; }
.wrong-q { font-size: 1rem; line-height: 1.75; color: var(--text-primary); font-weight: 500; flex: 1; min-width: 0; }
.wrong-item .wrong-a { font-size: 0.88rem; color: var(--text-secondary); line-height: 1.7; display: none; padding-top: var(--space-md); border-top: 1px dashed var(--border); animation: fadeSlideIn 0.2s ease; }
.wrong-item.expanded .wrong-a { display: block; }
.wrong-e { font-size: 0.8rem; color: var(--text-tertiary); margin-top: 6px; display: none; }
.wrong-item.expanded .wrong-e { display: block; }
.wrong-item .wrong-meta { display: flex; align-items: center; gap: var(--space-md); font-size: 0.75rem; color: var(--text-tertiary); margin-top: var(--space-md); padding-top: var(--space-sm); }
.wm-time { opacity: 0.7; }
.wm-source { flex: 1; }
.wrong-item-actions { display: flex; gap: var(--space-xs); margin-left: auto; }
.wi-action-btn { padding: 5px 12px; border: 1px solid var(--border); border-radius: var(--radius-full); background: none; cursor: pointer; font-size: 0.75rem; font-weight: 500; color: var(--text-secondary); transition: all 0.15s ease; display: flex; align-items: center; gap: 4px; }
.wi-action-btn:hover { background: var(--bg-hover); color: var(--text-primary); }
.wi-btn-pin:hover { background: rgba(245,158,11,0.08) !important; color: #f59e0b !important; }
.wi-btn-del:hover { background: rgba(239,68,68,0.06) !important; color: #ef4444 !important; }
.wi-btn-unmaster:hover { background: rgba(34,197,94,0.06) !important; color: #22c55e !important; }
@keyframes fadeSlideIn { from { opacity: 0; transform: translateY(-2px); } to { opacity: 1; transform: translateY(0); } }

/* ===== 19. List Page (Wrong/Mastered shared) ===== */
.list-page { position: relative; min-height: calc(100vh - var(--nav-height) - var(--space-2xl)); padding: 0 var(--space-lg) var(--space-lg); max-width: 860px; margin: 0 auto; }
.list-stats { display: flex; gap: 12px; margin: var(--space-md) 0; flex-wrap: wrap; }
.list-stat { flex: 1; min-width: 100px; text-align: center; padding: 14px 8px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 12px; }
.list-stat__num { font-size: 1.4rem; font-weight: 700; color: var(--text-primary); line-height: 1.2; }
.list-stat__label { font-size: 0.72rem; color: var(--text-tertiary); margin-top: 2px; }
.list-toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: var(--space-md); flex-wrap: wrap; }
.list-search { position: relative; flex: 1; min-width: 180px; }
.list-search svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--text-tertiary); pointer-events: none; }
.list-search input { width: 100%; height: 38px; padding: 0 14px 0 36px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-secondary); color: var(--text-primary); font-size: 0.88rem; outline: none; transition: border-color 0.15s; }
.list-search input:focus { border-color: var(--accent); }
.list-search input::placeholder { color: var(--text-tertiary); }
.list-btn { height: 38px; padding: 0 14px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-secondary); color: var(--text-secondary); font-size: 0.82rem; cursor: pointer; transition: all 0.12s; white-space: nowrap; display: inline-flex; align-items: center; gap: 5px; }
.list-btn:hover { background: var(--bg-hover); color: var(--text-primary); }
.list-btn--active { background: var(--rd-blue-strong, var(--accent)); color: #fff; border-color: var(--rd-blue-strong, var(--accent)); font-weight: 600; }
.list-btn--active:hover { background: var(--accent-hover); color: #fff; }
.list-btn--danger { color: #ef4444; }
.list-btn--danger:hover { background: rgba(239,68,68,0.08); color: #ef4444; }
.list-btn--export { margin-left: auto; }
.list-content { display: flex; flex-direction: column; gap: var(--space-md); }
.list-group { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 14px; overflow: hidden; }
.list-group__header { display: flex; align-items: center; gap: 10px; padding: 12px 16px; cursor: pointer; user-select: none; transition: background 0.12s; }
.list-group__header:hover { background: var(--bg-hover); }
.list-group__bar { width: 3px; height: 20px; border-radius: 2px; flex-shrink: 0; }
.list-group__title { flex: 1; font-size: 0.9rem; font-weight: 600; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-group__count { font-size: 0.78rem; font-weight: 600; padding: 2px 10px; border-radius: 20px; flex-shrink: 0; }
.list-group__chevron { width: 18px; height: 18px; flex-shrink: 0; transition: transform 0.2s; }
.list-group--collapsed .list-group__items { display: none; }
.list-group--collapsed .list-group__chevron { transform: rotate(-90deg); }
.list-group__items { border-top: 1px solid var(--border); }
.list-item { padding: 14px 16px; cursor: pointer; border-bottom: 1px solid var(--border); transition: background 0.1s; }
.list-item:last-child { border-bottom: none; }
.list-item:hover { background: var(--bg-hover); }
.list-item__q { display: flex; align-items: flex-start; gap: 8px; font-size: 0.92rem; color: var(--text-primary); line-height: 1.55; }
.list-item__q .wi-pin { flex-shrink: 0; }
.list-item__chevron { flex-shrink: 0; width: 18px; height: 18px; margin-top: 2px; transition: transform 0.2s; }
.list-item--expanded .list-item__chevron { transform: rotate(180deg); }
.list-item__a { display: none; margin-top: 10px; padding: 10px 14px; background: var(--bg-active); border-radius: 8px; font-size: 0.88rem; color: var(--text-primary); line-height: 1.55; }
.list-item--expanded .list-item__a { display: block; }
.list-item__e { display: none; margin-top: 8px; padding: 10px 14px; font-size: 0.84rem; color: var(--text-secondary); line-height: 1.6; }
.list-item--expanded .list-item__e { display: block; }
.list-item__meta { display: flex; align-items: center; justify-content: space-between; margin-top: 8px; gap: 8px; }
.list-item__src { font-size: 0.74rem; color: var(--text-tertiary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-item__actions { display: flex; gap: 4px; flex-shrink: 0; }
.list-item__act { height: 28px; padding: 0 10px; border: 1px solid var(--border); border-radius: 7px; background: transparent; color: var(--text-tertiary); font-size: 0.73rem; cursor: pointer; transition: all 0.1s; display: inline-flex; align-items: center; gap: 3px; white-space: nowrap; }
.list-item__act:hover { border-color: var(--border-hover); color: var(--text-primary); }
.list-item__act--pin:hover { color: #f59e0b; border-color: rgba(245,158,11,0.3); }
.list-item__act--del:hover { color: #ef4444; border-color: rgba(239,68,68,0.3); }
.list-item__act--unmaster:hover { color: #ef4444; border-color: rgba(239,68,68,0.3); }
.list-page--mastered .list-stat__num { color: var(--rd-green-strong, #15803d); }
/* Mastered keeps its green semantics, but #22c55e only reached 2.28:1 against
   the white label — use the darker green fill. */
.list-page--mastered .list-btn--active { background: var(--rd-green-strong, #15803d); border-color: var(--rd-green-strong, #15803d); }
.list-page--mastered .list-btn--active:hover { background: color-mix(in srgb, var(--rd-green-strong, #15803d) 88%, #000); }
.list-page--wrong .list-stat__num { color: #c2410c; }

/* ===== 27c. Formula / Error Book / Math Practice Module Styles ===== */
.formula-list { display: flex; flex-direction: column; gap: 0; }
.formula-item-title { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.formula-item-title span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.formula-mastered-badge { font-size: 0.7rem; padding: 2px 8px; border-radius: var(--radius-full); background: var(--success, #22c55e); color: white; flex-shrink: 0; }
.formula-content { margin-bottom: 12px; }
.formula-example { padding: 12px; border-radius: var(--radius-md); background: var(--bg-hover); margin-bottom: 8px; }
.formula-actions { display: flex; gap: 8px; }

.mp-template-card { cursor: pointer; transition: all 0.15s ease; }
.mp-template-card.selected { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent); background: var(--accent-light); }
.mp-diff-btn { opacity: 0.7; transition: all 0.15s ease; }
.mp-diff-btn.active { opacity: 1; font-weight: 700; background: var(--accent); color: var(--text-inverse); border-color: transparent; box-shadow: 0 2px 8px rgba(var(--accent-rgb), 0.25); }

.eb-thumb { border-radius: 8px; cursor: pointer; }
.eb-formula-ref { cursor: pointer; }

/* Error-book toolbar: wraps on desktop, horizontal-scroll on phones so all actions stay reachable */
.eb-toolbar { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; padding: 0 var(--space-lg) var(--space-md); }
.eb-toolbar #eb-summary { font-size: var(--fs-sm); color: var(--text-tertiary); margin-left: auto; }
@media (max-width: 600px) {
  .eb-toolbar { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  .eb-toolbar::-webkit-scrollbar { display: none; }
  .eb-toolbar .btn { flex-shrink: 0; }
  .eb-toolbar #eb-summary { display: none; }
}

/* ==== pages/codex-error-book.css ==== */
.ceb-page {
  max-width: 1180px;
  margin: 0 auto;
  padding: 28px 24px 56px;
  color: var(--text-primary, #172033);
}

.ceb-page-head {
  display: flex;
  align-items: flex-start;
  gap: 18px;
  margin-bottom: 24px;
}

.ceb-page-head h1, .ceb-group-head h2, .ceb-modal-dialog h2, .ceb-print-title h1 {
  margin: 0;
  letter-spacing: 0;
}

.ceb-page-head h1 { font-size: clamp(1.7rem, 3vw, 2.25rem); }
.ceb-page-head p { margin: 8px 0 0; color: var(--text-secondary, #667085); }
.ceb-eyebrow { margin-bottom: 7px; color: #b45309; font-size: .68rem; font-weight: 800; letter-spacing: .12em; }

.ceb-back-btn, .ceb-icon-btn, .ceb-modal-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border, #d9dee8);
  border-radius: 6px;
  background: var(--bg-card, #fff);
  color: inherit;
  cursor: pointer;
}

.ceb-back-btn { width: 38px; height: 38px; flex: 0 0 38px; text-decoration: none; }
.ceb-back-btn svg, .ceb-icon-btn svg, .ceb-modal-close svg, .ceb-action-btn svg, .ceb-main-btn svg, .ceb-toolbar-btn svg { width: 17px; height: 17px; }
.ceb-back-btn:hover, .ceb-icon-btn:hover, .ceb-modal-close:hover { border-color: #c2410c; color: #c2410c; }

.ceb-workflow {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  margin-bottom: 18px;
  border: 1px solid #eadfd1;
  background: #eadfd1;
}

.ceb-workflow-copy {
  display: flex;
  gap: 11px;
  min-width: 0;
  padding: 16px;
  background: #fffaf5;
}

.ceb-workflow-copy strong { display: block; font-size: .9rem; }
.ceb-workflow-copy p { margin: 5px 0 0; color: #756b61; font-size: .77rem; line-height: 1.55; }
.ceb-workflow-step {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
  border-radius: 50%;
  background: #c2410c;
  color: #fff;
  font-size: .72rem;
  font-weight: 800;
}

.ceb-toolbar {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  padding: 12px;
  border: 1px solid var(--border, #d9dee8);
  background: var(--bg-card, #fff);
}

.ceb-main-btn, .ceb-toolbar-btn, .ceb-action-btn, .ceb-filter-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 34px;
  border: 1px solid var(--border, #d9dee8);
  border-radius: 5px;
  padding: 7px 11px;
  background: var(--bg-card, #fff);
  color: var(--text-primary, #172033);
  cursor: pointer;
  font: inherit;
  font-size: .79rem;
}

.ceb-main-btn { border-color: #b45309; background: #b45309; color: #fff; font-weight: 700; }
.ceb-main-btn:hover { background: #92400e; }
.ceb-inline-link { width: fit-content; text-decoration: none; }
.ceb-toolbar-btn:hover, .ceb-action-btn:hover { border-color: #b45309; color: #92400e; }
.ceb-action-btn--primary { border-color: #b45309; color: #92400e; }
.ceb-action-btn--danger, .ceb-icon-btn--danger { color: #b42318; }
.ceb-action-btn--danger:hover, .ceb-icon-btn--danger:hover { border-color: #b42318; color: #b42318; }

.ceb-search {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 220px;
  flex: 1 1 240px;
  height: 34px;
  padding: 0 10px;
  border: 1px solid var(--border, #d9dee8);
  border-radius: 5px;
  color: var(--text-tertiary, #98a2b3);
}

.ceb-search svg { width: 16px; height: 16px; flex: 0 0 16px; }
.ceb-search input { width: 100%; border: 0; outline: 0; background: transparent; color: inherit; font: inherit; font-size: .79rem; }
.ceb-filter { display: flex; gap: 4px; flex-wrap: wrap; }
.ceb-filter-btn { min-height: 30px; padding: 5px 9px; color: var(--text-secondary, #667085); font-size: .74rem; }
.ceb-filter-btn span { min-width: 16px; color: var(--text-tertiary, #98a2b3); }
.ceb-filter-btn.is-active { border-color: #b45309; background: #fff7ed; color: #9a3412; font-weight: 700; }

.ceb-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 9px;
  margin: 14px 0 26px;
}

.ceb-stats > div { padding: 12px 14px; border-left: 3px solid #b45309; background: #f8fafc; }
.ceb-stats > div:nth-child(2) { border-left-color: #d97706; }
.ceb-stats > div:nth-child(3) { border-left-color: #15803d; }
.ceb-stats > div:nth-child(4) { border-left-color: #64748b; }
.ceb-stats strong { display: block; font-size: 1.3rem; line-height: 1; }
.ceb-stats span { display: block; margin-top: 5px; color: var(--text-secondary, #667085); font-size: .72rem; }

.ceb-group-list { display: flex; flex-direction: column; gap: 20px; }
.ceb-group-list--index { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; }
.ceb-group-card {
  display: flex;
  min-width: 0;
  min-height: 156px;
  flex-direction: column;
  border: 1px solid var(--border, #d9dee8);
  border-radius: 7px;
  background: var(--bg-card, #fff);
  transition: border-color .16s ease, box-shadow .16s ease, transform .16s ease;
}
.ceb-group-card:hover { border-color: #d58a49; box-shadow: 0 8px 20px rgba(146, 64, 14, .08); transform: translateY(-1px); }
.ceb-group-link { display: block; min-width: 0; flex: 1; padding: 16px; color: inherit; text-decoration: none; }
.ceb-group-card-title { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 7px; }
.ceb-group-card-title h2 { min-width: 0; margin: 0; overflow-wrap: anywhere; font-size: 1.02rem; letter-spacing: 0; }
.ceb-group-card-title svg { width: 18px; height: 18px; flex: 0 0 18px; color: #b45309; }
.ceb-group-link p { margin: 9px 0 0; color: var(--text-secondary, #667085); font-size: .76rem; }
.ceb-group-card-actions { display: flex; justify-content: flex-end; gap: 5px; padding: 8px 10px; border-top: 1px solid var(--border, #d9dee8); }
.ceb-group { border-top: 2px solid #d6dbe4; }
.ceb-group--detail { border-top: 0; }
.ceb-group-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 16px 2px 12px; }
.ceb-group-kicker { color: #b45309; font-size: .72rem; font-weight: 700; }
.ceb-group-head h2 { margin-top: 4px; font-size: 1.08rem; }
.ceb-group-head p { margin: 6px 0 0; color: var(--text-secondary, #667085); font-size: .75rem; }
.ceb-group-actions { display: flex; justify-content: flex-end; gap: 6px; flex-wrap: wrap; }
.ceb-action-btn { min-height: 30px; padding: 5px 8px; font-size: .72rem; }
.ceb-pin { display: inline-block; margin-left: 5px; padding: 2px 6px; border-radius: 3px; background: #fff7ed; color: #c2410c; font-size: .66rem; vertical-align: middle; }
.ceb-question-list { display: flex; flex-direction: column; gap: 7px; }

.ceb-question { border: 1px solid var(--border, #d9dee8); border-radius: 5px; background: var(--bg-card, #fff); }
.ceb-question-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 9px; border-bottom: 1px solid #edf0f4; background: #fbfcfd; }
.ceb-question-head > div:first-child { display: flex; align-items: center; gap: 7px; }
.ceb-question-number { display: inline-grid; place-items: center; width: 21px; height: 21px; border-radius: 3px; background: #f5f5f4; color: #57534e; font-size: .68rem; font-weight: 700; }
.ceb-question-actions { display: flex; gap: 5px; }
.ceb-icon-btn { width: 27px; height: 27px; padding: 5px; }
.ceb-status, .ceb-mastery { display: inline-block; padding: 2px 6px; border-radius: 3px; font-size: .63rem; font-weight: 700; }
.ceb-status--correct { background: #edf7f0; color: #28724a; }
.ceb-status--wrong { background: #faeeee; color: #9f3a3a; }
.ceb-status--unknown { background: #f1f5f9; color: #64748b; }
.ceb-mastery--unmastered { background: #fff7ed; color: #c2410c; }
.ceb-mastery--mastered { background: #ecfdf3; color: #15803d; }
.ceb-question-body { padding: 10px 12px 9px; line-height: 1.5; }
.ceb-question-type { margin-bottom: 4px; color: #8a94a3; font-size: .64rem; font-weight: 600; }
.ceb-stem { font-size: .9rem; }
.ceb-stem > :first-child { margin-top: 0; }
.ceb-stem > :last-child { margin-bottom: 0; }
.ceb-rich-text { min-width: 0; max-width: 100%; overflow-wrap: anywhere; line-height: 1.55; }
.ceb-rich-text > * { max-width: 100%; }
.ceb-rich-text p { margin: .45em 0; }
.ceb-rich-text p:first-child { margin-top: 0; }
.ceb-rich-text p:last-child { margin-bottom: 0; }
.ceb-rich-text h1, .ceb-rich-text h2, .ceb-rich-text h3,
.ceb-rich-text h4, .ceb-rich-text h5, .ceb-rich-text h6 { margin: .65em 0 .3em; line-height: 1.35; color: var(--text-primary, #172033); }
.ceb-rich-text h1 { font-size: 1.2em; }
.ceb-rich-text h2 { font-size: 1.1em; }
.ceb-rich-text h3 { font-size: 1em; }
.ceb-rich-text h4, .ceb-rich-text h5, .ceb-rich-text h6 { font-size: .92em; }
.ceb-rich-text ul, .ceb-rich-text ol { margin: .4em 0; padding-left: 1.4em; }
.ceb-rich-text li + li { margin-top: .18em; }
.ceb-rich-text blockquote { margin: .5em 0; padding: .35em .7em; border-left: 3px solid #d5dbe5; background: #fafbfc; color: #667085; }
.ceb-rich-text hr { margin: .65em 0; border: 0; border-top: 1px solid #d9dee8; }
.ceb-rich-text a { color: #9a3412; text-decoration: underline; text-underline-offset: 2px; }
.ceb-rich-text code { padding: .08em .28em; border-radius: 3px; background: #f1f5f9; color: #475467; font-family: Consolas, "Microsoft YaHei", monospace; font-size: .9em; }
.ceb-rich-text pre { max-width: 100%; overflow: auto; margin: .5em 0; padding: 7px 9px; background: #f8fafc; white-space: pre; }
.ceb-rich-text pre code { padding: 0; background: transparent; }
.ceb-rich-text table { width: 100%; margin: 6px 0; border-collapse: collapse; font-size: .78rem; }
.ceb-rich-text th, .ceb-rich-text td { max-width: 32em; padding: 4px 6px; border: 1px solid #cfd6e1; text-align: left; vertical-align: top; overflow-wrap: anywhere; }
.ceb-rich-text th { background: #f8fafc; font-weight: 700; }
.ceb-rich-text img, .ceb-rich-text .md-image { display: block; width: auto; max-width: 100%; height: auto; margin: .45em auto; object-fit: contain; }
.ceb-rich-text .katex-display { max-width: 100%; margin: .4em 0; overflow-x: auto; overflow-y: hidden; padding: 2px 0; }
.ceb-rich-text .katex { max-width: 100%; }
.ceb-options { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
.ceb-option { padding: 6px 8px 5px; border: 1px solid #e5e7eb; border-left: 2px solid #d1d5db; border-radius: 3px; }
.ceb-option--correct { border-color: #bdd9c7; border-left-color: #4d8a66; background: #f8fbf9; }
.ceb-option--wrong { border-color: #e2c1c1; border-left-color: #b65c5c; background: #fcf9f9; }
.ceb-option-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ceb-option-label { font-size: .82rem; font-weight: 700; }
.ceb-option-flags { display: flex; gap: 4px; flex-wrap: wrap; }
.ceb-mark { padding: 1px 4px; border: 1px solid currentColor; border-radius: 2px; background: transparent; font-size: .59rem; font-weight: 700; opacity: .82; }
.ceb-mark--correct { color: #28724a; }
.ceb-mark--wrong { color: #9f3a3a; }
.ceb-option-text { margin-top: 2px; font-size: .86rem; }
.ceb-option-analysis, .ceb-option-tip { display: flex; align-items: flex-start; gap: 6px; margin-top: 3px; padding: 0; border: 0; background: transparent; color: #667085; font-size: .71rem; line-height: 1.42; }
.ceb-option-tip { margin-top: 1px; color: #858b95; }
.ceb-option-analysis > span, .ceb-option-tip > span, .ceb-reference > span { display: inline-block; flex: 0 0 auto; margin: 0; color: #8a94a3; font-size: .6rem; font-weight: 700; line-height: 1.7; }
.ceb-option-analysis > .ceb-rich-text, .ceb-option-tip > .ceb-rich-text { min-width: 0; flex: 1 1 auto; }
.ceb-analysis, .ceb-notes, .ceb-reference { margin-top: 8px; padding: 7px 8px 0; border-top: 1px solid #e8ecf2; color: #667085; font-size: .75rem; line-height: 1.48; }
.ceb-analysis h4, .ceb-notes h4 { margin: 0 0 3px; color: #667085; font-size: .68rem; }
.ceb-notes { background: transparent; }
.ceb-notes ul { margin: 0; padding-left: 1.2em; }
.ceb-reference { background: transparent; }
.ceb-tags { display: flex; gap: 4px; flex-wrap: wrap; padding: 0 12px 8px; }
.ceb-tags span { padding: 2px 5px; border-radius: 2px; background: #f4f5f6; color: #7b8491; font-size: .61rem; }
.ceb-pending { padding: 9px; border: 1px dashed #cbd5e1; background: #f8fafc; }
.ceb-pending strong { display: block; margin-bottom: 4px; font-size: .75rem; }
.ceb-pending p, .ceb-no-questions, .ceb-loading { color: var(--text-secondary, #667085); font-size: .78rem; }
.ceb-empty { padding: 64px 20px; text-align: center; color: var(--text-secondary, #667085); }
.ceb-empty-icon { width: 42px; margin: 0 auto 12px; opacity: .35; }
.ceb-empty-icon svg { width: 42px; height: 42px; }
.ceb-empty h2 { margin: 0; color: var(--text-primary, #172033); font-size: 1.05rem; }
.ceb-empty p { margin: 8px 0 0; font-size: .8rem; }

.ceb-modal { position: fixed; z-index: 1000; inset: 0; display: grid; place-items: center; padding: 20px; background: rgba(15, 23, 42, .48); }
.ceb-modal-dialog { width: min(560px, 100%); max-height: min(780px, 92vh); overflow-y: auto; border-radius: 8px; background: var(--bg-card, #fff); box-shadow: 0 18px 60px rgba(15, 23, 42, .24); }
.ceb-modal-dialog--wide { width: min(780px, 100%); }
.ceb-modal-dialog > header { display: flex; align-items: flex-start; justify-content: space-between; gap: 15px; padding: 18px 20px 12px; border-bottom: 1px solid #edf0f4; }
.ceb-modal-dialog > header p { margin: 5px 0 0; color: var(--text-secondary, #667085); font-size: .75rem; }
.ceb-modal-dialog h2 { font-size: 1.05rem; }
.ceb-modal-close { width: 30px; height: 30px; padding: 6px; }
.ceb-modal-body { display: flex; flex-direction: column; gap: 13px; padding: 18px 20px; }
.ceb-modal-body label { display: flex; flex-direction: column; gap: 6px; color: #344054; font-size: .76rem; font-weight: 700; }
.ceb-modal-body input, .ceb-modal-body textarea, .ceb-modal-body select { width: 100%; box-sizing: border-box; border: 1px solid #cfd6e1; border-radius: 5px; padding: 9px 10px; outline: 0; background: #fff; color: #172033; font: inherit; font-size: .82rem; font-weight: 400; }
.ceb-modal-body input:focus, .ceb-modal-body textarea:focus, .ceb-modal-body select:focus { border-color: #b45309; box-shadow: 0 0 0 3px #fff7ed; }
.ceb-modal-body textarea { min-height: 110px; resize: vertical; line-height: 1.5; }
.ceb-form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px; }
.ceb-form-inline { display: flex; gap: 7px; flex-wrap: wrap; }
.ceb-checkbox { flex-direction: row !important; align-items: center; font-weight: 400 !important; }
.ceb-checkbox input { width: auto; }
.ceb-modal-dialog > footer { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 20px 18px; border-top: 1px solid #edf0f4; }

#ceb-print-root { display: none; }

.um-page { max-width: 1180px; margin: 0 auto; padding: 28px 24px 56px; color: var(--text-primary, #172033); }
.um-head { display: flex; align-items: flex-start; gap: 18px; margin-bottom: 24px; }
.um-head h1 { margin: 0; font-size: clamp(1.7rem, 3vw, 2.25rem); }
.um-head p { margin: 8px 0 0; color: var(--text-secondary, #667085); }
.um-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 9px; margin-bottom: 14px; }
.um-stats > div { padding: 13px 15px; border-left: 3px solid #c2410c; background: #fff7ed; }
.um-stats > div:nth-child(2) { border-left-color: #64748b; background: #f8fafc; }
.um-stats > div:nth-child(3) { border-left-color: #d97706; background: #fffbeb; }
.um-stats strong { display: block; font-size: 1.35rem; line-height: 1; }
.um-stats span { display: block; margin-top: 5px; color: #667085; font-size: .72rem; }
.um-toolbar { display: flex; align-items: center; gap: 9px; margin-bottom: 22px; padding: 12px; border: 1px solid var(--border, #d9dee8); background: #fff; }
.um-group-switch { display: flex; gap: 4px; }
.um-group-switch button { min-height: 30px; padding: 5px 9px; border: 1px solid #d9dee8; border-radius: 5px; background: #fff; color: #667085; cursor: pointer; font: inherit; font-size: .74rem; }
.um-group-switch button.is-active { border-color: #b45309; background: #fff7ed; color: #9a3412; font-weight: 700; }
.um-list { display: flex; flex-direction: column; gap: 20px; }
.um-group { border-top: 2px solid #d6dbe4; }
.um-group > header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 2px 10px; }
.um-group > header span { color: #b45309; font-size: .68rem; font-weight: 800; }
.um-group > header h2 { margin: 3px 0 0; font-size: 1rem; }
.um-mark-group, .um-mark-btn { display: inline-flex; align-items: center; gap: 5px; border: 1px solid #d9dee8; border-radius: 5px; padding: 6px 8px; background: #fff; color: #15803d; cursor: pointer; font: inherit; font-size: .72rem; }
.um-mark-group svg, .um-mark-btn svg { width: 15px; height: 15px; }
.um-mark-group:hover, .um-mark-btn:hover { border-color: #15803d; background: #f0fdf4; }
.um-item { border: 1px solid #d9dee8; border-radius: 7px; background: #fff; }
.um-item + .um-item { margin-top: 8px; }
.um-item > header { display: flex; align-items: center; gap: 7px; padding: 8px 11px; border-bottom: 1px solid #edf0f4; background: #fbfcfd; }
.um-number { display: inline-grid; place-items: center; width: 23px; height: 23px; border-radius: 4px; background: #fff7ed; color: #9a3412; font-size: .7rem; font-weight: 800; }
.um-status { padding: 3px 6px; border-radius: 3px; background: #fff7ed; color: #c2410c; font-size: .65rem; font-weight: 700; }
.um-mark-btn { margin-left: auto; }
.um-item-body { padding: 12px 14px 9px; line-height: 1.58; font-size: .86rem; }
.um-stem { font-size: .9rem; }
.um-options { display: flex; flex-direction: column; gap: 5px; margin-top: 9px; }
.um-options > div { padding: 5px 7px; border-left: 2px solid #cbd5e1; background: #f8fafc; }
.um-options strong { display: inline-block; min-width: 22px; }
.um-options small { display: block; margin: 3px 0 0 22px; color: #667085; }
.um-analysis { margin-top: 9px; padding: 7px 9px; border-left: 2px solid #94a3b8; background: #f8fafc; }
.um-analysis b { margin-right: 6px; color: #475467; font-size: .7rem; }
.um-pending { margin: 7px 0 0; color: #b45309; font-size: .74rem; }
.um-tags { display: flex; flex-wrap: wrap; gap: 5px; padding: 0 14px 10px; }
.um-tags span { padding: 3px 7px; border-radius: 3px; background: #f1f5f9; color: #64748b; font-size: .65rem; }
.um-empty { padding: 58px 20px; text-align: center; color: #667085; }
.um-empty h2 { margin: 0; color: #172033; font-size: 1.05rem; }
.um-empty p { margin: 8px 0 0; font-size: .78rem; }

[data-theme="dark"] .ceb-page,
[data-theme="dark"] .um-page {
  color: var(--text-primary);
}

[data-theme="dark"] .ceb-eyebrow,
[data-theme="dark"] .ceb-group-kicker,
[data-theme="dark"] .um-group > header span,
[data-theme="dark"] .um-pending {
  color: #e2a35f;
}

[data-theme="dark"] .ceb-back-btn,
[data-theme="dark"] .ceb-icon-btn,
[data-theme="dark"] .ceb-modal-close,
[data-theme="dark"] .ceb-toolbar,
[data-theme="dark"] .ceb-toolbar-btn,
[data-theme="dark"] .ceb-action-btn,
[data-theme="dark"] .ceb-filter-btn,
[data-theme="dark"] .ceb-group-card,
[data-theme="dark"] .ceb-question,
[data-theme="dark"] .um-toolbar,
[data-theme="dark"] .um-group-switch button,
[data-theme="dark"] .um-mark-group,
[data-theme="dark"] .um-mark-btn,
[data-theme="dark"] .um-item {
  border-color: var(--border);
  background: var(--surface);
  color: var(--text-primary);
}

[data-theme="dark"] .ceb-workflow {
  border-color: rgba(226, 163, 95, .22);
  background: rgba(226, 163, 95, .22);
}

[data-theme="dark"] .ceb-workflow-copy {
  background: #151311;
}

[data-theme="dark"] .ceb-workflow-copy p,
[data-theme="dark"] .ceb-page-head p,
[data-theme="dark"] .ceb-group-head p,
[data-theme="dark"] .ceb-modal-dialog > header p,
[data-theme="dark"] .um-head p,
[data-theme="dark"] .um-stats span,
[data-theme="dark"] .um-options small,
[data-theme="dark"] .um-empty {
  color: var(--text-secondary);
}

[data-theme="dark"] .ceb-workflow-step,
[data-theme="dark"] .ceb-main-btn {
  /* #b96125 left white text at 4.38:1 — just under AA. */
  border-color: #ab571f;
  background: #ab571f;
  color: #fff;
}

[data-theme="dark"] .ceb-main-btn:hover {
  background: #c26a2c;
}

[data-theme="dark"] .ceb-back-btn:hover,
[data-theme="dark"] .ceb-icon-btn:hover,
[data-theme="dark"] .ceb-modal-close:hover,
[data-theme="dark"] .ceb-toolbar-btn:hover,
[data-theme="dark"] .ceb-action-btn:hover,
[data-theme="dark"] .ceb-action-btn--primary {
  border-color: #e2a35f;
  color: #e2a35f;
}

[data-theme="dark"] .ceb-action-btn--danger,
[data-theme="dark"] .ceb-icon-btn--danger,
[data-theme="dark"] .ceb-action-btn--danger:hover,
[data-theme="dark"] .ceb-icon-btn--danger:hover {
  color: #ff8585;
  border-color: rgba(255, 133, 133, .5);
}

[data-theme="dark"] .ceb-search {
  border-color: var(--border);
  color: var(--text-tertiary);
}

[data-theme="dark"] .ceb-search input {
  color: var(--text-primary);
}

[data-theme="dark"] .ceb-search input::placeholder,
[data-theme="dark"] .ceb-modal-body input::placeholder,
[data-theme="dark"] .ceb-modal-body textarea::placeholder {
  color: var(--text-tertiary);
  opacity: 1;
}

[data-theme="dark"] .ceb-filter-btn,
[data-theme="dark"] .ceb-filter-btn span,
[data-theme="dark"] .ceb-question-type,
[data-theme="dark"] .ceb-option-analysis > span,
[data-theme="dark"] .ceb-reference > span,
[data-theme="dark"] .ceb-pending p,
[data-theme="dark"] .ceb-no-questions,
[data-theme="dark"] .ceb-loading {
  color: var(--text-secondary);
}

[data-theme="dark"] .ceb-filter-btn.is-active,
[data-theme="dark"] .um-group-switch button.is-active {
  border-color: #d58a49;
  background: rgba(226, 163, 95, .14);
  color: #f0b879;
}

[data-theme="dark"] .ceb-stats > div,
[data-theme="dark"] .um-stats > div,
[data-theme="dark"] .um-stats > div:nth-child(2),
[data-theme="dark"] .um-stats > div:nth-child(3) {
  background: var(--bg-tertiary);
}

[data-theme="dark"] .ceb-group,
[data-theme="dark"] .um-group {
  border-top-color: var(--border-hover);
}

[data-theme="dark"] .ceb-group-card:hover {
  border-color: #d58a49;
  box-shadow: 0 8px 20px rgba(0, 0, 0, .2);
}

[data-theme="dark"] .ceb-group-card-actions {
  border-top-color: var(--border);
}

[data-theme="dark"] .ceb-pin,
[data-theme="dark"] .ceb-question-number,
[data-theme="dark"] .ceb-mastery--unmastered,
[data-theme="dark"] .um-number,
[data-theme="dark"] .um-status {
  background: rgba(226, 163, 95, .14);
  color: #f0b879;
}

[data-theme="dark"] .ceb-question-head,
[data-theme="dark"] .um-item > header {
  border-bottom-color: var(--border);
  background: var(--bg-tertiary);
}

[data-theme="dark"] .ceb-status--correct,
[data-theme="dark"] .ceb-mastery--mastered {
  background: rgba(76, 183, 130, .14);
  color: #73d6a5;
}

[data-theme="dark"] .ceb-status--wrong {
  background: rgba(235, 87, 87, .14);
  color: #ff8585;
}

[data-theme="dark"] .ceb-status--unknown {
  background: rgba(154, 156, 163, .12);
  color: #b7bac1;
}

[data-theme="dark"] .ceb-rich-text th,
[data-theme="dark"] .ceb-rich-text td {
  border-color: var(--border-hover);
}

[data-theme="dark"] .ceb-rich-text th,
[data-theme="dark"] .ceb-rich-text pre,
[data-theme="dark"] .ceb-rich-text code,
[data-theme="dark"] .ceb-rich-text blockquote,
[data-theme="dark"] .ceb-pending,
[data-theme="dark"] .um-options > div,
[data-theme="dark"] .um-analysis {
  background: var(--bg-tertiary);
}

[data-theme="dark"] .ceb-rich-text h1,
[data-theme="dark"] .ceb-rich-text h2,
[data-theme="dark"] .ceb-rich-text h3,
[data-theme="dark"] .ceb-rich-text h4,
[data-theme="dark"] .ceb-rich-text h5,
[data-theme="dark"] .ceb-rich-text h6 {
  color: var(--text-primary);
}

[data-theme="dark"] .ceb-rich-text blockquote {
  border-left-color: var(--border-hover);
  color: var(--text-secondary);
}

[data-theme="dark"] .ceb-rich-text hr {
  border-top-color: var(--border);
}

[data-theme="dark"] .ceb-rich-text a {
  color: #f0b879;
}

[data-theme="dark"] .ceb-rich-text code {
  color: var(--text-secondary);
}

[data-theme="dark"] .ceb-option {
  border-color: var(--border);
  border-left-color: var(--border-hover);
}

[data-theme="dark"] .ceb-option--correct {
  border-color: rgba(115, 176, 143, .32);
  border-left-color: #5e9a78;
  background: rgba(76, 183, 130, .045);
}

[data-theme="dark"] .ceb-option--wrong {
  border-color: rgba(199, 111, 111, .32);
  border-left-color: #b86a6a;
  background: rgba(235, 87, 87, .045);
}

[data-theme="dark"] .ceb-mark--correct {
  background: transparent;
  color: #79bd99;
}

[data-theme="dark"] .ceb-mark--wrong {
  background: transparent;
  color: #d98b8b;
}

[data-theme="dark"] .ceb-option-analysis,
[data-theme="dark"] .ceb-option-tip,
[data-theme="dark"] .ceb-analysis,
[data-theme="dark"] .ceb-notes,
[data-theme="dark"] .ceb-reference {
  background: transparent;
  color: var(--text-secondary);
}

[data-theme="dark"] .ceb-option-analysis > span,
[data-theme="dark"] .ceb-option-tip > span,
[data-theme="dark"] .ceb-reference > span {
  color: var(--text-tertiary);
}

[data-theme="dark"] .ceb-analysis,
[data-theme="dark"] .ceb-notes,
[data-theme="dark"] .ceb-reference {
  border-top-color: var(--border);
}

[data-theme="dark"] .ceb-analysis h4,
[data-theme="dark"] .ceb-notes h4,
[data-theme="dark"] .um-analysis b,
[data-theme="dark"] .um-empty h2 {
  color: var(--text-primary);
}

[data-theme="dark"] .ceb-tags span,
[data-theme="dark"] .um-tags span {
  background: var(--bg-active);
  color: var(--text-secondary);
}

[data-theme="dark"] .ceb-modal {
  background: rgba(0, 0, 0, .7);
}

[data-theme="dark"] .ceb-modal-dialog {
  border: 1px solid var(--border-hover);
  background: var(--surface-strong);
  color: var(--text-primary);
  box-shadow: 0 22px 70px rgba(0, 0, 0, .58);
}

[data-theme="dark"] .ceb-modal-dialog > header,
[data-theme="dark"] .ceb-modal-dialog > footer {
  border-color: var(--border);
}

[data-theme="dark"] .ceb-modal-body label {
  color: var(--text-secondary);
}

[data-theme="dark"] .ceb-modal-body input,
[data-theme="dark"] .ceb-modal-body textarea,
[data-theme="dark"] .ceb-modal-body select {
  border-color: var(--border-hover);
  background: var(--bg-primary);
  color: var(--text-primary);
}

[data-theme="dark"] .ceb-modal-body input:focus,
[data-theme="dark"] .ceb-modal-body textarea:focus,
[data-theme="dark"] .ceb-modal-body select:focus {
  border-color: #d58a49;
  box-shadow: 0 0 0 3px rgba(226, 163, 95, .14);
}

[data-theme="dark"] .um-mark-group,
[data-theme="dark"] .um-mark-btn {
  color: #73d6a5;
}

[data-theme="dark"] .um-mark-group:hover,
[data-theme="dark"] .um-mark-btn:hover {
  border-color: #4cb782;
  background: rgba(76, 183, 130, .1);
}

[data-theme="dark"] .um-options > div,
[data-theme="dark"] .um-analysis {
  border-left-color: var(--border-hover);
}

@media (max-width: 760px) {
  .ceb-page { padding: 20px 12px 40px; }
  .ceb-workflow { grid-template-columns: 1fr; }
  .ceb-toolbar { align-items: stretch; }
  .ceb-main-btn, .ceb-toolbar-btn { flex: 1 1 auto; }
  .ceb-search { flex-basis: 100%; }
  .ceb-filter { width: 100%; }
  .ceb-filter-btn { flex: 1 1 auto; }
  .ceb-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ceb-group-list--index { grid-template-columns: 1fr; }
  .ceb-group-head { flex-direction: column; }
  .ceb-group-actions { justify-content: flex-start; }
  .ceb-form-grid { grid-template-columns: 1fr; }
  .ceb-question-head { align-items: flex-start; }
  .ceb-question-head > div:first-child { flex-wrap: wrap; }
  .um-page { padding: 20px 12px 40px; }
  .um-toolbar { align-items: stretch; flex-direction: column; }
  .um-group-switch button { flex: 1; }
  .um-group-switch { width: 100%; }
  .um-stats { grid-template-columns: 1fr; }
  .um-group > header { align-items: flex-start; }
}

@media print {
  @page { margin: 10mm; }
  body:has(#ceb-print-root) { min-height: 0; background: #fff !important; }
  body:has(#ceb-print-root) > :not(#ceb-print-root) { display: none !important; }
  #ceb-print-root { display: block !important; color: #111827; font-family: "Microsoft YaHei", Arial, sans-serif; font-size: 9pt; }
  .ceb-print-title { padding-bottom: 7px; border-bottom: 1px solid #111827; }
  .ceb-print-title h1 { font-size: 17pt; }
  .ceb-print-title p { margin: 3px 0 0; color: #4b5563; font-size: 8pt; }
  .ceb-print-group { break-before: auto; page-break-before: auto; }
  .ceb-print-group > header { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 9px 0 5px; padding-bottom: 3px; border-bottom: 1px solid #9ca3af; }
  .ceb-print-group > header h2 { font-size: 12pt; }
  .ceb-print-group > header p { margin: 0; color: #4b5563; font-size: 8pt; }
  #ceb-print-root .ceb-question { break-inside: auto; page-break-inside: auto; margin-bottom: 4px; border-color: #b7bcc5; border-radius: 0; background: #fff; color: #111827; }
  #ceb-print-root .ceb-question-head { break-after: avoid; page-break-after: avoid; padding: 3px 6px; border-bottom-color: #d1d5db; background: #fafafa; }
  #ceb-print-root .ceb-question-body { padding: 4px 6px; background: #fff; color: #111827; line-height: 1.36; }
  #ceb-print-root .ceb-question-number { width: 18px; height: 18px; background: #e5e7eb; color: #111827; }
  #ceb-print-root .ceb-status, #ceb-print-root .ceb-mastery { padding: 1px 4px; border: 1px solid #9ca3af; background: #fff; color: #111827; }
  #ceb-print-root .ceb-option, #ceb-print-root .ceb-reference { break-inside: avoid; page-break-inside: avoid; }
  #ceb-print-root .ceb-options { gap: 2px; margin-top: 4px; }
  #ceb-print-root .ceb-option { margin-top: 0; padding: 3px 5px; border-color: #c7cbd2; border-left-width: 2px; background: #fff; color: #111827; }
  #ceb-print-root .ceb-option--correct { border-color: #6b9b7d; background: #fbfdfb; }
  #ceb-print-root .ceb-option--wrong { border-color: #b97878; background: #fdfbfb; }
  #ceb-print-root .ceb-mark { padding: 1px 3px; }
  #ceb-print-root .ceb-option-analysis, #ceb-print-root .ceb-option-tip { margin-top: 1px; padding: 0; background: transparent; color: #4b5563; font-size: 7.5pt; }
  #ceb-print-root .ceb-analysis, #ceb-print-root .ceb-notes, #ceb-print-root .ceb-reference { margin-top: 4px; padding: 3px 4px 0; background: transparent; color: #374151; font-size: 8pt; }
  #ceb-print-root .ceb-rich-text table { margin: 4px 0; font-size: 8.5pt; }
  #ceb-print-root .ceb-rich-text th, #ceb-print-root .ceb-rich-text td { padding: 3px 5px; }
  #ceb-print-root .md-image { display: block; width: auto; max-width: 100%; max-height: 140mm; margin: 3px auto; object-fit: contain; }
  #ceb-print-root .ceb-tags { display: none; }
  #ceb-print-root .ceb-icon-btn, #ceb-print-root .ceb-question-actions { display: none !important; }
  .katex-display { margin: 4px 0; overflow: visible; }
  .katex { font-size: 1em; }
  .um-page { display: none !important; }
}
/* ==== pages/overview.css ==== */
/* ============================================
   Overview / Print / Sidebar / Editor (.ov-* .fullscreen-* .editor-*)
   Extracted from main.css. Load order matters (see index.html).
   ============================================ */

/* ===== 20. Overview / Print ===== */
.overview-page { display: flex; flex-direction: column; height: calc(100dvh - var(--nav-height) - var(--space-xl) - var(--space-2xl)); }
.ov-container { flex: 1; display: flex; overflow: hidden; min-height: 0; }
.ov-sidebar { width: 100%; background: var(--bg-primary); border-right: 1px solid var(--border); display: flex; flex-direction: column; overflow: hidden; transition: all var(--transition-base); }
.ov-sidebar-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--border); background: var(--bg-secondary); flex-shrink: 0; gap: 8px; }
.ov-sidebar-left { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.ov-sidebar-icon { width: 16px; height: 16px; color: var(--accent); flex-shrink: 0; }
.ov-sidebar-title { font-size: 0.85rem; font-weight: 600; color: var(--text-primary); letter-spacing: -0.01em; }
.ov-sidebar-right { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.ov-sidebar-actions { display: none; align-items: center; gap: 6px; }
.ov-sidebar-actions.ov-visible { display: flex; }
.ov-select-count { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--radius-full); background: var(--accent); color: white; font-size: 0.7rem; font-weight: 600; line-height: 1; }
.ov-action-btn { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: var(--radius-md); border: 1px solid var(--border); background: var(--bg-primary); color: var(--text-secondary); cursor: pointer; transition: all var(--transition-fast); padding: 0; }
.ov-action-btn:hover { background: var(--bg-hover); color: var(--text-primary); }
.ov-action-btn.ov-action-md { background: #10b981; color: white; border-color: transparent; }
.ov-action-btn.ov-action-md:hover { background: #059669; }
.ov-action-btn.ov-action-pdf { background: #ef4444; color: white; border-color: transparent; }
.ov-action-btn.ov-action-pdf:hover { background: #dc2626; }
.ov-action-btn.ov-action-print { background: var(--accent); color: white; border-color: transparent; }
.ov-action-btn.ov-action-print:hover { background: var(--accent-hover); }
.ov-sidebar-close { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: var(--radius-full); border: none; background: var(--bg-tertiary); color: var(--text-tertiary); cursor: pointer; transition: all var(--transition-fast); }
.ov-sidebar-close:hover { background: var(--bg-active); color: var(--text-primary); }
.ov-tree { flex: 1; overflow-y: auto; padding: var(--space-sm) 0; }
.ov-book { margin: 2px 0; }
.ov-book-header { display: flex; align-items: center; gap: 8px; padding: 10px 16px; cursor: pointer; border-radius: var(--radius-md); transition: all var(--transition-fast); user-select: none; }
.ov-book-header:hover { background: var(--bg-hover); }
.ov-book-icon { width: 16px; height: 16px; flex-shrink: 0; color: var(--accent); }
.ov-chapters { overflow: hidden; transition: max-height var(--transition-normal), opacity var(--transition-normal); max-height: 2000px; opacity: 1; padding-left: 20px; }
.ov-chapters.collapsed { max-height: 0 !important; opacity: 0; }
.ov-chapter, .ov-file-node { display: flex; align-items: center; gap: 10px; padding: 8px 12px; cursor: pointer; border-radius: var(--radius-md); transition: all var(--transition-fast); user-select: none; margin: 2px 0; }
.ov-chapter:hover, .ov-file-node:hover { background: var(--bg-hover); }
.ov-chapter.active, .ov-file-node.active { background: rgba(var(--accent-rgb), 0.08); color: var(--accent); font-weight: 500; }
.ov-check { width: 16px; height: 16px; border-radius: 4px; border: 2px solid var(--border-hover); background: transparent; flex-shrink: 0; cursor: pointer; position: relative; transition: all 0.15s cubic-bezier(0.25,0.46,0.45,0.94); user-select: none; -webkit-user-select: none; touch-action: none; }
.ov-check::after { content: ''; position: absolute; top: 1px; left: 3px; width: 4px; height: 7px; border: 2px solid white; border-top: none; border-left: none; transform: rotate(45deg) scale(0); transition: transform 0.15s cubic-bezier(0.25,0.46,0.45,0.94); }
.ov-check.checked { background: var(--accent); border-color: var(--accent); }
.ov-check.checked::after { transform: rotate(45deg) scale(1); }
.ov-check:hover { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.1); }
.ov-ch-bullet, .ov-file-bullet { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; background: var(--ov-color, var(--accent)); opacity: 0.7; }
.ov-ch-name, .ov-file-node .ov-name { flex: 1; font-size: 0.88rem; color: inherit; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 450; }
.ov-ch-meta, .ov-meta { font-size: 0.72rem; color: var(--text-tertiary); flex-shrink: 0; font-variant-numeric: tabular-nums; }
.ov-chevron { width: 12px; height: 12px; flex-shrink: 0; transition: transform var(--transition-normal); color: var(--text-tertiary); }
.ov-group { margin: 2px 0; }
.ov-group-header { display: flex; align-items: center; gap: 8px; padding: 10px 16px; cursor: pointer; border-radius: var(--radius-md); transition: all var(--transition-fast); user-select: none; }
.ov-group-header:hover { background: var(--bg-hover); }
.ov-folder-icon { width: 16px; height: 16px; flex-shrink: 0; color: var(--warning); }
.ov-group-children { overflow: hidden; transition: max-height var(--transition-normal), opacity var(--transition-normal); max-height: 2000px; opacity: 1; }
.ov-group-children.collapsed { max-height: 0 !important; opacity: 0; }
.ov-name { flex: 1; font-size: 0.9rem; font-weight: 550; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ov-count { font-size: 0.72rem; color: var(--text-tertiary); background: var(--bg-tertiary); padding: 2px 8px; border-radius: var(--radius-full); flex-shrink: 0; font-variant-numeric: tabular-nums; }
.ov-folder-node { margin: 2px 0; }
.ov-folder-hdr { display: flex; align-items: center; gap: 8px; padding: 8px 16px; cursor: pointer; border-radius: var(--radius-md); transition: all var(--transition-fast); user-select: none; padding-left: calc(16px + var(--ov-indent, 0px)); }
.ov-folder-hdr:hover { background: var(--bg-hover); }
.ov-folder-children { overflow: hidden; transition: max-height var(--transition-normal), opacity var(--transition-normal); max-height: 2000px; opacity: 1; }
.ov-folder-children.collapsed { max-height: 0 !important; opacity: 0; }
.ov-chapter .ch-card-download-btn, .ov-chapter .ch-download-btn, .ov-file-node .ch-card-download-btn, .ov-file-node .ch-download-btn { opacity: 0; width: 26px; height: 26px; border-radius: var(--radius-full); border: none; background: transparent; color: var(--text-tertiary); cursor: pointer; transition: all var(--transition-fast); padding: 0; flex-shrink: 0; }
.ov-chapter:hover .ch-card-download-btn, .ov-chapter:hover .ch-download-btn, .ov-file-node:hover .ch-card-download-btn, .ov-file-node:hover .ch-download-btn { opacity: 1; }
.ov-chapter .ch-card-download-btn:hover, .ov-chapter .ch-download-btn:hover, .ov-file-node .ch-card-download-btn:hover, .ov-file-node .ch-download-btn:hover { background: rgba(var(--accent-rgb), 0.1); color: var(--accent); }
.ov-main { flex: 1; display: flex; flex-direction: column; overflow: hidden; min-width: 0; background: var(--bg-secondary); }
.ov-mobile-bar { display: none; }
.ov-toolbar { display: flex; align-items: center; justify-content: space-between; padding: 10px 16px; background: var(--bg-primary); border-bottom: 1px solid var(--border); flex-shrink: 0; min-height: 44px; }
.ov-toolbar-left { display: flex; align-items: center; gap: 8px; }
.ov-filename-wrap { display: flex; align-items: center; gap: 6px; padding: 5px 12px; background: var(--bg-tertiary); border-radius: var(--radius-full); font-size: 0.82rem; font-weight: 500; color: var(--text-primary); }
.ov-filename-wrap svg { width: 14px; height: 14px; color: var(--accent); }
.ovc-chapter-title { font-size: 1.1rem; font-weight: 600; color: var(--text-primary); margin: 20px 0 10px; padding-bottom: 8px; border-bottom: 2px solid var(--accent); letter-spacing: -0.01em; page-break-after: avoid; }
.ovc-chapter-wrap:first-child > .ovc-chapter-title { margin-top: 0; }
.ov-print-only { display: flex; flex: 1; overflow: hidden; }

/* ===== Reserved export interface ===== */
.overview-page--placeholder { min-height: calc(100dvh - var(--nav-height) - var(--space-xl)); height: auto; }
.ov-placeholder {
  width: min(720px, calc(100% - 32px));
  margin: 64px auto;
  padding: 48px 32px;
  text-align: center;
  border: 1px dashed var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-secondary);
  color: var(--text-secondary);
}
.ov-placeholder-icon { width: 32px; height: 32px; margin: 0 auto 18px; color: var(--accent); }
.ov-placeholder-icon svg { width: 100%; height: 100%; }
.ov-placeholder h1 { margin: 0 0 10px; color: var(--text-primary); font-size: 1.2rem; }
.ov-placeholder p { margin: 0; font-size: .86rem; line-height: 1.6; }

/* ===== 21. Fullscreen Preview ===== */
.fullscreen-preview-overlay { position: fixed; inset: 0; z-index: 9999; background: var(--bg-primary); display: flex; flex-direction: column; animation: fadeIn 0.15s ease; }
.fullscreen-preview-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 24px; border-bottom: 1px solid var(--border); background: var(--bg-secondary); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
.fs-header-left { display: flex; align-items: center; gap: 10px; }
.fs-header-icon { width: 17px; height: 17px; color: var(--accent); flex-shrink: 0; }
.fs-title { font-size: 0.95rem; font-weight: 620; color: var(--text-primary); }
.fs-actions { display: flex; align-items: center; gap: 8px; }
.fullscreen-preview-content { flex: 1; overflow-y: auto; padding: 32px 40px; max-width: 900px; margin: 0 auto; width: 100%; line-height: 1.85; }
.fullscreen-preview-content img { max-width: 100%; border-radius: var(--radius-md); margin: 16px 0; cursor: zoom-in; }
.doc-path-badge { font-size: 0.72rem; padding: 1px 8px; border-radius: 999px; background: var(--bg-tertiary); color: var(--text-tertiary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 180px; }

/* ===== 22. Sidebar / Tree / Editor ===== */
.sidebar { width: var(--sidebar-width); flex-shrink: 0; }
.sidebar-tree { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-sm); }
.tree-item { display: flex; align-items: center; gap: var(--space-sm); padding: 10px var(--space-md); cursor: pointer; font-size: 0.88rem; transition: background var(--transition-fast); border-bottom: 1px solid var(--border-light); }
.tree-item:last-child { border-bottom: none; }
.tree-item:hover { background: var(--bg-hover); }
.tree-item.active { background: var(--accent-light); color: var(--accent); font-weight: 500; }
.tree-item .tree-toggle { width: 16px; font-size: 0.7rem; color: var(--text-tertiary); transition: transform var(--transition-fast); }
.tree-item .tree-toggle.open { transform: rotate(90deg); }
.tree-children .tree-item { padding-left: var(--space-xl); }
.editor-area { flex: 1; display: flex; flex-direction: column; }
.editor-toolbar { display: flex; gap: var(--space-sm); margin-bottom: var(--space-md); flex-wrap: wrap; align-items: center; }
.editor-content { flex: 1; display: flex; flex-direction: column; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; }
.editor-content textarea { flex: 1; width: 100%; min-height: 400px; padding: var(--space-lg); border: none; outline: none; background: transparent; color: var(--text-primary); font-family: "Cascadia Code", "Fira Code", "JetBrains Mono", monospace; font-size: 0.9rem; line-height: 1.7; resize: none; }
.editor-preview { padding: var(--space-lg); overflow-y: auto; flex: 1; min-height: 0; }
.editor-preview h1 { font-size: 1.5rem; margin-bottom: var(--space-md); }
.editor-preview h2 { font-size: 1.2rem; margin: var(--space-lg) 0 var(--space-sm); }
.editor-preview h3 { font-size: 1.05rem; margin: var(--space-md) 0 var(--space-sm); }
.editor-preview p { margin-bottom: var(--space-sm); }
.editor-preview ul, .editor-preview ol { padding-left: var(--space-lg); margin-bottom: var(--space-sm); }
.editor-preview code { background: var(--bg-tertiary); padding: 2px 6px; border-radius: 4px; font-size: 0.85em; }
.editor-preview pre { background: var(--bg-tertiary); padding: var(--space-md); border-radius: var(--radius-sm); overflow-x: auto; margin-bottom: var(--space-md); }
.editor-preview hr { border: none; border-top: 1px solid var(--border); margin: var(--space-lg) 0; }
.editor-preview blockquote { border-left: 3px solid var(--accent); padding-left: var(--space-md); color: var(--text-secondary); margin-bottom: var(--space-md); }

/* ==== pages/search.css ==== */
/* ============================================
   Search page v2 (.sch-*) — mobile-first
   ============================================ */

/* ===== 搜索页面容器 ===== */
.sch-page {
  max-width: 760px;
  margin: 0 auto;
  padding: 0 var(--space-sm) calc(var(--space-2xl) + env(safe-area-inset-bottom, 0px));
}

/* ===== Sticky 头部 (搜索框 + 筛选) ===== */
.sch-sticky {
  position: sticky;
  top: var(--nav-height);
  z-index: 20;
  background: var(--bg-primary);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  padding: var(--space-sm) 0 var(--space-xs);
}

/* ===== 搜索框（单一视觉元素，input 自己撑起整个圆角框） ===== */
.sch-bar {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
}
.sch-bar__icon {
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-shrink: 0;
  pointer-events: none;
  color: var(--text-tertiary);
  z-index: 1;
}
.sch-bar__icon svg { width: 20px; height: 20px; }
.sch-bar__input {
  flex: 1;
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: transparent; /* 无背景填充，避免"黑色方块"感 */
  font-size: 1rem;
  color: var(--text-primary);
  padding: 13px 44px 13px 44px;
  min-width: 0;
  outline: none;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.sch-bar__input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-light);
}
.sch-bar__input::placeholder { color: var(--text-tertiary); }
/* 移动端取消浏览器原生搜索框样式 */
.sch-bar__input::-webkit-search-decoration,
.sch-bar__input::-webkit-search-cancel-button { -webkit-appearance: none; }
.sch-bar__clear {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  flex-shrink: 0;
  width: 32px; height: 32px;
  border: none;
  background: transparent;
  color: var(--text-tertiary);
  border-radius: var(--radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 1;
  transition: all var(--transition-fast);
}
.sch-bar__clear:hover { background: var(--bg-hover); color: var(--text-primary); }
.sch-bar__clear svg { width: 16px; height: 16px; }

/* ===== 筛选栏 ===== */
.sch-filters {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) 0 var(--space-xs);
  flex-wrap: wrap;
}
.sch-filters__chips {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  flex: 1;
  min-width: 0;
}
.sch-filters__chips::-webkit-scrollbar { display: none; }
.sch-chip {
  flex-shrink: 0;
  padding: 6px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--surface);
  color: var(--text-secondary);
  font-size: 0.82rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: all var(--transition-fast);
}
.sch-chip:hover { background: var(--bg-hover); }
.sch-chip.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--text-inverse);
}
.sch-book-btn {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--surface);
  color: var(--text-secondary);
  font-size: 0.82rem;
  cursor: pointer;
  transition: all var(--transition-fast);
  max-width: 160px;
}
.sch-book-btn:hover { background: var(--bg-hover); border-color: var(--border-hover); }
.sch-book-btn svg { width: 14px; height: 14px; flex-shrink: 0; }
.sch-book-btn__text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ===== 科目分组徽章 ===== */
.sch-groups {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  padding-bottom: var(--space-xs);
}
.sch-group-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border: none;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--gc) 10%, transparent);
  color: var(--gc);
  font-size: 0.76rem;
  font-weight: 600;
  cursor: pointer;
  transition: all var(--transition-fast);
}
.sch-group-badge:hover { background: color-mix(in srgb, var(--gc) 18%, transparent); }
.sch-group-badge__num {
  font-size: 0.7rem;
  opacity: 0.8;
}

/* ===== 资料选择面板 (bottom sheet / dropdown) ===== */
.sch-book-overlay {
  position: fixed;
  inset: 0;
  z-index: 99;
  background: rgba(0, 0, 0, 0.35);
  opacity: 0;
  transition: opacity 0.25s ease;
}
.sch-book-overlay[hidden] { display: none; }
.sch-book-overlay.is-visible { opacity: 1; }

.sch-book-panel {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 100;
  max-height: 75vh;
  display: flex;
  flex-direction: column;
  background: var(--surface-strong);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
  box-shadow: 0 -4px 30px rgba(0,0,0,0.12);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  animation: sheetUp 0.25s cubic-bezier(0.25,0.46,0.45,0.94);
}
.sch-book-panel[hidden] { display: none; }
.sch-book-panel__handle {
  width: 40px;
  height: 4px;
  margin: 8px auto 4px;
  border-radius: var(--radius-full);
  background: var(--border-hover);
  flex-shrink: 0;
}
.sch-book-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-xs) var(--space-md);
  border-bottom: 1px solid var(--border);
}
.sch-book-panel__header h3 {
  font-size: 1rem;
  font-weight: 600;
  color: var(--text-primary);
  margin: 0;
}
.sch-book-panel__close {
  width: 32px; height: 32px;
  border: none;
  background: transparent;
  color: var(--text-tertiary);
  border-radius: var(--radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.sch-book-panel__close:hover { background: var(--bg-hover); color: var(--text-primary); }
.sch-book-panel__close svg { width: 18px; height: 18px; }
.sch-book-panel__search {
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--border);
}
.sch-book-panel__search input {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  font-size: 0.9rem;
  outline: none;
  background: var(--bg-primary);
  color: var(--text-primary);
}
.sch-book-panel__search input:focus { border-color: var(--accent); }
.sch-book-panel__list {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  flex: 1;
  padding-bottom: var(--space-md);
}
.sch-book-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: 12px var(--space-md);
  cursor: pointer;
  font-size: 0.88rem;
  color: var(--text-primary);
  transition: background var(--transition-fast);
  min-height: 48px;
}
.sch-book-item:hover, .sch-book-item:active { background: var(--bg-hover); }
.sch-book-item.is-selected {
  background: var(--accent-light);
  color: var(--accent);
  font-weight: 600;
}
.sch-book-item__name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sch-book-item__meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.sch-book-item__count {
  font-size: 0.74rem;
  color: var(--text-tertiary);
}
.sch-book-item__subject {
  font-size: 0.72rem;
  padding: 2px 8px;
  border-radius: var(--radius-full);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
}
.sch-book-item__empty {
  padding: var(--space-xl);
  text-align: center;
  font-size: 0.85rem;
  color: var(--text-tertiary);
}

/* ===== 结果区域 ===== */
.sch-results-area {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  min-height: 300px;
  padding-top: var(--space-sm);
}
.sch-results-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-xs) 0;
}
.sch-results-count {
  font-size: 0.82rem;
  color: var(--text-secondary);
  font-weight: 500;
}
.sch-results-more {
  font-size: 0.78rem;
  color: var(--text-tertiary);
}
.sch-results-end {
  text-align: center;
  padding: var(--space-lg) 0;
  font-size: 0.8rem;
  color: var(--text-tertiary);
}

/* ===== 结果卡片 ===== */
.sch-card {
  padding: var(--space-md);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  cursor: pointer;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast), transform var(--transition-fast);
}
.sch-card:hover {
  border-color: var(--border-hover);
  box-shadow: var(--shadow-md);
}
.sch-card:active {
  transform: scale(0.99);
}
.sch-card.is-selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-light);
}
.sch-card__meta {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-xs);
}
.sch-card__badge {
  font-size: 0.72rem;
  font-weight: 600;
  padding: 2px 10px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--sc) 12%, transparent);
  color: var(--sc);
  flex-shrink: 0;
}
.sch-card__loc {
  font-size: 0.76rem;
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.sch-card__q {
  font-size: 0.92rem;
  color: var(--text-primary);
  line-height: 1.55;
  margin-bottom: 4px;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.sch-card__a {
  font-size: 0.82rem;
  color: var(--text-secondary);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.sch-card__q .search-highlight,
.sch-card__a .search-highlight {
  background: color-mix(in srgb, var(--warning) 28%, transparent);
  color: var(--text-primary);
  padding: 0 2px;
  border-radius: 3px;
  font-weight: 600;
}

/* ===== 骨架屏 ===== */
.sch-card--skeleton {
  pointer-events: none;
}
.skel {
  background: linear-gradient(90deg, var(--bg-tertiary) 25%, var(--bg-hover) 50%, var(--bg-tertiary) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.3s infinite;
  border-radius: var(--radius-sm);
}
.skel--badge { width: 48px; height: 20px; border-radius: var(--radius-full); }
.skel--loc { width: 100px; height: 14px; }
.skel--q { width: 100%; height: 16px; margin-top: var(--space-xs); }
.skel--a { width: 90%; height: 14px; margin-top: 6px; }
.skel--a2 { width: 60%; height: 14px; margin-top: 4px; }
@keyframes shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ===== 空状态 ===== */
.sch-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-3xl) var(--space-lg);
  text-align: center;
  color: var(--text-tertiary);
}
.sch-empty__icon { opacity: 0.35; }
.sch-empty__icon svg { width: 48px; height: 48px; }
.sch-empty__title {
  font-size: 1rem;
  font-weight: 600;
  color: var(--text-secondary);
  margin: var(--space-sm) 0 0;
}
.sch-empty__desc {
  font-size: 0.82rem;
  color: var(--text-tertiary);
  line-height: 1.6;
  margin: 0;
}
.sch-empty--error .sch-empty__title { color: var(--danger); }

/* ===== 搜索历史 ===== */
.sch-history { padding: var(--space-sm) 0; }
.sch-history__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-sm);
}
.sch-history__head h3 {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-secondary);
  margin: 0;
}
.sch-history__clear {
  border: none;
  background: transparent;
  color: var(--accent);
  font-size: 0.8rem;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  transition: background var(--transition-fast);
}
.sch-history__clear:hover { background: var(--accent-light); }
.sch-history__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}
.sch-history__tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--surface);
  font-size: 0.82rem;
  color: var(--text-secondary);
  cursor: pointer;
  transition: all var(--transition-fast);
  position: relative;
}
.sch-history__tag:hover { background: var(--bg-hover); border-color: var(--border-hover); }
.sch-history__tag svg { width: 14px; height: 14px; color: var(--text-tertiary); }
.sch-history__del {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px; height: 18px;
  border-radius: var(--radius-full);
  margin-left: 2px;
}
.sch-history__del:hover { background: var(--bg-active); }
.sch-history__del svg { width: 11px; height: 11px; color: var(--text-tertiary); }

/* ===== 哨兵元素 (无限滚动) ===== */
.sch-sentinel { height: 1px; }

/* ===== body 滚动锁定 (资料面板打开时) ===== */
body.sch-noscroll { overflow: hidden; }

/* ===== sheetUp 动画 (定义在 responsive.css，这里补充) =====
   @keyframes sheetUp 已在 responsive.css 中定义 */

/* ============================================
   桌面端增强 (≥768px)
   ============================================ */
@media (min-width: 768px) {
  .sch-page { padding: 0 var(--space-lg) var(--space-2xl); }

  .sch-sticky { padding: var(--space-md) 0 var(--space-xs); }

  /* 筛选栏：科目 chips 不需滚动，资料选择器更宽 */
  .sch-filters { gap: var(--space-md); }
  .sch-filters__chips { overflow: visible; flex-wrap: wrap; }
  .sch-book-btn { max-width: 220px; }
  .sch-book-btn__text { max-width: 180px; }

  /* 资料选择面板：桌面端改为居中弹出浮层，而非底部 sheet */
  .sch-book-panel {
    position: fixed;
    bottom: auto;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 440px;
    max-width: 90vw;
    max-height: 520px;
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-xl);
    animation: fadeInScale 0.2s cubic-bezier(0.25,0.46,0.45,0.94);
  }
  .sch-book-panel__handle { display: none; }
  body.sch-noscroll { overflow: auto; }

  /* 结果卡片更大间距 */
  .sch-card { padding: var(--space-lg); }
  .sch-card__q { font-size: 0.95rem; }
}

@keyframes fadeInScale {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.96); }
  to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

/* ===== 深色主题微调 ===== */
[data-theme="dark"] .sch-card__q .search-highlight,
[data-theme="dark"] .sch-card__a .search-highlight {
  background: color-mix(in srgb, var(--warning) 35%, transparent);
}
/* ==== pages/derivation.css ==== */
/* ============================================
   Derivation module (.dv-*)
   Extracted from main.css. Load order matters (see index.html).
   ============================================ */

/* ===== 32. Derivation Module Redesign ===== */

/* -- Step cards -- */
.dv-step.review-card-answer{border-top:none;border:1px solid var(--border);border-radius:var(--radius-xl);overflow:hidden;margin-bottom:12px;background:var(--bg-secondary);transition:border-color 0.2s,box-shadow 0.2s}
.dv-step.review-card-answer.expanded{border-color:color-mix(in srgb,var(--mc,var(--accent)) 28%,transparent);box-shadow:0 2px 12px color-mix(in srgb,var(--mc,var(--accent)) 10%,transparent)}
.dv-step .review-card-toggle{justify-content:flex-start;gap:12px;padding:15px 18px;border:none;border-top:none;background:transparent;color:var(--text-secondary);font-weight:600;font-size:0.9rem;border-radius:var(--radius-xl);transition:background 0.15s}
.dv-step .review-card-toggle::after{display:none}
.dv-step.review-card-answer.expanded .review-card-toggle{border-radius:var(--radius-xl) var(--radius-xl) 0 0}
.dv-step .review-card-toggle:hover{background:var(--bg-hover)}
.dv-step.review-card-answer.expanded .review-card-toggle{color:var(--mc,var(--accent))}
.dv-step .review-card-toggle .toggle-icon{transition:transform 0.25s ease,color 0.2s}
.dv-step.review-card-answer.expanded .review-card-toggle .toggle-icon-up{color:var(--mc,var(--accent))}

/* Override review-card-answer-body padding for dv-steps */
.dv-step.review-card-answer .review-card-answer-body{padding:0 18px}
.dv-step.review-card-answer.expanded .review-card-answer-body{padding:2px 18px 18px;background:transparent;border-top:1px solid var(--border-light)}

/* -- Problem card -- */
.dv-problem-card{background:color-mix(in srgb,var(--mc,var(--accent)) 6%,var(--bg-secondary));border:1px solid color-mix(in srgb,var(--mc,var(--accent)) 20%,transparent);border-left:4px solid var(--mc,var(--accent));border-radius:var(--radius-xl);padding:18px 20px;margin-bottom:20px}
.dv-problem-badge{font-size:0.7rem;font-weight:700;color:var(--mc,var(--accent));text-transform:uppercase;letter-spacing:0.08em;margin-bottom:8px}
.dv-problem-text{font-size:1.05rem;line-height:1.75;color:var(--text-primary)}

/* -- Scene card -- */
.dv-scene-card{background:var(--bg-tertiary);border:1px solid var(--border);border-radius:var(--radius-xl);padding:18px 20px;margin-top:12px;animation:fadeIn 0.3s ease both}
.dv-scene-badge{font-size:0.7rem;font-weight:700;color:var(--text-secondary);text-transform:uppercase;letter-spacing:0.08em;margin-bottom:8px}
.dv-scene-body{font-size:0.95rem;color:var(--text-primary);line-height:1.65}

/* -- Navigation bar -- */
.dv-nav-bar{position:sticky;bottom:0;background:var(--surface-strong);border-top:1px solid var(--border);padding:12px 0 max(12px,env(safe-area-inset-bottom,0px));margin-top:20px;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);box-shadow:0 -6px 24px rgba(0,0,0,0.06)}
.dv-nav-progress{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.dv-nav-track{flex:1;height:5px;background:var(--bg-active);border-radius:var(--radius-full);overflow:hidden}
.dv-nav-fill{height:100%;background:linear-gradient(90deg,var(--mc,var(--accent)),color-mix(in srgb,var(--mc,var(--accent)) 60%,white));border-radius:var(--radius-full);transition:width 0.4s cubic-bezier(0.4,0,0.2,1)}
.dv-nav-count{font-size:0.8rem;font-weight:700;color:var(--mc,var(--accent));flex-shrink:0;min-width:40px;text-align:right}
.dv-nav-btns{display:flex;gap:10px}
.dv-nav-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:5px;padding:12px 16px;border:none;border-radius:var(--radius-full);font-size:0.88rem;font-weight:600;cursor:pointer;transition:all 0.22s cubic-bezier(0.25,0.46,0.45,0.94)}
.dv-nav-btn svg{flex-shrink:0}
.dv-nav-btn--prev{background:var(--bg-secondary);color:var(--text-secondary);border:1px solid var(--border)}
.dv-nav-btn--prev:hover:not(:disabled){background:var(--bg-hover);color:var(--text-primary);transform:translateY(-1px)}
.dv-nav-btn--prev:disabled{opacity:0.4;cursor:not-allowed}
.dv-nav-btn--next{background:linear-gradient(135deg,var(--mc,var(--accent)),color-mix(in srgb,var(--mc,var(--accent)) 65%,#1d4ed8));color:white;box-shadow:0 4px 14px color-mix(in srgb,var(--mc,var(--accent)) 30%,transparent)}
.dv-nav-btn--next:hover{transform:translateY(-2px);box-shadow:0 6px 20px color-mix(in srgb,var(--mc,var(--accent)) 40%,transparent)}
/* ==== pages/math-notes.css ==== */
/* Notes workspace v3 ------------------------------------------------------ */
.mn-page,
.mn-review-page {
  --mn: #4f46e5;
  --mn-deep: #3730a3;
  --mn-soft: #eef2ff;
  --mn-line: color-mix(in srgb, var(--mn) 18%, var(--border));
  position: relative;
  min-height: calc(100vh - 100px);
  overflow: clip;
}
.overlay.mn-sheet-overlay { align-items: center; padding-top: 0; }

.mn-ambient { position: absolute; inset: 0; pointer-events: none; opacity: .45; }
.mn-ambient::after { content: ''; position: absolute; top: 0; right: 8%; width: 160px; height: 1px; background: var(--mn-line); box-shadow: -220px 38vh 0 var(--mn-line), 140px 72vh 0 var(--mn-line); }
.mn-ambient span { display: none; }
.mn-shell { position: relative; max-width: 1120px; margin: 0 auto; padding: 0 24px 68px; }

.mn-page-header { position: relative; z-index: 1; display: flex; align-items: flex-start; gap: 14px; max-width: 1120px; margin: 0 auto 24px; padding: 4px 24px 0; }
.mn-page-header .mod-back-btn { margin-top: 3px; }
.mn-page-heading { min-width: 0; }
.mn-kicker { display: flex; align-items: center; gap: 7px; color: var(--text-tertiary); font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; }
.mn-kicker-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--mn-dot); box-shadow: 0 0 0 4px color-mix(in srgb, var(--mn-dot) 14%, transparent); }
.mn-heading-title { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.mn-heading-title h1 { margin: 0; color: var(--text-primary); font-size: clamp(1.35rem, 3vw, 2rem); line-height: 1.2; font-weight: 760; }
.mn-subject-icon { display: grid; place-items: center; width: 32px; height: 32px; border: 1px solid color-mix(in srgb, var(--mc) 32%, var(--border)); border-radius: 8px; background: color-mix(in srgb, var(--ml) 38%, var(--bg-secondary)); color: var(--mc); font-size: .82rem; font-weight: 800; }
.mn-page-heading p { margin: 7px 0 0; color: var(--text-tertiary); font-size: .86rem; line-height: 1.55; }

.mn-intro { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; padding: 4px 0 18px; border-bottom: 1px solid var(--border-light); }
.mn-intro-eyebrow, .mn-editor-eyebrow { color: var(--mn); font-size: .68rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.mn-intro h2 { margin: 6px 0 0; color: var(--text-primary); font-size: clamp(1.25rem, 2.4vw, 1.7rem); line-height: 1.25; font-weight: 760; }
.mn-intro p { margin: 7px 0 0; color: var(--text-secondary); font-size: .86rem; }
.mn-intro-count { display: flex; flex-direction: column; align-items: flex-end; flex-shrink: 0; color: var(--text-tertiary); font-size: .74rem; }
.mn-intro-count strong { color: var(--text-primary); font-size: 2rem; line-height: 1; font-variant-numeric: tabular-nums; }
.mn-main-actions { display: flex; gap: 8px; padding: 18px 0 14px; }
.mn-primary-action, .mn-quiet-action { display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-height: 40px; padding: 9px 15px; border-radius: 7px; border: 1px solid transparent; font: inherit; font-size: .84rem; font-weight: 700; cursor: pointer; transition: transform .2s ease, background-color .2s ease, border-color .2s ease, color .2s ease, box-shadow .2s ease; }
.mn-primary-action { color: #fff; background: var(--mn); box-shadow: 0 5px 16px color-mix(in srgb, var(--mn) 24%, transparent); }
.mn-primary-action:hover:not(:disabled) { background: var(--mn-deep); transform: translateY(-2px); box-shadow: 0 9px 22px color-mix(in srgb, var(--mn) 30%, transparent); }
.mn-primary-action:active:not(:disabled) { transform: translateY(0) scale(.98); }
.mn-primary-action:disabled, .mn-quiet-action:disabled { opacity: .42; cursor: not-allowed; box-shadow: none; }
.mn-quiet-action { color: var(--text-secondary); background: var(--bg-secondary); border-color: var(--border); }
.mn-quiet-action:hover:not(:disabled) { color: var(--mn); border-color: var(--mn-line); background: color-mix(in srgb, var(--mn) 6%, var(--bg-secondary)); transform: translateY(-1px); }
.mn-primary-action svg, .mn-quiet-action svg { width: 16px; height: 16px; flex-shrink: 0; }
.mn-primary-action.is-loading { pointer-events: none; }
.mn-primary-action.is-loading span::after { content: '…'; }

.mn-group-rail { display: flex; align-items: center; gap: 7px; overflow-x: auto; padding: 2px 0 14px; scrollbar-width: none; scroll-snap-type: x proximity; }
.mn-group-rail::-webkit-scrollbar { display: none; }
.mn-group-tab, .mn-group-add { display: inline-flex; align-items: center; gap: 7px; min-height: 34px; padding: 7px 11px; border: 1px solid var(--border); border-radius: 7px; background: var(--bg-secondary); color: var(--text-secondary); white-space: nowrap; font: inherit; font-size: .78rem; font-weight: 700; cursor: pointer; scroll-snap-align: start; transition: transform .18s ease, color .18s ease, background-color .18s ease, border-color .18s ease; }
.mn-group-tab:hover, .mn-group-add:hover { color: var(--mn); border-color: var(--mn-line); transform: translateY(-1px); }
.mn-group-tab.active { color: #fff; background: var(--mn); border-color: var(--mn); box-shadow: 0 4px 12px color-mix(in srgb, var(--mn) 22%, transparent); }
.mn-group-tab i, .mn-group-chip i { width: 7px; height: 7px; border-radius: 50%; background: var(--mn-group, var(--mn)); flex-shrink: 0; }
.mn-group-tab.active i { background: rgba(255,255,255,.9); }
.mn-group-tab b { font-size: .68rem; opacity: .62; font-variant-numeric: tabular-nums; }
.mn-group-tab.active b { opacity: .8; }
.mn-group-add { color: var(--mn); border-style: dashed; background: transparent; }
.mn-group-add svg { width: 14px; height: 14px; }

.mn-controls { display: flex; align-items: center; gap: 9px; margin-bottom: 8px; }
.mn-search { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; height: 42px; padding: 0 12px; border: 1px solid var(--border); border-radius: 7px; background: var(--bg-secondary); transition: border-color .18s ease, box-shadow .18s ease; }
.mn-search:focus-within { border-color: color-mix(in srgb, var(--mn) 48%, var(--border)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--mn) 12%, transparent); }
.mn-search > svg { width: 17px; height: 17px; color: var(--text-tertiary); flex-shrink: 0; }
.mn-search input { width: 100%; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--text-primary); font: inherit; font-size: .88rem; }
.mn-search input::placeholder { color: var(--text-tertiary); }
.mn-search button { display: grid; place-items: center; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 50%; background: var(--bg-tertiary); color: var(--text-secondary); cursor: pointer; }
.mn-search button[hidden] { display: none; }
.mn-search button svg { width: 13px; height: 13px; }
.mn-controls select { height: 42px; padding: 0 12px; border: 1px solid var(--border); border-radius: 7px; background: var(--bg-secondary); color: var(--text-secondary); font: inherit; font-size: .78rem; font-weight: 700; outline: 0; cursor: pointer; }
.mn-controls select:focus { border-color: var(--mn); }
.mn-result-line { min-height: 24px; padding: 6px 2px 9px; color: var(--text-tertiary); font-size: .75rem; }
.mn-result-line b { color: var(--mn); font-variant-numeric: tabular-nums; }

.mn-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.mn-note-card { display: flex; flex-direction: column; min-width: 0; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-secondary); overflow: hidden; opacity: 0; animation: mnCardIn .38s cubic-bezier(.22,1,.36,1) var(--mn-card-delay, 0ms) forwards; transition: transform .24s ease, border-color .24s ease, box-shadow .24s ease; }
.mn-note-card:hover { border-color: var(--mn-line); transform: translateY(-3px); box-shadow: 0 12px 28px rgba(15,23,42,.1); }
.mn-card-cover { position: relative; display: block; width: 100%; aspect-ratio: 4 / 3; padding: 0; overflow: hidden; border: 0; border-bottom: 1px solid var(--border-light); background: var(--bg-tertiary); cursor: zoom-in; }
.mn-card-cover img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .5s cubic-bezier(.22,1,.36,1), opacity .3s ease; }
.mn-card-cover:hover img { transform: scale(1.045); }
.mn-cover-count { position: absolute; left: 9px; bottom: 8px; padding: 4px 7px; border-radius: 5px; color: #fff; background: rgba(15,23,42,.72); font-size: .66rem; font-weight: 700; }
.mn-cover-open { position: absolute; right: 9px; bottom: 8px; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 6px; color: #fff; background: rgba(15,23,42,.72); opacity: 0; transform: translateY(4px); transition: opacity .2s ease, transform .2s ease; }
.mn-card-cover:hover .mn-cover-open, .mn-card-cover:focus-visible .mn-cover-open { opacity: 1; transform: translateY(0); }
.mn-cover-open svg { width: 14px; height: 14px; }
.mn-card-cover--empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; color: var(--text-tertiary); cursor: pointer; }
.mn-card-cover--empty svg { width: 25px; height: 25px; opacity: .55; }
.mn-card-cover--empty small { font-size: .72rem; }
.mn-card-content { min-width: 0; padding: 12px 13px 10px; }
.mn-card-topline { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; color: var(--text-tertiary); font-size: .68rem; }
.mn-card-topline > span:last-child { white-space: nowrap; }
.mn-group-chip { display: inline-flex; align-items: center; gap: 5px; min-width: 0; max-width: 70%; color: var(--mn-group, var(--mn)); font-size: .7rem; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mn-group-chip--none { color: var(--text-tertiary); }
.mn-card-content h3 { margin: 8px 0 0; overflow: hidden; color: var(--text-primary); font-size: .96rem; line-height: 1.35; font-weight: 750; text-overflow: ellipsis; white-space: nowrap; }
.mn-card-content p { margin: 5px 0 0; color: var(--text-tertiary); font-size: .72rem; }
.mn-card-footer { display: flex; align-items: center; gap: 7px; min-width: 0; padding: 9px 11px 11px; border-top: 1px solid var(--border-light); }
.mn-move-select { display: flex; align-items: center; gap: 5px; min-width: 0; flex: 1; color: var(--text-tertiary); font-size: .67rem; }
.mn-move-select select { min-width: 0; max-width: 100%; padding: 4px 4px; border: 0; background: transparent; color: var(--text-secondary); font: inherit; font-weight: 700; outline: 0; text-overflow: ellipsis; }
.mn-card-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
.mn-icon-btn { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--text-tertiary); cursor: pointer; transition: background-color .18s ease, color .18s ease, transform .18s ease; }
.mn-icon-btn:hover { color: var(--mn); background: color-mix(in srgb, var(--mn) 10%, transparent); transform: translateY(-1px); }
.mn-icon-btn--danger:hover { color: var(--danger); background: var(--danger-light); }
.mn-icon-btn svg { width: 16px; height: 16px; }

.mn-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 220px; padding: 28px 18px; color: var(--text-secondary); text-align: center; }
.mn-empty--grid { grid-column: 1 / -1; border: 1px dashed var(--border); border-radius: 8px; background: color-mix(in srgb, var(--bg-secondary) 58%, transparent); }
.mn-empty-mark { display: grid; place-items: center; width: 48px; height: 48px; margin-bottom: 12px; border-radius: 50%; color: var(--mn); background: var(--mn-soft); font-size: 1.7rem; font-weight: 700; }
.mn-empty h2 { margin: 0; color: var(--text-primary); font-size: 1.02rem; }
.mn-empty p { max-width: 340px; margin: 7px 0 16px; color: var(--text-tertiary); font-size: .82rem; line-height: 1.6; }
.mn-loading-line { width: 46%; height: 22px; border-radius: 5px; background: var(--bg-tertiary); animation: mnPulse 1.2s ease-in-out infinite; }
.mn-loading-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 18px; }
.mn-loading-grid i { display: block; aspect-ratio: 4 / 3; border-radius: 8px; background: var(--bg-tertiary); animation: mnPulse 1.2s ease-in-out infinite; }
.mn-loading-grid i:nth-child(2) { animation-delay: .12s; }
.mn-loading-grid i:nth-child(3) { animation-delay: .24s; }

/* Editor and group manager */
.mn-editor, .mn-group-manager { width: min(92vw, 620px); max-height: min(88vh, 760px); }
.mn-editor-grab { display: none; width: 38px; height: 4px; margin: 9px auto 0; border-radius: 99px; background: var(--border); }
.mn-editor-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 20px 22px 15px; border-bottom: 1px solid var(--border-light); }
.mn-editor-head h2 { margin: 5px 0 0; color: var(--text-primary); font-size: 1.18rem; line-height: 1.3; }
.mn-editor-body { overflow: auto; padding: 18px 22px 22px; }
.mn-form-field { display: block; margin-bottom: 15px; }
.mn-form-field > span, .mn-upload-label { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 7px; color: var(--text-primary); font-size: .78rem; font-weight: 750; }
.mn-upload-label small { color: var(--text-tertiary); font-size: .68rem; font-weight: 500; }
.mn-upload-label b { color: var(--mn); font-size: .72rem; }
.mn-name-input, .mn-select { width: 100%; box-sizing: border-box; min-height: 42px; padding: 9px 12px; border: 1px solid var(--border); border-radius: 7px; background: var(--bg-secondary); color: var(--text-primary); font: inherit; font-size: .88rem; outline: 0; transition: border-color .18s ease, box-shadow .18s ease; }
.mn-name-input:focus, .mn-select:focus { border-color: var(--mn); box-shadow: 0 0 0 3px color-mix(in srgb, var(--mn) 12%, transparent); }
.mn-upload-zone { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 126px; padding: 16px; border: 1.5px dashed var(--mn-line); border-radius: 8px; background: color-mix(in srgb, var(--mn) 3%, var(--bg-secondary)); color: var(--text-secondary); cursor: pointer; user-select: none; transition: border-color .2s ease, background-color .2s ease, transform .2s ease; }
.mn-upload-zone:hover, .mn-upload-zone:focus-visible, .mn-upload-zone.is-dragging { border-color: var(--mn); background: color-mix(in srgb, var(--mn) 9%, var(--bg-secondary)); transform: translateY(-1px); outline: 0; }
.mn-upload-plus { display: grid; place-items: center; width: 34px; height: 34px; margin-bottom: 7px; border-radius: 50%; color: #fff; background: var(--mn); }
.mn-upload-plus svg { width: 18px; height: 18px; }
.mn-upload-zone strong { font-size: .83rem; }
.mn-upload-zone small { margin-top: 4px; color: var(--text-tertiary); font-size: .7rem; }
.mn-preview-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; margin-top: 12px; }
.mn-preview-item { position: relative; aspect-ratio: 1; overflow: hidden; border: 1px solid var(--border); border-radius: 7px; background: var(--bg-tertiary); cursor: grab; transition: transform .18s ease, border-color .18s ease, opacity .18s ease; }
.mn-preview-item:hover, .mn-preview-item.is-over { border-color: var(--mn); transform: translateY(-2px); }
.mn-preview-item.is-dragging { opacity: .4; }
.mn-preview-item.is-uploading { cursor: wait; }
.mn-preview-open { display: block; width: 100%; height: 100%; padding: 0; border: 0; background: transparent; cursor: zoom-in; }
.mn-preview-open img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mn-preview-index { position: absolute; left: 5px; bottom: 5px; min-width: 17px; padding: 2px 4px; border-radius: 4px; color: #fff; background: rgba(15,23,42,.72); font-size: .62rem; font-weight: 700; text-align: center; pointer-events: none; }
.mn-preview-remove { position: absolute; top: 4px; right: 4px; display: grid; place-items: center; width: 21px; height: 21px; padding: 0; border: 0; border-radius: 50%; color: #fff; background: rgba(15,23,42,.76); cursor: pointer; }
.mn-preview-remove:hover { background: var(--danger); }
.mn-preview-remove svg { width: 11px; height: 11px; }
.mn-preview-progress { position: absolute; inset: 0; display: grid; place-items: center; background: rgba(15,23,42,.35); pointer-events: none; }
.mn-preview-progress i { width: 17px; height: 17px; border: 2px solid rgba(255,255,255,.38); border-top-color: #fff; border-radius: 50%; animation: mnSpin .7s linear infinite; }
.mn-editor-actions { display: flex; justify-content: flex-end; gap: 8px; padding: 13px 22px 18px; border-top: 1px solid var(--border-light); }
.mn-group-summary { display: flex; gap: 10px; padding: 14px 22px; border-bottom: 1px solid var(--border-light); color: var(--text-tertiary); font-size: .75rem; }
.mn-group-summary b { color: var(--text-primary); }
.mn-new-group { padding: 16px 22px; border-bottom: 1px solid var(--border-light); background: color-mix(in srgb, var(--mn) 3%, var(--bg-secondary)); }
.mn-new-group > div { display: flex; gap: 8px; padding: 10px 0 6px; }
.mn-new-group .mn-primary-action { width: 100%; }
.mn-swatches { display: flex; flex-wrap: wrap; gap: 8px; }
.mn-swatch { width: 24px; height: 24px; padding: 0; border: 2px solid transparent; border-radius: 50%; background: var(--mn-swatch); cursor: pointer; transition: transform .18s ease, box-shadow .18s ease; }
.mn-swatch:hover { transform: scale(1.12); }
.mn-swatch.active { border-color: var(--bg-secondary); box-shadow: 0 0 0 2px var(--mn-swatch); }
.mn-group-list { display: flex; flex-direction: column; gap: 7px; overflow: auto; padding: 15px 22px 22px; }
.mn-group-row { display: flex; align-items: center; gap: 9px; min-height: 48px; padding: 7px 8px 7px 11px; border: 1px solid var(--border); border-radius: 7px; background: var(--bg-secondary); }
.mn-group-row-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--mn-group); flex-shrink: 0; }
.mn-group-row-name { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.mn-group-row-name strong { overflow: hidden; color: var(--text-primary); font-size: .82rem; text-overflow: ellipsis; white-space: nowrap; }
.mn-group-row-name small { color: var(--text-tertiary); font-size: .68rem; }
.mn-group-row.is-editing { flex-wrap: wrap; padding: 12px; }
.mn-group-row.is-editing .mn-name-input { flex-basis: 100%; }
.mn-group-edit-line { display: flex; align-items: center; justify-content: space-between; width: 100%; gap: 10px; }
.mn-group-edit-line > div:last-child { display: flex; gap: 5px; }
.mn-group-edit-line .mn-primary-action, .mn-group-edit-line .mn-quiet-action { min-height: 32px; padding: 6px 10px; font-size: .74rem; }
.mn-manager-empty { padding: 28px 12px; color: var(--text-tertiary); font-size: .82rem; text-align: center; }

/* Full-screen image viewer */
.mn-image-viewer { position: fixed; inset: 0; z-index: 500; display: grid; place-items: center; padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left)); animation: mnFadeIn .2s ease both; }
.mn-viewer-backdrop { position: absolute; inset: 0; background: rgba(2,6,23,.86); backdrop-filter: blur(12px); }
.mn-viewer-dialog { position: relative; z-index: 1; display: flex; flex-direction: column; width: min(100%, 980px); height: min(94vh, 880px); overflow: hidden; border: 1px solid rgba(255,255,255,.14); border-radius: 10px; color: #fff; background: rgba(15,23,42,.94); box-shadow: 0 24px 80px rgba(0,0,0,.42); animation: mnViewerIn .3s cubic-bezier(.22,1,.36,1) both; }
.mn-viewer-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 13px 16px; border-bottom: 1px solid rgba(255,255,255,.1); }
.mn-viewer-head > div { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.mn-viewer-head span { color: rgba(255,255,255,.55); font-size: .7rem; font-weight: 700; }
.mn-viewer-head strong { overflow: hidden; color: #fff; font-size: .84rem; text-overflow: ellipsis; white-space: nowrap; }
.mn-viewer-head .mn-icon-btn { color: rgba(255,255,255,.72); }
.mn-viewer-head .mn-icon-btn:hover { color: #fff; background: rgba(255,255,255,.12); }
.mn-viewer-stage { position: relative; display: grid; place-items: center; flex: 1; min-height: 0; overflow: hidden; touch-action: pan-y; }
.mn-viewer-stage img { max-width: 100%; max-height: 100%; object-fit: contain; user-select: none; transition: transform .2s ease; transform-origin: center; }
.mn-viewer-arrow { position: absolute; top: 50%; z-index: 2; display: grid; place-items: center; width: 42px; height: 42px; padding: 0; border: 1px solid rgba(255,255,255,.18); border-radius: 50%; color: #fff; background: rgba(2,6,23,.55); cursor: pointer; transform: translateY(-50%); transition: background-color .18s ease, transform .18s ease; }
.mn-viewer-arrow:hover:not(:disabled) { background: rgba(79,70,229,.85); transform: translateY(-50%) scale(1.05); }
.mn-viewer-arrow:disabled { opacity: .25; cursor: default; }
.mn-viewer-arrow svg { width: 19px; height: 19px; }
.mn-viewer-arrow--prev { left: 14px; }
.mn-viewer-arrow--next { right: 14px; }
.mn-viewer-tools { display: flex; align-items: center; justify-content: center; gap: 7px; padding: 9px 12px; border-top: 1px solid rgba(255,255,255,.1); color: rgba(255,255,255,.72); }
.mn-viewer-tools .mn-icon-btn { width: 28px; height: 28px; color: inherit; background: rgba(255,255,255,.08); }
.mn-viewer-tools .mn-icon-btn:hover { color: #fff; background: rgba(79,70,229,.85); }
.mn-viewer-tools > span { min-width: 42px; font-size: .72rem; text-align: center; }
.mn-viewer-reset, .mn-viewer-open { padding: 5px 9px; border: 0; border-radius: 5px; color: rgba(255,255,255,.72); background: rgba(255,255,255,.08); font: inherit; font-size: .68rem; cursor: pointer; text-decoration: none; }
.mn-viewer-reset:hover, .mn-viewer-open:hover { color: #fff; background: rgba(255,255,255,.15); }
.mn-viewer-thumbs { display: flex; gap: 7px; overflow-x: auto; padding: 10px 13px max(10px, env(safe-area-inset-bottom)); border-top: 1px solid rgba(255,255,255,.1); scrollbar-width: thin; }
.mn-viewer-thumb { flex: 0 0 54px; width: 54px; height: 42px; padding: 0; overflow: hidden; border: 2px solid transparent; border-radius: 5px; background: rgba(255,255,255,.08); cursor: pointer; opacity: .6; transition: border-color .18s ease, opacity .18s ease, transform .18s ease; }
.mn-viewer-thumb:hover { opacity: .9; transform: translateY(-2px); }
.mn-viewer-thumb.active { border-color: #a5b4fc; opacity: 1; }
.mn-viewer-thumb img { width: 100%; height: 100%; object-fit: cover; }

/* Immersive review */
.mn-review-shell { position: relative; max-width: 820px; margin: 0 auto; padding: 0 24px 68px; }
.mn-review-progress { height: 5px; margin-bottom: 18px; overflow: hidden; border-radius: 99px; background: var(--bg-tertiary); }
.mn-review-progress span { display: block; height: 100%; border-radius: inherit; background: var(--mn); transition: width .35s ease; }
.mn-review-card { overflow: hidden; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-secondary); box-shadow: 0 16px 42px rgba(15,23,42,.08); animation: mnReviewNext .34s cubic-bezier(.22,1,.36,1) both; }
.mn-review-card--prev { animation-name: mnReviewPrev; }
.mn-review-front { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 13px; width: 100%; min-height: 360px; padding: 30px; border: 0; color: var(--text-primary); background: transparent; cursor: pointer; text-align: center; }
.mn-review-symbol { display: grid; place-items: center; width: 54px; height: 54px; border-radius: 50%; color: var(--mn); background: var(--mn-soft); }
.mn-review-symbol svg { width: 24px; height: 24px; }
.mn-review-front strong { max-width: 80%; font-size: clamp(1.25rem, 4vw, 1.8rem); line-height: 1.4; }
.mn-review-front span:last-child { color: var(--text-tertiary); font-size: .8rem; }
.mn-review-back { padding: 17px; }
.mn-review-back-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 14px; }
.mn-review-back-head > div { display: flex; align-items: center; gap: 8px; min-width: 0; }
.mn-review-back-head strong { overflow: hidden; color: var(--text-primary); font-size: .9rem; text-overflow: ellipsis; white-space: nowrap; }
.mn-review-gallery { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 9px; }
.mn-review-image { position: relative; aspect-ratio: 4 / 3; overflow: hidden; padding: 0; border: 1px solid var(--border); border-radius: 7px; background: var(--bg-tertiary); cursor: zoom-in; }
.mn-review-image img { width: 100%; height: 100%; object-fit: cover; transition: transform .35s ease; }
.mn-review-image:hover img { transform: scale(1.04); }
.mn-review-image span { position: absolute; right: 5px; bottom: 5px; padding: 2px 5px; border-radius: 4px; color: #fff; background: rgba(15,23,42,.72); font-size: .64rem; }
.mn-review-no-image { grid-column: 1 / -1; padding: 50px 0; color: var(--text-tertiary); text-align: center; }
.mn-review-nav { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 15px; }
.mn-review-nav > span { color: var(--text-tertiary); font-size: .78rem; font-weight: 700; white-space: nowrap; }
.mn-review-nav > span i { margin: 0 3px; font-style: normal; opacity: .5; }

@keyframes mnCardIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
@keyframes mnFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes mnViewerIn { from { opacity: 0; transform: scale(.97) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } }
@keyframes mnReviewNext { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: translateX(0); } }
@keyframes mnReviewPrev { from { opacity: 0; transform: translateX(-24px); } to { opacity: 1; transform: translateX(0); } }
@keyframes mnPulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@keyframes mnSpin { to { transform: rotate(360deg); } }

@media (max-width: 900px) {
  .mn-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
  .overlay.mn-sheet-overlay { align-items: flex-end; padding-top: 0; }
  .mn-page, .mn-review-page { min-height: calc(100vh - 78px); }
  .mn-page-header { gap: 9px; margin-bottom: 18px; padding: 0 14px; }
  .mn-page-heading p { max-width: 290px; font-size: .78rem; }
  .mn-shell { padding: 0 14px max(44px, env(safe-area-inset-bottom)); }
  .mn-intro { align-items: flex-start; padding-bottom: 14px; }
  .mn-intro h2 { font-size: 1.18rem; }
  .mn-intro p { font-size: .76rem; }
  .mn-intro-count strong { font-size: 1.6rem; }
  .mn-main-actions { position: sticky; top: var(--nav-height); z-index: 8; margin-inline: -14px; padding: 10px 14px; background: color-mix(in srgb, var(--bg-primary) 88%, transparent); backdrop-filter: blur(10px); }
  .mn-main-actions .mn-primary-action { flex: 1; }
  .mn-main-actions .mn-quiet-action { width: 42px; padding: 8px; }
  .mn-main-actions .mn-quiet-action span { display: none; }
  .mn-group-rail { margin-inline: -14px; padding-inline: 14px; }
  .mn-controls { gap: 7px; }
  .mn-controls select { max-width: 94px; padding-inline: 8px; font-size: .72rem; }
  .mn-grid { gap: 9px; }
  .mn-note-card { border-radius: 7px; }
  .mn-card-cover { aspect-ratio: 1 / 1; }
  .mn-card-content { padding: 9px 9px 8px; }
  .mn-card-topline { font-size: .61rem; }
  .mn-card-content h3 { margin-top: 6px; font-size: .82rem; }
  .mn-card-content p { font-size: .64rem; }
  .mn-card-footer { align-items: stretch; flex-direction: column; gap: 3px; padding: 7px 8px 8px; }
  .mn-move-select { min-height: 26px; }
  .mn-card-actions { position: absolute; top: 7px; right: 7px; padding: 2px; border-radius: 6px; background: rgba(15,23,42,.58); }
  .mn-card-actions .mn-icon-btn { color: #fff; }
  .mn-card-actions .mn-icon-btn:hover { color: #fff; background: rgba(255,255,255,.16); }
  .mn-card-actions .mn-icon-btn--danger:hover { background: rgba(239,68,68,.8); }
  .mn-cover-open { opacity: 1; transform: none; }
  .mn-editor, .mn-group-manager { width: 100%; max-height: min(91vh, 820px); border-radius: 16px 16px 0 0; animation: mnSheetIn .28s cubic-bezier(.22,1,.36,1) both; }
  .mn-editor-grab { display: block; }
  .mn-editor-head { padding: 13px 16px 12px; }
  .mn-editor-body { padding: 15px 16px 20px; }
  .mn-editor-actions { padding: 11px 16px max(14px, env(safe-area-inset-bottom)); }
  .mn-preview-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 7px; }
  .mn-group-summary, .mn-new-group { padding-inline: 16px; }
  .mn-group-list { padding-inline: 16px; padding-bottom: max(18px, env(safe-area-inset-bottom)); }
  .mn-image-viewer { padding: 0; }
  .mn-viewer-dialog { width: 100%; height: 100%; border: 0; border-radius: 0; }
  .mn-viewer-head { padding: max(10px, env(safe-area-inset-top)) 12px 10px; }
  .mn-viewer-stage { min-height: 0; }
  .mn-viewer-arrow { width: 36px; height: 36px; }
  .mn-viewer-arrow--prev { left: 9px; }
  .mn-viewer-arrow--next { right: 9px; }
  .mn-viewer-tools { padding-block: 8px; }
  .mn-viewer-thumbs { padding-inline: 10px; }
  .mn-review-shell { padding: 0 14px max(44px, env(safe-area-inset-bottom)); }
  .mn-review-front { min-height: 280px; padding: 24px; }
  .mn-review-back { padding: 11px; }
  .mn-review-gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px; }
  .mn-review-nav .mn-primary-action, .mn-review-nav .mn-quiet-action { min-height: 38px; padding-inline: 10px; }
  .mn-review-nav .mn-primary-action span, .mn-review-nav .mn-quiet-action span { display: inline; }
}

@keyframes mnSheetIn { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: translateY(0); } }

@media (prefers-reduced-motion: reduce) {
  .mn-note-card, .mn-review-card, .mn-image-viewer, .mn-viewer-dialog, .mn-editor, .mn-group-manager { animation: none; opacity: 1; }
  .mn-card-cover img, .mn-primary-action, .mn-quiet-action, .mn-note-card, .mn-preview-item { transition: none; }
}
/* ==== pages/chem-foundations.css ==== */
/* 化学基础地毯复习 (.cf-*) */
.cf-page {
  /* --cf-accent is a *fill* colour (white text sits on it); --cf-accent-ink is
     the matching *text* colour on tinted/plain surfaces. They only diverge in
     dark mode — see the [data-theme="dark"] block at the end of this file. */
  --cf-accent: #0f766e;
  --cf-accent-ink: #0f766e;
  --cf-accent-soft: color-mix(in srgb, #0f766e 9%, var(--bg-secondary));
  --cf-new: #64748b;
  --cf-fuzzy: #c46a12;
  --cf-mastered: #16834a;
  width: min(1240px, calc(100% - 32px));
  margin: 0 auto;
  padding: 22px 0 64px;
}

.cf-header {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 18px;
  align-items: center;
  margin-bottom: 22px;
}

.cf-title-block { min-width: 0; }
.cf-title-block .mod-subject-badge { padding: 5px 12px; }
.cf-title-block .mod-badge-icon { display: flex; width: 22px; height: 22px; }
.cf-title-block .mod-badge-icon svg { width: 100%; height: 100%; }
.cf-title-block .mod-badge-text { font-size: 0.82rem; letter-spacing: 0; }
.cf-title-block h1 { margin: 10px 0 2px; font-size: 1.65rem; line-height: 1.2; letter-spacing: 0; }
.cf-title-block p { margin: 0; color: var(--text-tertiary); font-size: 0.82rem; }

.cf-continue-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 15px;
  border: 1px solid color-mix(in srgb, var(--cf-accent) 45%, var(--border));
  border-radius: 6px;
  background: var(--cf-accent);
  color: #fff;
  font: inherit;
  font-size: 0.86rem;
  font-weight: 650;
  cursor: pointer;
}
.cf-continue-btn svg { width: 17px; height: 17px; }
.cf-continue-btn:hover { background: color-mix(in srgb, var(--cf-accent) 88%, #000); }

.cf-dashboard {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(320px, 0.9fr);
  gap: 28px;
  align-items: center;
  margin: 0 0 18px;
  padding: 18px 20px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--cf-accent) 3%, var(--bg-secondary));
}

.cf-progress-summary {
  display: grid;
  grid-template-columns: auto minmax(120px, 1fr) auto;
  gap: 14px;
  align-items: center;
}
.cf-progress-value { display: flex; align-items: baseline; gap: 8px; white-space: nowrap; }
.cf-progress-value strong { color: var(--cf-accent-ink); font-size: 1.55rem; font-variant-numeric: tabular-nums; }
.cf-progress-value span, .cf-progress-count { color: var(--text-tertiary); font-size: 0.76rem; }
.cf-progress-count { font-variant-numeric: tabular-nums; white-space: nowrap; }
.cf-progress-track { height: 7px; overflow: hidden; border-radius: 4px; background: var(--bg-active); }
.cf-progress-track span { display: block; width: 0; height: 100%; background: var(--cf-accent); transition: width 180ms ease; }

.cf-stat-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(86px, 1fr));
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
}
.cf-stat {
  min-width: 0;
  padding: 9px 12px;
  border: 0;
  border-right: 1px solid var(--border);
  background: var(--bg-secondary);
  color: var(--text-primary);
  cursor: pointer;
  text-align: left;
}
.cf-stat:last-child { border-right: 0; }
.cf-stat:hover { background: var(--bg-hover); }
.cf-stat span { display: block; font-size: 1.15rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.cf-stat small { color: var(--text-tertiary); font-size: 0.7rem; }
.cf-stat--new span { color: var(--cf-new); }
.cf-stat--fuzzy span { color: var(--cf-fuzzy); }
.cf-stat--mastered span { color: var(--cf-mastered); }

.cf-toolbar {
  position: sticky;
  top: calc(var(--nav-height) + 8px);
  z-index: 8;
  display: grid;
  grid-template-columns: minmax(230px, 1fr) auto;
  gap: 12px;
  align-items: center;
  margin-bottom: 16px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: color-mix(in srgb, var(--bg-secondary) 94%, transparent);
  box-shadow: var(--shadow-sm);
  backdrop-filter: blur(8px);
}
.cf-search { position: relative; display: flex; align-items: center; min-width: 0; }
.cf-search svg { position: absolute; left: 11px; width: 17px; height: 17px; color: var(--text-tertiary); pointer-events: none; }
.cf-search input {
  width: 100%;
  height: 36px;
  padding: 0 12px 0 36px;
  border: 1px solid var(--border);
  border-radius: 6px;
  outline: 0;
  background: var(--bg-primary);
  color: var(--text-primary);
  font: inherit;
  font-size: 0.82rem;
}
.cf-search input:focus { border-color: var(--cf-accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--cf-accent) 14%, transparent); }

.cf-filter {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
}
.cf-filter button {
  min-width: 64px;
  height: 34px;
  padding: 0 10px;
  border: 0;
  border-right: 1px solid var(--border);
  background: var(--bg-secondary);
  color: var(--text-secondary);
  font: inherit;
  font-size: 0.76rem;
  cursor: pointer;
}
.cf-filter button:last-child { border-right: 0; }
.cf-filter button:hover { background: var(--bg-hover); }
.cf-filter button[aria-pressed="true"] { background: var(--cf-accent-soft); color: var(--cf-accent-ink); font-weight: 650; }
.cf-unit-select { display: none; }

.cf-workspace {
  display: grid;
  grid-template-columns: 248px minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}
.cf-outline {
  position: sticky;
  top: calc(var(--nav-height) + 74px);
  max-height: calc(100vh - var(--nav-height) - 92px);
  overflow: auto;
  border-right: 1px solid var(--border);
  padding-right: 12px;
  scrollbar-width: thin;
}
.cf-outline-title { padding: 4px 9px 10px; color: var(--text-tertiary); font-size: 0.7rem; font-weight: 700; }
.cf-outline-item {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  gap: 9px;
  align-items: center;
  width: 100%;
  min-height: 52px;
  padding: 7px 9px;
  border: 0;
  border-left: 2px solid transparent;
  border-radius: 0 5px 5px 0;
  background: transparent;
  color: var(--text-secondary);
  text-align: left;
  cursor: pointer;
}
.cf-outline-item:hover { background: var(--bg-hover); }
.cf-outline-item.active { border-left-color: var(--cf-accent); background: var(--cf-accent-soft); color: var(--text-primary); }
.cf-outline-index { color: var(--text-tertiary); font-size: 0.67rem; font-variant-numeric: tabular-nums; text-align: center; }
.cf-outline-copy { min-width: 0; }
.cf-outline-copy strong, .cf-outline-copy small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cf-outline-copy strong { font-size: 0.76rem; font-weight: 600; }
.cf-outline-copy small { margin-top: 2px; color: var(--text-tertiary); font-size: 0.64rem; }
.cf-outline-percent { color: var(--text-tertiary); font-size: 0.66rem; font-variant-numeric: tabular-nums; }

.cf-content { min-width: 0; outline: 0; scroll-margin-top: calc(var(--nav-height) + 74px); }
.cf-content-head {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: end;
  min-height: 54px;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.cf-content-head span, .cf-unit-heading span { color: var(--cf-accent-ink); font-size: 0.68rem; font-weight: 700; }
.cf-content-head h2 { margin: 3px 0 0; font-size: 1.2rem; letter-spacing: 0; }
.cf-content-head > strong { color: var(--text-tertiary); font-size: 0.75rem; white-space: nowrap; }
.cf-unit-section { margin-bottom: 30px; }
.cf-results-hint {
  margin: -2px 0 8px;
  color: var(--text-tertiary);
  font-size: 0.72rem;
}
.cf-unit-heading {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: end;
  margin-bottom: 8px;
  padding: 7px 2px;
}
.cf-unit-heading h2 { margin: 3px 0 0; font-size: 1.02rem; letter-spacing: 0; }
.cf-unit-heading > div:last-child { color: var(--text-tertiary); font-size: 0.7rem; white-space: nowrap; }
.cf-item-list { border-top: 1px solid var(--border); }

.cf-item {
  --cf-status-color: var(--cf-new);
  border-bottom: 1px solid var(--border);
  border-left: 2px solid transparent;
  background: var(--bg-secondary);
  transition: border-color 120ms ease, background 120ms ease;
}
.cf-item--fuzzy { --cf-status-color: var(--cf-fuzzy); }
.cf-item--mastered { --cf-status-color: var(--cf-mastered); }
.cf-item.expanded { border-left-color: var(--cf-status-color); background: color-mix(in srgb, var(--cf-status-color) 2.5%, var(--bg-secondary)); }
.cf-item-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  min-height: 58px;
  padding: 7px 10px 7px 12px;
}
.cf-item-toggle {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto 20px;
  gap: 10px;
  align-items: center;
  min-width: 0;
  padding: 7px 2px;
  border: 0;
  background: transparent;
  color: var(--text-primary);
  text-align: left;
  cursor: pointer;
}
.cf-item-title-wrap { min-width: 0; display: grid; gap: 2px; }
.cf-item-kicker {
  color: var(--cf-accent-ink);
  font-size: 0.64rem;
  font-weight: 700;
  line-height: 1.2;
}
.cf-item-number {
  display: inline-flex;
  width: 30px;
  height: 26px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-tertiary);
  font-size: 0.68rem;
  font-variant-numeric: tabular-nums;
}
.cf-item-title { min-width: 0; overflow-wrap: anywhere; font-size: 0.88rem; font-weight: 620; line-height: 1.4; }
.cf-item-formula-preview {
  min-width: 0;
  overflow: hidden;
  color: var(--text-tertiary);
  font-family: "Cascadia Mono", "SFMono-Regular", Consolas, monospace;
  font-size: 0.68rem;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cf-item--equation:not(.expanded) .cf-item-header { min-height: 66px; }
.cf-item-state { color: var(--cf-status-color); font-size: 0.68rem; white-space: nowrap; }
.cf-item-chevron { display: flex; color: var(--text-tertiary); }
.cf-item-chevron svg { width: 16px; height: 16px; transition: transform 140ms ease; }
.cf-item.expanded .cf-item-chevron svg { transform: rotate(180deg); }

.cf-status-control {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 5px;
}
.cf-status-btn {
  min-width: 52px;
  height: 30px;
  padding: 0 7px;
  border: 0;
  border-right: 1px solid var(--border);
  background: var(--bg-primary);
  color: var(--text-tertiary);
  font: inherit;
  font-size: 0.68rem;
  cursor: pointer;
}
.cf-status-btn:last-child { border-right: 0; }
.cf-status-btn:hover { background: var(--bg-hover); color: var(--text-primary); }
.cf-status-btn--new[aria-pressed="true"] { background: color-mix(in srgb, var(--cf-new) 12%, var(--bg-secondary)); color: var(--cf-new); font-weight: 650; }
.cf-status-btn--fuzzy[aria-pressed="true"] { background: color-mix(in srgb, var(--cf-fuzzy) 12%, var(--bg-secondary)); color: var(--cf-fuzzy); font-weight: 650; }
.cf-status-btn--mastered[aria-pressed="true"] { background: color-mix(in srgb, var(--cf-mastered) 12%, var(--bg-secondary)); color: var(--cf-mastered); font-weight: 650; }

.cf-item-body {
  padding: 0 14px 16px 58px;
  animation: cf-reveal 140ms ease both;
}
@keyframes cf-reveal { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: translateY(0); } }
.cf-core-points { padding: 12px 0 14px; border-top: 1px dashed var(--border); }
.cf-core-points h3 { margin: 0 0 8px; color: var(--text-secondary); font-size: 0.72rem; }
.cf-core-points ul { display: grid; gap: 7px; margin: 0; padding: 0; list-style: none; }
.cf-core-points li { position: relative; padding-left: 15px; color: var(--text-secondary); font-size: 0.81rem; line-height: 1.65; }
.cf-core-points li::before { content: ''; position: absolute; top: 0.67em; left: 1px; width: 5px; height: 5px; border-radius: 50%; background: var(--cf-accent); }
.cf-equations { padding: 12px 0 14px; border-top: 1px dashed var(--border); }
.cf-equations h3 { margin: 0 0 8px; color: var(--text-secondary); font-size: 0.72rem; }
.cf-equations > div { display: grid; gap: 6px; }
.cf-equations code {
  display: block;
  width: 100%;
  padding: 8px 10px;
  overflow-x: auto;
  border: 1px solid color-mix(in srgb, var(--cf-accent) 16%, var(--border));
  border-radius: 4px;
  background: color-mix(in srgb, var(--cf-accent) 4%, var(--bg-primary));
  color: var(--text-primary);
  font-family: "Cascadia Mono", "SFMono-Regular", Consolas, monospace;
  font-size: 0.76rem;
  line-height: 1.55;
  white-space: nowrap;
}
.cf-item-notes { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.cf-note { min-width: 0; padding: 10px 12px; border-left: 2px solid; background: var(--bg-primary); }
.cf-note--pitfall { border-left-color: var(--cf-fuzzy); }
.cf-note--check { border-left-color: #2563a8; }
.cf-note strong { display: block; margin-bottom: 4px; color: var(--text-secondary); font-size: 0.68rem; }
.cf-note p { margin: 0; color: var(--text-secondary); font-size: 0.77rem; line-height: 1.6; overflow-wrap: anywhere; }

.cf-empty, .cf-load-error, .cf-loading {
  display: flex;
  min-height: 320px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  color: var(--text-tertiary);
  text-align: center;
}
.cf-empty svg, .cf-load-error svg, .cf-loading svg { width: 32px; height: 32px; }
.cf-loading svg { animation: spin 0.8s linear infinite; }
.cf-empty h2, .cf-load-error h1 { margin: 0; color: var(--text-primary); font-size: 1rem; }
.cf-empty button, .cf-load-error button { padding: 8px 12px; border: 1px solid var(--border); border-radius: 5px; background: var(--bg-secondary); color: var(--text-primary); cursor: pointer; }

.cf-overview-panel {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  align-items: end;
  margin-bottom: 14px;
  padding: 16px 18px;
  border: 1px solid color-mix(in srgb, var(--cf-accent) 16%, var(--border));
  border-left: 3px solid var(--cf-accent);
  background: color-mix(in srgb, var(--cf-accent) 4%, var(--bg-secondary));
}
.cf-overview-eyebrow { color: var(--cf-accent-ink); font-size: 0.68rem; font-weight: 700; }
.cf-overview-panel h2 { margin: 4px 0 3px; font-size: 1.05rem; }
.cf-overview-panel p { margin: 0; color: var(--text-tertiary); font-size: 0.76rem; line-height: 1.5; }
.cf-overview-total { display: grid; gap: 2px; flex: 0 0 auto; text-align: right; }
.cf-overview-total strong { color: var(--cf-accent-ink); font-size: 1.35rem; font-variant-numeric: tabular-nums; }
.cf-overview-total span { color: var(--text-tertiary); font-size: 0.7rem; }
.cf-category-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.cf-category-card {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr) auto;
  gap: 8px 10px;
  align-items: start;
  min-width: 0;
  padding: 13px 14px 11px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-secondary);
  color: var(--text-primary);
  text-align: left;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease, transform 120ms ease;
}
.cf-category-card:hover { border-color: color-mix(in srgb, var(--cf-accent) 48%, var(--border)); background: var(--bg-hover); transform: translateY(-1px); }
.cf-category-card--equation { border-left: 3px solid color-mix(in srgb, var(--cf-accent) 65%, var(--border)); }
.cf-category-index { color: var(--text-tertiary); font-size: 0.68rem; font-variant-numeric: tabular-nums; }
.cf-category-copy { min-width: 0; }
.cf-category-copy strong, .cf-category-copy small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cf-category-copy strong { font-size: 0.8rem; line-height: 1.35; }
.cf-category-copy small { margin-top: 3px; color: var(--text-tertiary); font-size: 0.68rem; }
.cf-category-count { color: var(--text-tertiary); font-size: 0.68rem; white-space: nowrap; }
.cf-category-progress { grid-column: 1 / -1; height: 4px; overflow: hidden; background: var(--bg-active); }
.cf-category-progress i { display: block; height: 100%; background: var(--cf-accent); }
.cf-category-footer { grid-column: 1 / -1; display: flex; justify-content: space-between; gap: 8px; align-items: center; color: var(--text-tertiary); font-size: 0.68rem; }
.cf-category-footer span { display: inline-flex; align-items: center; gap: 3px; color: var(--cf-accent-ink); font-weight: 650; }
.cf-category-footer svg { width: 13px; height: 13px; }
.cf-pagination { display: flex; justify-content: space-between; gap: 14px; align-items: center; margin-top: 14px; padding: 10px 2px; color: var(--text-tertiary); font-size: 0.72rem; }
.cf-pagination-controls { display: flex; align-items: center; gap: 8px; }
.cf-pagination-controls button { display: inline-flex; align-items: center; gap: 3px; min-height: 30px; padding: 0 8px; border: 1px solid var(--border); border-radius: 5px; background: var(--bg-secondary); color: var(--text-secondary); font: inherit; cursor: pointer; }
.cf-pagination-controls button:hover:not(:disabled) { border-color: var(--cf-accent); color: var(--cf-accent); }
.cf-pagination-controls button:disabled { opacity: 0.45; cursor: not-allowed; }
.cf-pagination-controls svg { width: 14px; height: 14px; }
.cf-pagination-current { min-width: 74px; text-align: center; font-variant-numeric: tabular-nums; }

@media (max-width: 920px) {
  .cf-page { width: min(100% - 24px, 820px); }
  .cf-dashboard { grid-template-columns: 1fr; gap: 16px; }
  .cf-toolbar { grid-template-columns: minmax(0, 1fr) auto; }
  .cf-unit-select {
    display: block;
    grid-column: 1 / -1;
    width: 100%;
    height: 36px;
    padding: 0 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-secondary);
    color: var(--text-primary);
    font: inherit;
    font-size: 0.8rem;
  }
  .cf-workspace { grid-template-columns: 1fr; }
  .cf-outline { display: none; }
  .cf-category-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 680px) {
  .cf-page { width: calc(100% - 18px); padding-top: 12px; }
  .cf-header { grid-template-columns: auto minmax(0, 1fr); gap: 10px; }
  .cf-title-block h1 { font-size: 1.3rem; }
  .cf-continue-btn { grid-column: 1 / -1; justify-content: center; }
  .cf-dashboard { padding: 14px 12px; }
  .cf-progress-summary { grid-template-columns: auto minmax(80px, 1fr); }
  .cf-progress-count { grid-column: 2; }
  .cf-toolbar { top: calc(var(--nav-height) + 4px); grid-template-columns: 1fr; padding: 8px; }
  .cf-filter { width: 100%; }
  .cf-filter button { min-width: 0; padding: 0 5px; }
  .cf-item-header { grid-template-columns: 1fr; gap: 4px; padding: 7px 8px 9px; }
  .cf-item-toggle { grid-template-columns: 30px minmax(0, 1fr) auto 18px; gap: 7px; }
  .cf-status-control { margin-left: 37px; }
  .cf-status-btn { min-width: 0; }
  .cf-item-body { padding: 0 10px 14px 45px; }
  .cf-item-notes { grid-template-columns: 1fr; }
  .cf-overview-panel { align-items: start; flex-direction: column; gap: 8px; }
  .cf-overview-total { text-align: left; }
  .cf-category-grid { grid-template-columns: 1fr; }
  .cf-pagination { align-items: stretch; flex-direction: column; }
  .cf-pagination-controls { justify-content: space-between; }
}

@media (max-width: 430px) {
  .cf-stat { padding: 8px; text-align: center; }
  .cf-progress-value strong { font-size: 1.3rem; }
  .cf-item-state { display: none; }
  .cf-item-toggle { grid-template-columns: 30px minmax(0, 1fr) 18px; }
  .cf-item--equation:not(.expanded) .cf-item-header { min-height: 62px; }
  .cf-item-formula-preview { max-width: calc(100vw - 100px); }
}

/* ===== Legibility floor =====
   This page is the densest in the app (24 categories × ~500 rows), and it had
   drifted to 0.68rem (10.9px) for most secondary text — below a comfortable
   reading size for sustained study. Raise the floor to 0.72rem (11.5px) for
   labels and 0.76rem for anything carrying real content. */
.cf-outline-title,
.cf-content-head span,
.cf-unit-heading span,
.cf-unit-heading > div:last-child,
.cf-item-state,
.cf-note strong,
.cf-overview-eyebrow,
.cf-category-index,
.cf-category-copy small,
.cf-category-count,
.cf-category-footer,
.cf-stat small,
.cf-overview-total span { font-size: 0.72rem; }
.cf-core-points h3,
.cf-equations h3,
.cf-pagination,
.cf-overview-panel p { font-size: 0.76rem; }
/* Second pass: the sidebar copy, the per-row kicker and the item-row <small>
   labels were still at 0.64–0.68rem (10.2–10.9px) after the first floor.
   NOTE: <small> must be set explicitly — the UA sheet's `font-size: smaller`
   multiplies the parent (0.83x), so a footer at 0.72rem still rendered its
   <small> at 9.6px. */
.cf-outline-copy small,
.cf-outline-percent,
.cf-outline-index,
.cf-item-kicker,
.cf-category-footer small { font-size: 0.72rem; }

/* ===== Dark theme =====
   The base tokens above are tuned for light surfaces. In dark mode the teal is
   too dark to read (active filter text sat at 3.5:1), so text moves to a
   lighter teal while the fill stays deep enough for white text on top. */
[data-theme="dark"] .cf-page {
  --cf-accent: #0f766e;
  --cf-accent-ink: #4fd1c5;
  --cf-accent-soft: color-mix(in srgb, #4fd1c5 14%, var(--bg-secondary));
  --cf-new: #94a3b8;
  --cf-fuzzy: #e0964a;
  --cf-mastered: #4ade80;
}
/* ==== pages/chem-specialties.css ==== */
/* Science experiment specialty training (.ce-*) */
.ce-page {
  --ce-accent: #b45309;
  width: min(100%, 1180px);
  margin: 0 auto;
  padding: 8px 0 40px;
  color: var(--text-primary);
}

.ce-page *, .ce-page *::before, .ce-page *::after { box-sizing: border-box; }
.ce-page button, .ce-page input, .ce-page select, .ce-page textarea { font: inherit; letter-spacing: 0; }
.ce-page button { color: inherit; }

.ce-header {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
  margin-bottom: 24px;
}
.ce-title-block { min-width: 0; }
.ce-title-block .mod-subject-badge { margin-bottom: 10px; padding: 4px 12px; }
.ce-title-block .mod-badge-text { font-size: 0.78rem; }
.ce-title-block .mod-badge-icon { display: inline-flex; width: 18px; height: 18px; }
.ce-title-block .mod-badge-icon svg { width: 100%; height: 100%; }
.ce-title-block h1 { margin: 0; font-size: 1.65rem; line-height: 1.25; letter-spacing: 0; }
.ce-title-block > p { margin: 6px 0 0; color: var(--text-tertiary); font-size: 0.82rem; line-height: 1.55; }

.ce-loading, .ce-load-error {
  display: flex;
  min-height: 380px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  color: var(--text-tertiary);
  text-align: center;
}
.ce-loading > span, .ce-load-error > svg { width: 34px; height: 34px; color: var(--ce-accent); }
.ce-loading svg { width: 100%; height: 100%; animation: spin 0.8s linear infinite; }
.ce-load-error h1 { margin: 4px 0 0; color: var(--text-primary); font-size: 1.1rem; }
.ce-load-error p { margin: 0; }
.ce-load-error button {
  min-height: 34px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-secondary);
  cursor: pointer;
}

/* Specialty hub */
.ce-hub-summary {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 24px;
  padding: 20px 22px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--ce-accent) 4%, var(--bg-primary));
}
.ce-hub-summary__copy > span, .ce-kicker, .ce-section-label {
  color: var(--ce-accent);
  font-size: 0.67rem;
  font-weight: 750;
  letter-spacing: 0;
}
.ce-hub-summary h2 { margin: 6px 0 4px; font-size: 1.35rem; letter-spacing: 0; }
.ce-hub-summary p { margin: 0; color: var(--text-secondary); font-size: 0.8rem; line-height: 1.55; }
.ce-hub-progress { display: grid; min-width: 190px; grid-template-columns: 1fr auto; gap: 2px 12px; align-items: end; }
.ce-hub-progress strong { color: var(--ce-accent); font-size: 1.55rem; font-variant-numeric: tabular-nums; }
.ce-hub-progress > span { color: var(--text-tertiary); font-size: 0.72rem; }
.ce-hub-progress i { grid-column: 1 / -1; display: block; height: 5px; overflow: hidden; background: var(--bg-active); }
.ce-hub-progress b { display: block; height: 100%; background: var(--ce-accent); }

.ce-specialty-entry { margin-top: 20px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-secondary); overflow: hidden; }
.ce-specialty-entry__main {
  display: grid;
  grid-template-columns: 58px minmax(0, 1fr) auto;
  gap: 18px;
  align-items: center;
  padding: 22px;
}
.ce-specialty-icon {
  display: grid;
  width: 58px;
  height: 58px;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--ce-accent) 28%, var(--border));
  border-radius: 8px;
  background: color-mix(in srgb, var(--ce-accent) 8%, var(--bg-secondary));
  color: var(--ce-accent);
}
.ce-specialty-icon svg { width: 28px; height: 28px; }
.ce-specialty-entry__main h2 { margin: 5px 0 4px; font-size: 1.15rem; letter-spacing: 0; }
.ce-specialty-entry__main p { margin: 0; color: var(--text-tertiary); font-size: 0.78rem; line-height: 1.55; overflow-wrap: anywhere; }
.ce-primary-button {
  display: inline-flex;
  min-height: 38px;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 14px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: var(--ce-accent);
  color: #fff !important;
  font-size: 0.8rem;
  font-weight: 700;
  cursor: pointer;
  transition: filter 120ms ease, transform 120ms ease;
}
.ce-primary-button:hover { filter: brightness(1.08); transform: translateY(-1px); }
.ce-primary-button svg { width: 16px; height: 16px; }

.ce-mini-chain {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: var(--bg-primary);
}
.ce-mini-step {
  display: grid;
  gap: 3px;
  min-width: 0;
  padding: 13px 12px;
  border-right: 1px solid var(--border);
}
.ce-mini-step:last-child { border-right: 0; }
.ce-mini-step > span { color: var(--text-tertiary); font-size: 0.64rem; font-variant-numeric: tabular-nums; }
.ce-mini-step strong { font-size: 0.78rem; }
.ce-mini-step small { color: var(--text-tertiary); font-size: 0.66rem; }
.ce-specialty-stats { display: grid; grid-template-columns: repeat(4, 1fr); padding: 16px 22px; }
.ce-specialty-stats > div { display: grid; gap: 3px; border-right: 1px solid var(--border); text-align: center; }
.ce-specialty-stats > div:last-child { border-right: 0; }
.ce-specialty-stats strong { color: var(--text-primary); font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.ce-specialty-stats span { color: var(--text-tertiary); font-size: 0.68rem; }

/* Trainer overview */
.ce-dashboard {
  display: grid;
  grid-template-columns: minmax(260px, 1.8fr) repeat(3, minmax(100px, 0.6fr));
  margin-bottom: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-secondary);
  overflow: hidden;
}
.ce-progress-block { padding: 14px 16px; border-right: 1px solid var(--border); }
.ce-progress-block > div:first-child { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.ce-progress-block span, .ce-stat span { color: var(--text-tertiary); font-size: 0.68rem; }
.ce-progress-block strong { color: var(--ce-accent); font-size: 1.25rem; font-variant-numeric: tabular-nums; }
.ce-progress-track { height: 5px; margin: 8px 0 5px; overflow: hidden; background: var(--bg-active); }
.ce-progress-track i { display: block; height: 100%; background: var(--ce-accent); }
.ce-progress-block small { color: var(--text-tertiary); font-size: 0.65rem; }
.ce-stat { display: grid; align-content: center; justify-items: center; gap: 2px; padding: 12px; border-right: 1px solid var(--border); }
.ce-stat:last-child { border-right: 0; }
.ce-stat strong { font-size: 1.18rem; font-variant-numeric: tabular-nums; }

.ce-chain-map {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  margin-bottom: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-secondary);
  overflow: hidden;
}
.ce-chain-node {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 7px;
  min-width: 0;
  padding: 11px 10px 9px;
  border-right: 1px solid var(--border);
  border-bottom: 3px solid transparent;
}
.ce-chain-node:last-child { border-right: 0; }
.ce-chain-node.is-active { border-bottom-color: var(--step-color); background: color-mix(in srgb, var(--step-color) 5%, var(--bg-secondary)); }
.ce-chain-node > span { color: var(--step-color); font-size: 0.62rem; font-weight: 750; font-variant-numeric: tabular-nums; }
.ce-chain-node div { min-width: 0; }
.ce-chain-node strong, .ce-chain-node small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ce-chain-node strong { font-size: 0.74rem; }
.ce-chain-node small { margin-top: 3px; color: var(--text-tertiary); font-size: 0.6rem; }
.ce-chain-node > b { grid-column: 2; color: var(--text-tertiary); font-size: 0.62rem; font-weight: 600; }

.ce-toolbar {
  position: sticky;
  top: calc(var(--nav-height) + 4px);
  z-index: 20;
  display: grid;
  grid-template-columns: auto minmax(135px, 0.7fr) minmax(115px, 0.55fr) 1fr 34px;
  gap: 8px;
  align-items: end;
  margin-bottom: 12px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: color-mix(in srgb, var(--bg-primary) 92%, transparent);
  backdrop-filter: blur(12px);
}
.ce-mode-switch, .ce-status-filter { display: inline-flex; min-height: 34px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-secondary); overflow: hidden; }
.ce-mode-switch button, .ce-status-filter button {
  min-width: 0;
  padding: 0 10px;
  border: 0;
  border-right: 1px solid var(--border);
  background: transparent;
  color: var(--text-tertiary);
  font-size: 0.7rem;
  white-space: nowrap;
  cursor: pointer;
}
.ce-mode-switch button:last-child, .ce-status-filter button:last-child { border-right: 0; }
.ce-mode-switch button[aria-pressed="true"] { background: var(--ce-accent); color: #fff; }
.ce-status-filter button[aria-pressed="true"] { background: var(--bg-active); color: var(--text-primary); font-weight: 700; }
.ce-toolbar > label { display: grid; gap: 3px; color: var(--text-tertiary); font-size: 0.61rem; }
.ce-toolbar select {
  width: 100%;
  height: 34px;
  padding: 0 28px 0 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-secondary);
  color: var(--text-primary);
  font-size: 0.72rem;
}
.ce-icon-button {
  display: grid;
  width: 34px;
  height: 34px;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-secondary);
  color: var(--text-secondary);
  cursor: pointer;
}
.ce-icon-button:hover { border-color: var(--ce-accent); color: var(--ce-accent); }
.ce-icon-button svg { width: 16px; height: 16px; }

/* Scenario queue + practice */
.ce-workspace { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 12px; align-items: start; }
.ce-queue {
  position: sticky;
  top: calc(var(--nav-height) + 58px);
  max-height: calc(100vh - var(--nav-height) - 74px);
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-secondary);
}
.ce-queue__head { display: flex; align-items: center; justify-content: space-between; padding: 11px 12px; border-bottom: 1px solid var(--border); }
.ce-queue__head span { color: var(--text-secondary); font-size: 0.7rem; font-weight: 700; }
.ce-queue__head strong { color: var(--text-tertiary); font-size: 0.68rem; font-variant-numeric: tabular-nums; }
.ce-queue__list { max-height: calc(100vh - var(--nav-height) - 118px); overflow-y: auto; }
.ce-queue-item {
  display: grid;
  grid-template-columns: 25px minmax(0, 1fr) 8px;
  gap: 8px;
  align-items: center;
  width: 100%;
  min-height: 58px;
  padding: 8px 10px;
  border: 0;
  border-bottom: 1px solid var(--border-light);
  background: transparent;
  text-align: left;
  cursor: pointer;
}
.ce-queue-item:last-child { border-bottom: 0; }
.ce-queue-item:hover { background: var(--bg-hover); }
.ce-queue-item.is-active { background: color-mix(in srgb, var(--ce-accent) 8%, var(--bg-secondary)); box-shadow: inset 2px 0 var(--ce-accent); }
.ce-queue-index { color: var(--text-tertiary); font-size: 0.62rem; font-variant-numeric: tabular-nums; }
.ce-queue-copy { min-width: 0; }
.ce-queue-copy strong, .ce-queue-copy small { display: block; }
.ce-queue-copy strong { color: var(--text-secondary); font-size: 0.72rem; line-height: 1.4; overflow-wrap: anywhere; }
.ce-queue-item.is-active .ce-queue-copy strong { color: var(--text-primary); }
.ce-queue-copy small { margin-top: 4px; color: var(--text-tertiary); font-size: 0.61rem; }
.ce-status-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text-tertiary); }
.ce-status-dot--practiced { background: #d97706; }
.ce-status-dot--mastered { background: #15803d; }
.ce-queue-empty { padding: 28px 12px; color: var(--text-tertiary); font-size: 0.72rem; text-align: center; }
.ce-queue-empty p { margin: 0 0 10px; }
.ce-queue-empty button { min-height: 30px; border: 1px solid var(--border); border-radius: 5px; background: var(--bg-primary); cursor: pointer; }

.ce-practice { min-width: 0; scroll-margin-top: calc(var(--nav-height) + 12px); border: 1px solid var(--border); border-radius: 8px; background: var(--bg-secondary); overflow: hidden; }
.ce-scenario-head { display: flex; justify-content: space-between; gap: 20px; padding: 18px 20px 15px; }
.ce-scenario-head > div:first-child { min-width: 0; }
.ce-scenario-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.ce-scenario-tags span { padding: 3px 7px; border: 1px solid var(--border); border-radius: 4px; color: var(--text-tertiary); font-size: 0.62rem; }
.ce-scenario-head h2 { margin: 9px 0 4px; font-size: 1.18rem; line-height: 1.35; letter-spacing: 0; overflow-wrap: anywhere; }
.ce-scenario-head p { margin: 0; color: var(--text-tertiary); font-size: 0.74rem; line-height: 1.55; }
.ce-timer-wrap { display: grid; align-content: start; justify-items: end; flex: 0 0 auto; }
.ce-timer-wrap span { color: var(--text-tertiary); font-size: 0.61rem; }
.ce-timer-wrap strong { margin-top: 3px; font-size: 1.02rem; font-variant-numeric: tabular-nums; }

.ce-material { padding: 16px 20px; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); background: var(--bg-primary); }
.ce-material > p { margin: 7px 0 9px; color: var(--text-secondary); font-size: 0.79rem; line-height: 1.75; }
.ce-material > ul { display: grid; gap: 4px; margin: 0; padding-left: 18px; }
.ce-material > ul li { color: var(--text-tertiary); font-size: 0.7rem; line-height: 1.6; }
.ce-apparatus {
  display: flex;
  align-items: stretch;
  gap: 6px;
  margin-top: 14px;
  overflow-x: auto;
  padding-bottom: 3px;
}
.ce-apparatus-node {
  display: grid;
  min-width: 104px;
  min-height: 58px;
  align-content: center;
  gap: 4px;
  padding: 8px 9px;
  border: 1px solid var(--border);
  border-top: 2px solid color-mix(in srgb, var(--ce-accent) 70%, var(--border));
  border-radius: 5px;
  background: var(--bg-secondary);
}
.ce-apparatus-node span { color: var(--ce-accent); font-size: 0.59rem; font-weight: 750; }
.ce-apparatus-node strong { font-size: 0.67rem; font-weight: 650; line-height: 1.35; overflow-wrap: anywhere; }
.ce-flow-arrow { display: grid; min-width: 16px; place-items: center; color: var(--text-tertiary); }
.ce-flow-arrow svg { width: 15px; height: 15px; }

.ce-step-nav { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); border-bottom: 1px solid var(--border); background: var(--bg-secondary); }
.ce-step-nav button {
  display: grid;
  min-width: 0;
  min-height: 52px;
  place-items: center;
  gap: 2px;
  padding: 6px 3px;
  border: 0;
  border-right: 1px solid var(--border);
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--text-tertiary);
  cursor: pointer;
}
.ce-step-nav button:last-child { border-right: 0; }
.ce-step-nav button:hover { background: var(--bg-hover); color: var(--text-primary); }
.ce-step-nav button.is-active { border-bottom-color: var(--ce-accent); color: var(--ce-accent); background: color-mix(in srgb, var(--ce-accent) 4%, var(--bg-secondary)); }
.ce-step-nav button.is-done { color: #15803d; }
.ce-step-nav button span { display: grid; width: 20px; height: 20px; place-items: center; border: 1px solid currentColor; border-radius: 50%; font-size: 0.58rem; font-variant-numeric: tabular-nums; }
.ce-step-nav button svg { width: 11px; height: 11px; }
.ce-step-nav button strong { max-width: 100%; font-size: 0.63rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.ce-step-panel { padding: 22px 20px 20px; scroll-margin-top: calc(var(--nav-height) + 12px); border-left: 3px solid var(--step-color); }
.ce-step-title { display: flex; gap: 12px; align-items: start; }
.ce-step-title > span { padding-top: 3px; color: var(--step-color); font-size: 0.62rem; font-weight: 800; }
.ce-step-title h3 { margin: 0; font-size: 1.02rem; }
.ce-step-title p { margin: 3px 0 0; color: var(--text-tertiary); font-size: 0.68rem; }
.ce-prompt { display: grid; gap: 5px; margin: 17px 0 12px; }
.ce-prompt strong { font-size: 0.86rem; line-height: 1.65; }
.ce-prompt small { color: var(--text-tertiary); font-size: 0.68rem; }
.ce-answer-box { position: relative; display: grid; gap: 6px; }
.ce-answer-box > span { color: var(--text-secondary); font-size: 0.68rem; font-weight: 700; }
.ce-answer-box textarea {
  width: 100%;
  min-height: 112px;
  resize: vertical;
  padding: 11px 12px 25px;
  border: 1px solid var(--border);
  border-radius: 6px;
  outline: 0;
  background: var(--bg-primary);
  color: var(--text-primary);
  font-size: 0.78rem;
  line-height: 1.7;
}
.ce-answer-box textarea:focus { border-color: var(--step-color, var(--ce-accent)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--step-color, var(--ce-accent)) 13%, transparent); }
.ce-answer-box > small { position: absolute; right: 9px; bottom: 7px; color: var(--text-tertiary); font-size: 0.59rem; pointer-events: none; }
.ce-step-actions, .ce-submit-row { display: flex; justify-content: flex-end; margin-top: 12px; }

.ce-reference { margin-top: 14px; border: 1px solid color-mix(in srgb, var(--step-color) 28%, var(--border)); border-radius: 6px; overflow: hidden; }
.ce-reference__answer { padding: 13px 14px; background: color-mix(in srgb, var(--step-color) 5%, var(--bg-primary)); }
.ce-reference__answer span { color: var(--step-color); font-size: 0.65rem; font-weight: 800; }
.ce-reference__answer p { margin: 6px 0 0; color: var(--text-secondary); font-size: 0.76rem; line-height: 1.75; white-space: pre-line; }
.ce-reference__grid { display: grid; grid-template-columns: 1fr 1fr; border-top: 1px solid var(--border); }
.ce-reference__grid > div { padding: 11px 13px; }
.ce-reference__grid > div + div { border-left: 1px solid var(--border); }
.ce-reference__grid strong { display: block; margin-bottom: 6px; color: var(--text-secondary); font-size: 0.65rem; }
.ce-reference__grid ul { display: grid; gap: 4px; margin: 0; padding-left: 16px; }
.ce-reference__grid li, .ce-reference__grid p { color: var(--text-tertiary); font-size: 0.67rem; line-height: 1.55; }
.ce-reference__grid p { margin: 0; }
.ce-pitfall { background: color-mix(in srgb, #be123c 4%, var(--bg-secondary)); }
.ce-pitfall strong { color: #be123c; }

.ce-rating { display: grid; grid-template-columns: minmax(75px, 1fr) repeat(3, minmax(92px, auto)); gap: 6px; align-items: center; padding: 9px; border-top: 1px solid var(--border); background: var(--bg-secondary); }
.ce-rating > span { color: var(--text-tertiary); font-size: 0.64rem; font-weight: 700; }
.ce-rating button {
  display: flex;
  min-height: 34px;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 0 9px;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--bg-primary);
  cursor: pointer;
}
.ce-rating button:hover { border-color: var(--step-color); }
.ce-rating button[aria-pressed="true"] { border-color: var(--step-color); background: color-mix(in srgb, var(--step-color) 9%, var(--bg-secondary)); color: var(--step-color); }
.ce-rating button strong { font-size: 0.65rem; }
.ce-rating button small { color: var(--text-tertiary); font-size: 0.58rem; }

.ce-full-chain { display: grid; gap: 10px; padding: 16px; background: var(--bg-primary); }
.ce-full-step { min-width: 0; padding: 14px; border: 1px solid var(--border); border-left: 3px solid var(--step-color); border-radius: 6px; background: var(--bg-secondary); }
.ce-full-step__head { display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 8px; align-items: start; margin-bottom: 10px; }
.ce-full-step__head > span { color: var(--step-color); font-size: 0.62rem; font-weight: 800; }
.ce-full-step__head strong, .ce-full-step__head small { display: block; }
.ce-full-step__head strong { font-size: 0.77rem; }
.ce-full-step__head small { margin-top: 3px; color: var(--text-tertiary); font-size: 0.67rem; line-height: 1.5; }
.ce-full-step .ce-answer-box textarea { min-height: 92px; }
.ce-full-step .ce-reference { --step-color: inherit; }

.ce-completion { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 16px; align-items: center; padding: 22px 20px; border-left: 3px solid #15803d; background: color-mix(in srgb, #15803d 5%, var(--bg-secondary)); }
.ce-completion-score { display: flex; align-items: baseline; color: #15803d; }
.ce-completion-score strong { font-size: 2rem; font-variant-numeric: tabular-nums; }
.ce-completion-score span { font-size: 0.78rem; }
.ce-completion-copy > span { color: #15803d; font-size: 0.64rem; font-weight: 750; }
.ce-completion-copy h3 { margin: 4px 0; font-size: 0.95rem; }
.ce-completion-copy p { margin: 0; color: var(--text-tertiary); font-size: 0.68rem; line-height: 1.55; }
.ce-completion-actions { display: flex; gap: 7px; }
.ce-completion-actions button {
  display: inline-flex;
  min-height: 36px;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-secondary);
  font-size: 0.69rem;
  cursor: pointer;
}
.ce-completion-actions button.is-primary { border-color: #15803d; background: #15803d; color: #fff; }
.ce-completion-actions svg { width: 14px; height: 14px; }
.ce-completion > small { grid-column: 1 / -1; padding-top: 12px; border-top: 1px solid var(--border); color: var(--text-tertiary); font-size: 0.66rem; line-height: 1.55; }

@media (max-width: 1020px) {
  .ce-page { width: min(100% - 24px, 900px); }
  .ce-chain-map { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .ce-chain-node:nth-child(4) { border-right: 0; }
  .ce-chain-node:nth-child(-n+4) { border-bottom-color: var(--border); }
  .ce-chain-node.is-active { border-bottom-color: var(--step-color); }
  .ce-toolbar { grid-template-columns: auto 1fr 1fr 34px; }
  .ce-status-filter { grid-column: 1 / -1; }
  .ce-status-filter button { flex: 1; }
}

@media (max-width: 780px) {
  .ce-page { width: calc(100% - 18px); padding-top: 4px; }
  .ce-header { gap: 10px; margin-bottom: 16px; }
  .ce-title-block h1 { font-size: 1.35rem; }
  .ce-hub-summary { align-items: start; flex-direction: column; gap: 12px; padding: 16px; }
  .ce-hub-progress { width: 100%; min-width: 0; }
  .ce-specialty-entry__main { grid-template-columns: 48px minmax(0, 1fr); padding: 16px; }
  .ce-specialty-icon { width: 48px; height: 48px; }
  .ce-specialty-entry__main .ce-primary-button { grid-column: 1 / -1; }
  .ce-mini-chain { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .ce-mini-step:nth-child(4) { border-right: 0; }
  .ce-mini-step:nth-child(-n+4) { border-bottom: 1px solid var(--border); }
  .ce-specialty-stats { grid-template-columns: repeat(2, 1fr); gap: 14px 0; padding: 14px; }
  .ce-specialty-stats > div:nth-child(2) { border-right: 0; }
  .ce-specialty-stats > div:nth-child(-n+2) { padding-bottom: 12px; border-bottom: 1px solid var(--border); }
  .ce-dashboard { grid-template-columns: repeat(3, 1fr); }
  .ce-progress-block { grid-column: 1 / -1; border-right: 0; border-bottom: 1px solid var(--border); }
  .ce-chain-map { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ce-chain-node, .ce-chain-node:nth-child(4) { border-right: 1px solid var(--border); border-bottom-color: var(--border); }
  .ce-chain-node:nth-child(even) { border-right: 0; }
  .ce-chain-node:last-child { border-bottom: 0; }
  .ce-chain-node.is-active { border-bottom-color: var(--step-color); }
  .ce-toolbar { position: static; grid-template-columns: 1fr 1fr 34px; }
  .ce-mode-switch { grid-column: 1 / -1; }
  .ce-mode-switch button { flex: 1; }
  .ce-status-filter { grid-column: 1 / -1; overflow-x: auto; }
  .ce-workspace { grid-template-columns: 1fr; }
  .ce-queue { position: static; max-height: none; }
  .ce-queue__list { display: flex; max-height: none; overflow-x: auto; overflow-y: hidden; }
  .ce-queue-item { min-width: 210px; border-right: 1px solid var(--border); border-bottom: 0; }
  .ce-queue-item.is-active { box-shadow: inset 0 -2px var(--ce-accent); }
  .ce-step-nav { overflow-x: auto; grid-template-columns: repeat(7, minmax(64px, 1fr)); }
  .ce-reference__grid { grid-template-columns: 1fr; }
  .ce-reference__grid > div + div { border-top: 1px solid var(--border); border-left: 0; }
  .ce-rating { grid-template-columns: repeat(3, 1fr); }
  .ce-rating > span { grid-column: 1 / -1; }
  .ce-completion { grid-template-columns: auto minmax(0, 1fr); }
  .ce-completion-actions { grid-column: 1 / -1; }
  .ce-completion-actions button { flex: 1; justify-content: center; }
}

@media (max-width: 520px) {
  .ce-title-block .mod-subject-badge { margin-bottom: 6px; }
  .ce-dashboard { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ce-stat { padding: 9px 5px; }
  .ce-toolbar { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 34px; }
  .ce-toolbar > label { min-width: 0; }
  .ce-scenario-head { padding: 14px; }
  .ce-scenario-head h2 { font-size: 1.02rem; }
  .ce-material { padding: 14px; }
  .ce-step-panel { padding: 17px 13px 15px; }
  .ce-answer-box textarea { min-height: 126px; font-size: 0.8rem; }
  .ce-rating { gap: 4px; }
  .ce-rating button { min-height: 48px; flex-direction: column; justify-content: center; gap: 1px; padding: 4px; text-align: center; }
  .ce-full-chain { padding: 9px; }
  .ce-full-step { padding: 11px 9px; }
  .ce-completion { padding: 17px 13px; }
  .ce-completion-score strong { font-size: 1.65rem; }
  .ce-completion-actions { flex-direction: column; }
}

/* Model-generated multiple choice feedback */
.ce-mcq-empty, .ce-mcq-loading, .ce-mcq-error {
  display: flex;
  min-height: 94px;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px;
  border: 1px solid color-mix(in srgb, var(--step-color, var(--ce-accent)) 24%, var(--border));
  border-radius: 6px;
  background: color-mix(in srgb, var(--step-color, var(--ce-accent)) 4%, var(--bg-primary));
}
.ce-mcq-empty > div, .ce-mcq-loading > div, .ce-mcq-error > div { min-width: 0; }
.ce-mcq-empty strong, .ce-mcq-empty small, .ce-mcq-loading strong, .ce-mcq-loading small { display: block; }
.ce-mcq-empty strong { font-size: 0.78rem; }
.ce-mcq-empty small, .ce-mcq-loading small { margin-top: 5px; color: var(--text-tertiary); font-size: 0.66rem; line-height: 1.5; }
.ce-mcq-empty--compact { min-height: 72px; padding: 11px; }
.ce-mcq-empty--compact .ce-primary-button { min-height: 32px; padding: 0 10px; font-size: 0.68rem; }
.ce-mcq-empty--compact .ce-primary-button svg { width: 14px; height: 14px; }
.ce-mcq-loading { justify-content: flex-start; }
.ce-mcq-loading > span { display: grid; width: 25px; height: 25px; place-items: center; flex: 0 0 auto; color: var(--ce-accent); }
.ce-mcq-loading svg { width: 20px; height: 20px; animation: spin 0.8s linear infinite; }
.ce-mcq-loading strong { font-size: 0.76rem; }
.ce-mcq-error { min-height: 72px; border-color: color-mix(in srgb, #be123c 26%, var(--border)); background: color-mix(in srgb, #be123c 4%, var(--bg-primary)); }
.ce-mcq-error > div { display: flex; align-items: center; gap: 9px; }
.ce-mcq-error > div > svg { width: 23px; height: 23px; flex: 0 0 auto; color: #be123c; }
.ce-mcq-error strong, .ce-mcq-error small { display: block; }
.ce-mcq-error strong { color: #be123c; font-size: 0.74rem; }
.ce-mcq-error small { margin-top: 4px; color: var(--text-tertiary); font-size: 0.65rem; line-height: 1.45; overflow-wrap: anywhere; }
.ce-mcq-error > button { min-height: 32px; padding: 0 10px; border: 1px solid #be123c; border-radius: 5px; background: transparent; color: #be123c; font-size: 0.68rem; cursor: pointer; }
.ce-mcq { margin-top: 2px; }
.ce-mcq--compact { margin-top: 0; }
.ce-mcq-kicker { display: block; color: var(--step-color, var(--ce-accent)); font-size: 0.62rem; font-weight: 800; }
.ce-mcq-fallback-note { margin: 6px 0 0; padding: 7px 9px; border-left: 2px solid #b45309; background: color-mix(in srgb, #b45309 5%, var(--bg-primary)); color: var(--text-tertiary); font-size: 0.65rem; line-height: 1.5; }
.ce-mcq-question { margin: 7px 0 13px; color: var(--text-primary); font-size: 0.88rem; line-height: 1.7; }
.ce-mcq--compact .ce-mcq-question { font-size: 0.77rem; line-height: 1.6; }
.ce-mcq-options { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.ce-mcq-option {
  display: grid;
  grid-template-columns: 27px minmax(0, 1fr);
  gap: 9px;
  align-items: start;
  min-width: 0;
  min-height: 48px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-secondary);
  text-align: left;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease, transform 120ms ease;
}
.ce-mcq-option:hover:not(:disabled) { border-color: var(--step-color, var(--ce-accent)); background: color-mix(in srgb, var(--step-color, var(--ce-accent)) 5%, var(--bg-secondary)); transform: translateY(-1px); }
.ce-mcq-option > span { display: grid; width: 24px; height: 24px; place-items: center; border: 1px solid currentColor; border-radius: 50%; color: var(--text-tertiary); font-size: 0.67rem; font-weight: 800; }
.ce-mcq-option strong { min-width: 0; color: var(--text-secondary); font-size: 0.74rem; font-weight: 550; line-height: 1.55; overflow-wrap: anywhere; }
.ce-mcq-option[aria-pressed="true"] > span { color: inherit; }
.ce-mcq-option.is-correct { border-color: #15803d; background: color-mix(in srgb, #15803d 8%, var(--bg-secondary)); color: #15803d; }
.ce-mcq-option.is-wrong { border-color: #be123c; background: color-mix(in srgb, #be123c 7%, var(--bg-secondary)); color: #be123c; }
.ce-mcq-option.is-correct strong, .ce-mcq-option.is-wrong strong { color: inherit; }
.ce-mcq-option:disabled { cursor: default; opacity: 1; }
.ce-feedback { margin-top: 12px; padding: 12px 13px; border-left: 3px solid; border-radius: 4px; background: var(--bg-primary); }
.ce-feedback--correct { border-left-color: #15803d; background: color-mix(in srgb, #15803d 5%, var(--bg-primary)); }
.ce-feedback--wrong { border-left-color: #be123c; background: color-mix(in srgb, #be123c 5%, var(--bg-primary)); }
.ce-feedback-head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 5px 12px; }
.ce-feedback-head strong { font-size: 0.72rem; }
.ce-feedback--correct .ce-feedback-head strong { color: #15803d; }
.ce-feedback--wrong .ce-feedback-head strong { color: #be123c; }
.ce-feedback-head span { color: var(--text-tertiary); font-size: 0.65rem; }
.ce-feedback > p { margin: 7px 0 0; color: var(--text-secondary); font-size: 0.7rem; line-height: 1.65; }
.ce-feedback details { margin-top: 8px; color: var(--text-tertiary); font-size: 0.66rem; }
.ce-feedback summary { cursor: pointer; }
.ce-feedback ul { display: grid; gap: 4px; margin: 7px 0 0; padding-left: 17px; }
.ce-feedback li { line-height: 1.5; }
.ce-feedback li strong { margin-right: 4px; color: var(--text-secondary); }
.ce-mcq-retry { display: inline-flex; min-height: 30px; align-items: center; margin-top: 10px; padding: 0 10px; border: 1px solid var(--border); border-radius: 5px; background: var(--bg-secondary); color: var(--text-secondary); font-size: 0.66rem; cursor: pointer; }
.ce-mcq-retry:hover { border-color: var(--step-color, var(--ce-accent)); color: var(--step-color, var(--ce-accent)); }
.ce-full-chain__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 2px 2px 7px; }
.ce-full-chain__head span, .ce-full-chain__head strong { display: block; }
.ce-full-chain__head span { color: var(--ce-accent); font-size: 0.66rem; font-weight: 800; }
.ce-full-chain__head strong { margin-top: 3px; color: var(--text-tertiary); font-size: 0.7rem; font-weight: 500; }
.ce-full-chain__head .ce-primary-button { min-height: 34px; font-size: 0.7rem; }
.ce-full-step .ce-mcq-empty { min-height: 72px; }
.ce-full-step .ce-mcq-empty small { display: none; }

@media (max-width: 520px) {
  .ce-mcq-empty, .ce-mcq-loading, .ce-mcq-error { align-items: stretch; flex-direction: column; gap: 11px; }
  .ce-mcq-empty .ce-primary-button, .ce-mcq-error > button { width: 100%; }
  .ce-mcq-options { grid-template-columns: 1fr; }
  .ce-mcq-option { min-height: 52px; }
  .ce-full-chain__head { align-items: stretch; flex-direction: column; }
  .ce-full-chain__head .ce-primary-button { width: 100%; }
}

/* ===== Legibility floor =====
   The trainer is the densest reading surface in the app (13 scenarios x a
   7-step reasoning chain, plus MCQ feedback) and had drifted to 0.58–0.68rem
   (9.3–10.9px) for nearly every secondary label. Raise content-bearing text to
   at least 0.7rem (11.2px). Circular step markers and the apparatus diagram
   keep a slightly smaller size because their boxes are fixed-width and would
   clip, but nothing is left below 0.62rem (9.9px). */
.ce-mini-step small,
.ce-progress-block small,
.ce-progress-block span,
.ce-stat span,
.ce-specialty-stats span,
.ce-queue__head strong,
.ce-queue-index,
.ce-scenario-tags span,
.ce-apparatus-node strong,
.ce-step-title p,
.ce-prompt small,
.ce-answer-box > span,
.ce-reference__answer span,
.ce-reference__grid strong,
.ce-reference__grid li,
.ce-reference__grid p,
.ce-rating > span,
.ce-rating button small,
.ce-full-step__head small,
.ce-completion-copy p,
.ce-completion > small,
.ce-mcq-empty small,
.ce-mcq-loading small,
.ce-mcq-error small,
.ce-mcq-fallback-note,
.ce-feedback-head span,
.ce-feedback details,
.ce-mcq-retry,
.ce-full-chain__head span,
.ce-mcq-kicker,
.ce-mini-step > span,
.ce-chain-node small,
.ce-chain-node > b { font-size: 0.7rem; }
/* Fixed-width circular markers / step chips — raise but keep them fitting. */
.ce-chain-node > span,
.ce-step-title > span,
.ce-full-step__head > span,
.ce-step-nav button strong,
.ce-apparatus-node span,
.ce-completion-copy > span { font-size: 0.66rem; }
.ce-step-nav button span,
.ce-rating button strong,
.ce-mcq-option > span { font-size: 0.64rem; }
.ce-answer-box > small { font-size: 0.62rem; }
/* ==== pages/chn-memorization.css ==== */
/* 语文理解性默写专项 (.cm-*) */
.cm-page {
  --cm-accent: #c2410c;
  --cm-accent-soft: color-mix(in srgb, var(--cm-accent) 9%, var(--bg-secondary));
  width: min(1120px, calc(100% - 32px));
  margin: 0 auto;
  padding: 24px 0 64px;
}
.cm-header { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 18px; align-items: center; margin-bottom: 20px; }
.cm-heading { min-width: 0; }
.cm-eyebrow, .cm-kicker { color: var(--cm-accent); font-size: .68rem; font-weight: 750; letter-spacing: .12em; }
.cm-heading h1, .cm-session-header h1 { margin: 7px 0 4px; color: var(--text-primary); font-size: 1.7rem; line-height: 1.2; letter-spacing: 0; }
.cm-heading p, .cm-session-header p { margin: 0; color: var(--text-tertiary); font-size: .82rem; }
.cm-header-mark { display: flex; align-items: center; gap: 7px; padding: 8px 11px; border: 1px solid color-mix(in srgb, var(--cm-accent) 22%, var(--border)); background: var(--cm-accent-soft); color: var(--cm-accent); font-size: .74rem; font-weight: 700; }
.cm-header-mark svg { width: 17px; height: 17px; }
.cm-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 9px; margin-bottom: 20px; }
.cm-stat { min-width: 0; padding: 13px 15px 12px; border: 1px solid var(--border); background: var(--bg-secondary); }
.cm-stat--accent { border-top: 2px solid var(--cm-accent); }
.cm-stat span, .cm-stat small { display: block; color: var(--text-tertiary); font-size: .7rem; }
.cm-stat strong { display: inline-block; margin: 5px 5px 0 0; color: var(--text-primary); font-size: 1.45rem; line-height: 1; font-variant-numeric: tabular-nums; }
.cm-stat--accent strong { color: var(--cm-accent); }
.cm-status-summary { display: flex; gap: 9px; align-items: center; margin: -11px 0 19px; color: var(--text-tertiary); font-size: .7rem; }
.cm-status-summary b { padding: 4px 7px; font-size: .68rem; font-weight: 650; }
.cm-status-summary--remembered { color: var(--success); background: var(--success-light); }
.cm-status-summary--fuzzy { color: var(--warning); background: var(--warning-light); }
.cm-status-summary--forgot { color: var(--danger); background: var(--danger-light); }
.cm-selection { background: transparent; }
.cm-selection-head { display: flex; justify-content: space-between; gap: 16px; align-items: center; padding: 18px 20px 14px; border-bottom: 1px solid var(--border-light); }
.cm-selection-head h2 { margin: 5px 0 0; font-size: 1.06rem; }
.cm-mode-switch { display: inline-flex; gap: 3px; padding: 3px; border: 1px solid var(--border); background: var(--bg-primary); }
.cm-mode-switch button { display: inline-flex; align-items: center; gap: 6px; min-height: 31px; padding: 0 10px; border: 0; background: transparent; color: var(--text-tertiary); font: inherit; font-size: .74rem; cursor: pointer; }
.cm-mode-switch button svg { width: 14px; height: 14px; }
.cm-mode-switch button.is-active { background: var(--cm-accent); color: #fff; }
.cm-toolbar { display: flex; gap: 9px; align-items: center; padding: 12px 20px; }
.cm-search { display: flex; flex: 1 1 auto; gap: 8px; align-items: center; min-width: 0; max-width: 420px; height: 35px; padding: 0 10px; border: 1px solid var(--border); background: var(--bg-primary); color: var(--text-tertiary); }
.cm-search svg { width: 15px; height: 15px; flex: 0 0 auto; }
.cm-search input { width: 100%; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--text-primary); font: inherit; font-size: .78rem; }
.cm-select-all { height: 35px; padding: 0 11px; border: 1px solid var(--border); background: var(--bg-primary); color: var(--text-secondary); font: inherit; font-size: .74rem; cursor: pointer; }
.cm-select-all:hover { border-color: var(--cm-accent); color: var(--cm-accent); }
.cm-poem-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; padding: 0 20px 16px; }
.cm-poem-card { position: relative; min-width: 0; border: 1px solid var(--border); background: var(--bg-primary); transition: border-color 130ms ease, background 130ms ease; }
.cm-poem-card:hover, .cm-poem-card.is-selected { border-color: color-mix(in srgb, var(--cm-accent) 52%, var(--border)); background: var(--cm-accent-soft); }
.cm-poem-card.is-pinned { border-left: 3px solid var(--cm-accent); }
.cm-poem-main { display: grid; grid-template-columns: 27px minmax(0, 1fr) auto; gap: 8px; width: 100%; min-height: 74px; align-items: center; padding: 11px 41px 11px 12px; border: 0; background: transparent; color: inherit; text-align: left; cursor: pointer; }
.cm-poem-select { display: flex; width: 21px; height: 21px; align-items: center; justify-content: center; border: 1px solid var(--border-hover); color: var(--cm-accent); }
.cm-poem-select svg { width: 14px; height: 14px; }
.cm-poem-card:not(.is-selected) .cm-poem-select { color: transparent; }
.cm-checkbox { display: flex; width: 19px; height: 19px; align-items: center; justify-content: center; border: 1px solid var(--border-hover); }
.cm-checkbox.is-checked { border-color: var(--cm-accent); background: var(--cm-accent); color: #fff; }
.cm-checkbox svg { width: 13px; height: 13px; }
.cm-poem-copy { min-width: 0; }
.cm-poem-copy strong, .cm-poem-copy small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-poem-copy strong { color: var(--text-primary); font-size: .84rem; }
.cm-poem-copy small { margin-top: 4px; color: var(--text-tertiary); font-size: .7rem; }
.cm-poem-meta { display: grid; justify-items: end; gap: 2px; min-width: 43px; }
.cm-poem-meta b { color: var(--cm-accent); font-size: .94rem; font-variant-numeric: tabular-nums; }
.cm-poem-meta small { color: var(--text-tertiary); font-size: .65rem; }
.cm-last-status { margin-top: 3px; padding: 2px 4px; font-size: .62rem; font-style: normal; white-space: nowrap; }
.cm-last-status--remembered { color: var(--success); background: var(--success-light); }
.cm-last-status--fuzzy { color: var(--warning); background: var(--warning-light); }
.cm-last-status--forgot { color: var(--danger); background: var(--danger-light); }
.cm-last-status--new { color: var(--text-tertiary); background: var(--bg-active); }
.cm-pin { position: absolute; top: 10px; right: 10px; display: inline-flex; width: 25px; height: 25px; align-items: center; justify-content: center; border: 0; background: transparent; color: var(--text-tertiary); cursor: pointer; }
.cm-pin svg { width: 14px; height: 14px; }
.cm-pin:hover, .cm-pin.is-pinned { color: var(--cm-accent); }
.cm-selection-foot { display: flex; justify-content: space-between; gap: 12px; align-items: center; padding: 12px 20px; border-top: 1px solid var(--border-light); color: var(--text-tertiary); font-size: .74rem; }
.cm-start { display: inline-flex; gap: 7px; align-items: center; min-height: 35px; padding: 0 13px; background: var(--cm-accent); border-color: var(--cm-accent); }
.cm-start svg { width: 15px; height: 15px; }
.cm-start:disabled { opacity: .45; cursor: not-allowed; }
.cm-source-note { display: flex; gap: 7px; align-items: center; margin-top: 12px; color: var(--text-tertiary); font-size: .7rem; }
.cm-source-note svg { width: 14px; height: 14px; flex: 0 0 auto; color: var(--cm-accent); }
.cm-no-match { grid-column: 1 / -1; padding: 30px; color: var(--text-tertiary); text-align: center; font-size: .8rem; }
.cm-empty { display: flex; min-height: 290px; flex-direction: column; align-items: center; justify-content: center; gap: 9px; padding: 30px 20px; color: var(--text-tertiary); text-align: center; }
.cm-empty-mark { display: flex; width: 40px; height: 40px; align-items: center; justify-content: center; border: 1px solid color-mix(in srgb, var(--cm-accent) 26%, var(--border)); color: var(--cm-accent); font-size: 1.35rem; }
.cm-empty h2 { margin: 0; color: var(--text-primary); font-size: 1rem; }
.cm-empty p, .cm-empty span { margin: 0; font-size: .76rem; }
.cm-empty span { color: var(--cm-accent); }
.cm-loading { display: flex; min-height: 360px; flex-direction: column; align-items: center; justify-content: center; gap: 11px; color: var(--text-tertiary); font-size: .8rem; }
.cm-loading svg { width: 28px; height: 28px; color: var(--cm-accent); animation: spin .8s linear infinite; }

/* Session */
.cm-page--session { width: min(820px, calc(100% - 32px)); }
.cm-session-header { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 15px; align-items: center; margin-bottom: 17px; }
.cm-session-header h1 { font-size: 1.35rem; }
.cm-session-count { color: var(--cm-accent); font-size: 1.5rem; font-variant-numeric: tabular-nums; }
.cm-session-count small { color: var(--text-tertiary); font-size: .75rem; }
.cm-session-progress { height: 4px; margin-bottom: 16px; background: var(--bg-active); }
.cm-session-progress span { display: block; height: 100%; background: var(--cm-accent); transition: width 160ms ease; }
.cm-question-shell { border: 1px solid var(--border); background: var(--bg-secondary); }
.cm-question-meta { display: flex; gap: 9px; align-items: center; padding: 12px 18px; border-bottom: 1px solid var(--border-light); color: var(--text-tertiary); font-size: .72rem; }
.cm-question-history { margin-left: auto; }
.cm-source { display: inline-flex; align-items: center; padding: 3px 6px; font-size: .63rem; }
.cm-source--real { color: #2563a8; background: rgba(37, 99, 168, .1); }
.cm-source--ai { color: #7c3aed; background: rgba(124, 58, 237, .1); }
.cm-question-card { padding: 31px 35px 28px; }
.cm-prompt { min-height: 120px; color: var(--text-primary); font-size: 1.08rem; line-height: 2; white-space: pre-wrap; }
.cm-reveal { display: inline-flex; gap: 7px; align-items: center; min-height: 36px; margin-top: 24px; padding: 0 13px; border: 1px solid color-mix(in srgb, var(--cm-accent) 35%, var(--border)); background: var(--cm-accent-soft); color: var(--cm-accent); font: inherit; font-size: .78rem; cursor: pointer; }
.cm-reveal svg { width: 15px; height: 15px; }
.cm-answer { margin-top: 20px; padding: 15px 16px; border-left: 3px solid var(--cm-accent); background: var(--cm-accent-soft); }
.cm-answer span { display: block; margin-bottom: 8px; color: var(--cm-accent); font-size: .68rem; font-weight: 700; }
.cm-answer strong { display: block; color: var(--text-primary); font-size: 1rem; line-height: 1.8; white-space: pre-wrap; }
.cm-answer p { margin: 9px 0 0; color: var(--text-secondary); font-size: .76rem; line-height: 1.6; white-space: pre-wrap; }
.cm-session-actions { padding: 0 18px 18px; }
.cm-status-label { margin-bottom: 9px; color: var(--text-tertiary); font-size: .75rem; }
.cm-statuses { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; }
.cm-status { display: inline-flex; justify-content: center; gap: 6px; align-items: center; min-height: 39px; border: 1px solid var(--border); background: var(--bg-primary); color: var(--text-secondary); font: inherit; font-size: .78rem; cursor: pointer; }
.cm-status svg { width: 15px; height: 15px; }
.cm-status:hover { border-color: currentColor; }
.cm-status--remembered:hover { color: var(--success); background: var(--success-light); }
.cm-status--fuzzy:hover { color: var(--warning); background: var(--warning-light); }
.cm-status--forgot:hover { color: var(--danger); background: var(--danger-light); }
.cm-nav-actions { display: flex; justify-content: space-between; gap: 10px; margin-top: 18px; }
.cm-nav-btn { display: inline-flex; gap: 5px; align-items: center; min-height: 31px; padding: 0 8px; border: 0; background: transparent; color: var(--text-tertiary); font: inherit; font-size: .73rem; cursor: pointer; }
.cm-nav-btn svg { width: 15px; height: 15px; }
.cm-nav-btn:hover:not(:disabled) { color: var(--cm-accent); }
.cm-nav-btn:disabled { opacity: .35; cursor: not-allowed; }

@media (max-width: 720px) {
  .cm-page, .cm-page--session { width: calc(100% - 20px); padding-top: 14px; }
  .cm-header { grid-template-columns: auto minmax(0, 1fr); gap: 11px; }
  .cm-header-mark { grid-column: 2; justify-self: start; }
  .cm-heading h1 { font-size: 1.4rem; }
  .cm-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cm-status-summary { flex-wrap: wrap; margin-top: -9px; }
  .cm-selection-head { align-items: start; flex-direction: column; padding: 15px 13px 12px; }
  .cm-mode-switch { width: 100%; }
  .cm-mode-switch button { flex: 1; justify-content: center; }
  .cm-toolbar { padding: 10px 13px; }
  .cm-poem-list { grid-template-columns: 1fr; padding: 0 13px 13px; }
  .cm-selection-foot { align-items: stretch; flex-direction: column; padding: 11px 13px; }
  .cm-start { justify-content: center; }
  .cm-session-header h1 { font-size: 1.12rem; }
  .cm-question-card { padding: 24px 18px 22px; }
  .cm-prompt { min-height: 100px; font-size: .98rem; }
  .cm-question-meta { padding: 10px 12px; }
  .cm-question-history { display: none; }
}

@media (max-width: 420px) {
  .cm-stat { padding: 11px 10px; }
  .cm-stat strong { font-size: 1.25rem; }
  .cm-poem-main { padding-left: 9px; padding-right: 36px; }
  .cm-statuses { grid-template-columns: 1fr; }
}
/* ==== pages/bio-memorization.css ==== */
/* 生物必备知识手册闪卡（.bm-*）：筛选工作台 + 沉浸背诵屏 */
.bm-page {
  --bm-accent: #15803d;
  --bm-accent-soft: color-mix(in srgb, var(--bm-accent) 9%, var(--bg-secondary));
  --bm-accent-line: color-mix(in srgb, var(--bm-accent) 28%, var(--border));
  margin: 0 auto;
  padding: 20px 0 56px;
}
.bm-page--workbench { width: min(1180px, calc(100% - 32px)); }
.bm-page--session { width: min(880px, calc(100% - 24px)); padding-bottom: 28px; }
.bm-page kbd {
  display: inline-flex;
  min-width: 17px;
  height: 17px;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
  border: 1px solid var(--border);
  border-bottom-width: 2px;
  background: var(--bg-primary);
  color: var(--text-tertiary);
  font-family: inherit;
  font-size: .67rem;
  font-weight: 700;
}

/* ---------- 页头 ---------- */
.bm-header {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 18px;
  align-items: center;
  margin-bottom: 16px;
}
.bm-heading { min-width: 0; }
.bm-heading h1 {
  margin: 6px 0 4px;
  color: var(--text-primary);
  font-size: 1.68rem;
  line-height: 1.2;
}
.bm-heading p { margin: 0; color: var(--text-tertiary); font-size: .78rem; }
.bm-eyebrow {
  color: var(--bm-accent);
  font-size: .7rem;
  font-weight: 800;
  letter-spacing: .13em;
}
.bm-source-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  max-width: 245px;
  min-height: 32px;
  padding: 0 11px;
  border: 1px solid var(--bm-accent-line);
  background: var(--bm-accent-soft);
  color: var(--bm-accent);
  font-size: .7rem;
  font-weight: 700;
}
.bm-source-badge svg { width: 15px; height: 15px; flex: 0 0 auto; }
.bm-source-badge span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- 总览：今日队列 + 复习状态分桶 ---------- */
.bm-overview {
  display: grid;
  grid-template-columns: minmax(230px, 1.15fr) repeat(4, minmax(78px, 108px));
  gap: 9px;
  margin-bottom: 12px;
}
.bm-progress-block,
.bm-stat,
.bm-today { border: 1px solid var(--border); background: var(--bg-secondary); }
.bm-today {
  grid-row: span 2;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px 13px;
  border-left: 3px solid var(--danger);
}
.bm-today.is-clear { border-left-color: var(--success); }
.bm-today-main { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.bm-today-main .bm-eyebrow { flex: 1 1 100%; }
.bm-today-main strong { color: var(--danger); font-size: 1.86rem; line-height: 1; font-variant-numeric: tabular-nums; }
.bm-today.is-clear .bm-today-main strong { color: var(--success); }
.bm-today-unit { color: var(--text-secondary); font-size: .76rem; }
.bm-today-hint { margin: 0; color: var(--text-tertiary); font-size: .67rem; }
/* 今日学习量进度：复习 + 新学占目标多少。 */
.bm-today-progress { display: grid; gap: 4px; }
.bm-today-track { height: 4px; overflow: hidden; background: var(--bg-active); }
.bm-today-track i { display: block; height: 100%; background: var(--bm-accent); transition: width 200ms ease; }
.bm-today-progress small { color: var(--text-tertiary); font-size: .63rem; font-variant-numeric: tabular-nums; }
.bm-today-actions { display: flex; gap: 6px; align-items: stretch; margin-top: auto; }
.bm-goal {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 0 8px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
  color: var(--text-tertiary);
  font-size: .66rem;
  white-space: nowrap;
}
.bm-goal select {
  height: 32px;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: .7rem;
  cursor: pointer;
}
.bm-today-btn {
  display: inline-flex;
  flex: 1 1 auto;
  min-height: 34px;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid var(--danger);
  background: var(--danger);
  color: #fff;
  font: inherit;
  font-size: .74rem;
  font-weight: 700;
  cursor: pointer;
  transition: filter 130ms ease;
}
.bm-today-btn:hover:not(:disabled) { filter: brightness(.94); }
.bm-today.is-clear .bm-today-btn { border-color: var(--border); background: var(--bg-primary); color: var(--text-tertiary); }
.bm-today-btn:disabled { cursor: not-allowed; opacity: .6; }
.bm-today-btn svg { width: 14px; height: 14px; }
.bm-progress-block { grid-column: 2 / -1; padding: 12px 14px 10px; }
.bm-progress-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.bm-progress-head span { color: var(--text-secondary); font-size: .71rem; }
.bm-progress-head strong { color: var(--bm-accent); font-size: 1.02rem; font-variant-numeric: tabular-nums; }
.bm-progress-track,
.bm-session-track,
.bm-page-tile-track { overflow: hidden; background: var(--bg-active); }
.bm-progress-track { height: 5px; margin: 8px 0 6px; }
.bm-progress-track span {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--bm-accent), #4cae68);
  transition: width 220ms ease;
}
.bm-progress-block p { margin: 0; color: var(--text-tertiary); font-size: .66rem; }
.bm-stat { display: grid; grid-template-columns: 1fr auto; align-content: center; padding: 10px 12px; }
.bm-stat span { grid-column: 1 / -1; color: var(--text-tertiary); font-size: .66rem; }
.bm-stat strong { margin-top: 4px; color: var(--text-primary); font-size: 1.3rem; line-height: 1; font-variant-numeric: tabular-nums; }
.bm-stat small { align-self: end; color: var(--text-tertiary); font-size: .62rem; }
.bm-stat--due strong { color: var(--danger); }
.bm-stat--learning strong { color: var(--warning); }
.bm-stat--mastered strong { color: var(--success); }
.bm-stat--fresh strong { color: var(--text-secondary); }

/* ---------- 工作台：筛选面板 ---------- */
.bm-panel { border: 1px solid var(--border); background: var(--bg-secondary); }
.bm-panel-head {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 16px;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border-light);
}
.bm-panel-title { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.bm-panel-title strong { color: var(--text-primary); font-size: .92rem; }
.bm-panel-note { color: var(--text-tertiary); font-size: .66rem; }
.bm-panel-tools { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; }
.bm-panel-tools button,
.bm-pages-tools button {
  display: inline-flex;
  min-height: 32px;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
  color: var(--text-secondary);
  font: inherit;
  font-size: .7rem;
  cursor: pointer;
  transition: border-color 130ms ease, color 130ms ease, background 130ms ease;
}
.bm-panel-tools button:hover:not(:disabled),
.bm-pages-tools button:hover:not(:disabled) { border-color: var(--bm-accent); color: var(--bm-accent); background: var(--bm-accent-soft); }
.bm-panel-tools button:disabled,
.bm-pages-tools button:disabled { opacity: .4; cursor: not-allowed; }
.bm-panel-tools svg { width: 14px; height: 14px; }

.bm-filter-row {
  display: grid;
  grid-template-columns: minmax(200px, 1.5fr) repeat(3, minmax(130px, 1fr));
  gap: 9px;
  padding: 12px 14px;
}
.bm-search {
  display: flex;
  min-width: 0;
  height: 35px;
  align-items: center;
  gap: 8px;
  padding: 0 10px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
  color: var(--text-tertiary);
  transition: border-color 130ms ease, box-shadow 130ms ease;
}
.bm-search:focus-within {
  border-color: var(--bm-accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--bm-accent) 14%, transparent);
}
.bm-search svg { width: 15px; height: 15px; flex: 0 0 auto; }
.bm-search input {
  width: 100%;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text-primary);
  font: inherit;
  font-size: .76rem;
}
.bm-search input::placeholder { color: var(--text-tertiary); }
.bm-field {
  display: flex;
  min-width: 0;
  height: 35px;
  align-items: center;
  border: 1px solid var(--border);
  background: var(--bg-primary);
}
.bm-field > span { flex: 0 0 auto; padding-left: 9px; color: var(--text-tertiary); font-size: .66rem; font-weight: 700; }
.bm-field select {
  width: 100%;
  min-width: 0;
  height: 33px;
  padding: 0 22px 0 7px;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: .72rem;
  cursor: pointer;
}
.bm-field select:disabled { cursor: not-allowed; opacity: .55; }
.bm-field--compact { height: 32px; }
.bm-field--compact > span { padding-left: 8px; }
.bm-field--compact select { height: 30px; font-size: .7rem; }

/* ---------- 工作台：页码网格（默认收起，按需展开） ---------- */
.bm-pages { border-top: 1px solid var(--border-light); }
.bm-pages-toggle {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 8px;
  padding: 11px 14px;
  border: 0;
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: .74rem;
  font-weight: 650;
  text-align: left;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.bm-pages-toggle:hover { background: var(--bm-accent-soft); color: var(--bm-accent); }
.bm-pages-toggle svg { width: 15px; height: 15px; flex: 0 0 auto; }
.bm-pages-toggle small { margin-left: auto; color: var(--text-tertiary); font-size: .66rem; font-weight: 400; }
.bm-pages-toggle svg:last-child { color: var(--text-tertiary); }
.bm-pages.is-open .bm-pages-toggle { color: var(--bm-accent); }
.bm-pages.is-open .bm-pages-toggle small { color: var(--bm-accent); }
.bm-pages-head {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  align-items: center;
  justify-content: space-between;
  padding: 0 14px 9px;
}
.bm-pages-title { display: flex; align-items: center; gap: 8px; min-width: 0; }
.bm-pages-title svg { width: 15px; height: 15px; color: var(--bm-accent); }
.bm-pages-title strong { color: var(--text-primary); font-size: .8rem; }
.bm-pages-title small { color: var(--text-tertiary); font-size: .67rem; }
.bm-pages-tools { display: flex; flex-wrap: wrap; gap: 6px; }
.bm-pages .bm-page-grid,
.bm-pages .bm-pages-hint { margin: 0 14px; }
.bm-pages .bm-pages-hint { margin-bottom: 14px; }
.bm-page-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(66px, 1fr));
  gap: 6px;
  max-height: 320px;
  overflow-y: auto;
  padding: 1px;
}
.bm-page-tile {
  position: relative;
  display: grid;
  grid-template-rows: auto auto 4px;
  gap: 3px;
  padding: 7px 8px 6px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
  color: var(--text-secondary);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease, color 120ms ease;
}
.bm-page-tile:hover:not(:disabled) { border-color: var(--bm-accent-line); background: var(--bm-accent-soft); }
.bm-page-tile-no { color: var(--text-primary); font-size: .82rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.bm-page-tile-meta {
  overflow: hidden;
  color: var(--text-tertiary);
  font-size: .61rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bm-page-tile-track {
  display: flex;
  gap: 1px;
  height: 4px;
  background: var(--bg-active);
}
.bm-page-tile-track i { display: block; height: 100%; transition: width 160ms ease; }
.bm-page-tile-track i.is-due { background: var(--danger); }
.bm-page-tile-track i.is-fresh { background: color-mix(in srgb, var(--text-tertiary) 55%, transparent); }
.bm-page-tile-track i.is-learning { background: var(--warning); }
.bm-page-tile-track i.is-mastered { background: var(--success); }
/* 到期页最显眼：整格换成警示底色，右上角直接标“N 待复习”。 */
.bm-page-tile.is-due:not(.is-selected) {
  border-color: color-mix(in srgb, var(--danger) 42%, var(--border));
  background: color-mix(in srgb, var(--danger) 8%, var(--bg-primary));
}
.bm-page-tile.is-due .bm-page-tile-meta { color: var(--danger); font-weight: 700; }
.bm-page-tile.is-learning:not(.is-selected) { border-color: color-mix(in srgb, var(--warning) 34%, var(--border)); }
.bm-page-tile.is-selected {
  border-color: var(--bm-accent);
  background: var(--bm-accent);
  color: #fff;
  box-shadow: 0 4px 14px color-mix(in srgb, var(--bm-accent) 26%, transparent);
}
.bm-page-tile.is-selected .bm-page-tile-no,
.bm-page-tile.is-selected .bm-page-tile-meta { color: #fff; }
.bm-page-tile.is-selected .bm-page-tile-track { background: rgba(255, 255, 255, .35); }
.bm-page-tile.is-selected .bm-page-tile-track i { background: #fff; }
.bm-page-tile.is-complete:not(.is-selected) { border-color: color-mix(in srgb, var(--success) 34%, var(--border)); }
.bm-page-tile.is-empty { opacity: .38; }
.bm-page-tile-badge,
.bm-page-tile-done {
  position: absolute;
  top: 5px;
  right: 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.bm-page-tile-badge {
  min-width: 15px;
  height: 15px;
  padding: 0 4px;
  background: var(--danger);
  color: #fff;
  font-size: .58rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.bm-page-tile.is-selected .bm-page-tile-badge { background: #fff; color: var(--danger); }
.bm-page-tile-done { color: var(--success); }
.bm-page-tile.is-selected .bm-page-tile-done { color: #fff; }
.bm-page-tile-done svg { width: 12px; height: 12px; }
.bm-pages-hint { margin: 9px 0 0; color: var(--text-tertiary); font-size: .66rem; }

/* ---------- 工作台：底部开始条 ---------- */
.bm-start-bar {
  position: sticky;
  bottom: 10px;
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 16px;
  align-items: center;
  justify-content: space-between;
  margin-top: 12px;
  padding: 11px 14px;
  border: 1px solid var(--bm-accent-line);
  background: color-mix(in srgb, var(--bg-secondary) 94%, var(--bm-accent));
  box-shadow: 0 10px 30px rgba(10, 40, 20, .10);
}
.bm-start-info {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  gap: 2px 6px;
  align-items: baseline;
  min-width: 0;
  flex: 1 1 auto;
}
.bm-start-info strong { color: var(--bm-accent); font-size: 1.42rem; line-height: 1; font-variant-numeric: tabular-nums; }
.bm-start-info span { color: var(--text-secondary); font-size: .76rem; }
.bm-start-info small {
  overflow: hidden;
  color: var(--text-tertiary);
  font-size: .67rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bm-start-btn {
  display: inline-flex;
  min-height: 40px;
  align-items: center;
  gap: 8px;
  padding: 0 20px;
  border: 1px solid var(--bm-accent);
  background: var(--bm-accent);
  color: #fff;
  font: inherit;
  font-size: .82rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 130ms ease;
}
.bm-start-btn:hover:not(:disabled) { background: color-mix(in srgb, var(--bm-accent) 88%, #000); }
.bm-start-btn:disabled { opacity: .45; cursor: not-allowed; }
.bm-start-btn svg { width: 15px; height: 15px; }
.bm-start-info em {
  flex: 1 1 100%;
  margin-top: 2px;
  color: var(--text-tertiary);
  font-size: .65rem;
  font-style: normal;
}

/* ---------- 背诵屏：顶部常驻条 ---------- */
.bm-session-bar {
  position: sticky;
  top: calc(var(--nav-height) + 8px);
  z-index: 5;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) minmax(150px, auto);
  gap: 10px 16px;
  align-items: center;
  margin-bottom: 14px;
  padding: 10px 13px;
  border: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg-secondary) 92%, transparent);
  backdrop-filter: blur(6px);
}
.bm-session-back {
  display: inline-flex;
  min-height: 32px;
  align-items: center;
  gap: 5px;
  padding: 0 10px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
  color: var(--text-secondary);
  font: inherit;
  font-size: .72rem;
  cursor: pointer;
}
.bm-session-back:hover { border-color: var(--bm-accent); color: var(--bm-accent); background: var(--bm-accent-soft); }
.bm-session-back svg { width: 14px; height: 14px; }
.bm-session-meta { display: grid; gap: 2px; min-width: 0; }
.bm-session-meta strong {
  overflow: hidden;
  color: var(--text-primary);
  font-size: .78rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bm-session-meta small { color: var(--text-tertiary); font-size: .65rem; }
.bm-session-position { display: grid; gap: 4px; justify-items: end; min-width: 0; }
.bm-session-position > span { color: var(--text-tertiary); font-size: .7rem; font-variant-numeric: tabular-nums; }
.bm-session-position strong { color: var(--bm-accent); font-size: .95rem; }
.bm-session-position small { color: var(--text-tertiary); font-size: .63rem; }
.bm-session-track { width: 100%; height: 4px; }
.bm-session-track i { display: block; height: 100%; background: var(--bm-accent); transition: width 200ms ease; }

/* ---------- 背诵屏：卡片 ---------- */
.bm-stage { display: grid; gap: 12px; }
.bm-flashcard {
  display: flex;
  min-height: min(56vh, 520px);
  flex-direction: column;
  padding: 20px 24px 18px;
  border: 1px solid var(--border);
  border-top: 3px solid var(--bm-accent-line);
  background: var(--bg-secondary);
  box-shadow: 0 16px 44px rgba(10, 40, 20, .08);
  cursor: pointer;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.bm-flashcard:hover { border-color: var(--bm-accent-line); box-shadow: 0 20px 52px rgba(10, 40, 20, .11); }
.bm-flashcard.is-revealed { cursor: default; box-shadow: 0 20px 52px rgba(10, 40, 20, .11); }
.bm-flashcard.bm-card--remembered { border-top-color: var(--success); }
.bm-flashcard.bm-card--fuzzy { border-top-color: var(--warning); }
.bm-flashcard.bm-card--forgot { border-top-color: var(--danger); }
.bm-card-top { display: flex; align-items: center; gap: 8px; }
.bm-card-index { color: var(--text-tertiary); font-size: .64rem; font-weight: 700; letter-spacing: .04em; }
.bm-card-page {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
  padding: 3px 7px;
  border: 1px solid var(--border);
  background: var(--bg-tertiary);
  color: var(--text-tertiary);
  font-size: .61rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.bm-card-page svg { width: 11px; height: 11px; }
.bm-card-status { padding: 3px 6px; background: var(--bg-tertiary); color: var(--text-tertiary); font-size: .61rem; font-weight: 700; }
.bm-card-status--new { background: var(--bg-tertiary); color: var(--text-tertiary); }
.bm-card-status--remembered { background: var(--success-light); color: var(--success); }
.bm-card-status--fuzzy { background: var(--warning-light); color: var(--warning); }
.bm-card-status--forgot { background: var(--danger-light); color: var(--danger); }
/* 记忆持久度圆环：满环=刚背完，越空越接近遗忘（墨墨那个饼状图的含义）。 */
.bm-ring {
  --bm-ring: 0%;
  --bm-ring-color: var(--bm-accent);
  position: relative;
  display: inline-block;
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: conic-gradient(var(--bm-ring-color) var(--bm-ring), var(--bg-active) 0);
}
.bm-ring::after {
  content: '';
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: var(--bg-secondary);
}
.bm-ring--due {
  --bm-ring-color: var(--danger);
  /* 空的环也要看得出“该复习了”，所以底槽染一点红。 */
  background: conic-gradient(var(--danger) var(--bm-ring), color-mix(in srgb, var(--danger) 24%, var(--bg-active)) 0);
}
.bm-ring--learning { --bm-ring-color: var(--warning); }
.bm-ring--mastered { --bm-ring-color: var(--success); }
/* 复习阶段：一眼看出这张卡在调度里的位置与下一次什么时候来。 */
.bm-card-schedule {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 7px;
  font-size: .66rem;
}
.bm-schedule-state {
  padding: 2px 7px;
  border: 1px solid currentColor;
  font-weight: 700;
}
.bm-schedule-text { color: var(--text-tertiary); }
.bm-card-schedule--due { color: var(--danger); }
.bm-card-schedule--learning { color: var(--warning); }
.bm-card-schedule--mastered { color: var(--success); }
.bm-card-schedule--new { color: var(--text-tertiary); }
.bm-card-path {
  margin: 8px 0 0;
  overflow: hidden;
  color: var(--bm-accent);
  font-size: .66rem;
  font-weight: 650;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bm-flash-question {
  display: flex;
  flex: 1 1 auto;
  min-height: 180px;
  align-items: center;
  justify-content: center;
  padding: 26px 8px 18px;
  text-align: center;
}
.bm-flash-question .bm-prompt { max-width: 700px; font-size: 1.3rem; font-weight: 650; line-height: 1.9; }
.bm-prompt { font-size: .92rem; font-weight: 650; line-height: 1.72; }
.bm-flash-answer-zone { flex: 0 0 auto; }
.bm-flash-answer { max-height: min(38vh, 340px); overflow: auto; }
.bm-flash-answer .bm-answer-body { font-size: .9rem; }
.bm-flash-answer .md-image { max-height: 240px; }
.bm-answer { margin-top: 4px; padding: 12px 13px; border-left: 3px solid var(--bm-accent); background: var(--bm-accent-soft); }
.bm-answer-label { display: flex; justify-content: space-between; gap: 8px; align-items: center; margin-bottom: 8px; }
.bm-answer-label span { color: var(--bm-accent); font-size: .67rem; font-weight: 800; letter-spacing: .04em; }
.bm-answer-label small { color: var(--text-tertiary); font-size: .6rem; }
.bm-answer-body { color: var(--text-secondary); font-size: .84rem; line-height: 1.75; }

.bm-reveal {
  display: flex;
  width: 100%;
  min-height: 38px;
  align-items: center;
  justify-content: center;
  gap: 7px;
  border: 1px dashed var(--bm-accent-line);
  background: var(--bm-accent-soft);
  color: var(--bm-accent);
  font: inherit;
  font-size: .74rem;
  font-weight: 700;
  cursor: pointer;
}
.bm-reveal:hover { border-color: var(--bm-accent); background: color-mix(in srgb, var(--bm-accent) 14%, var(--bg-secondary)); }
.bm-reveal svg { width: 15px; height: 15px; }

.bm-grade-bar { display: grid; gap: 6px; margin-top: 10px; }
.bm-grade-bar--idle {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 9px 10px;
  border: 1px dashed var(--border);
  color: var(--text-tertiary);
  font-size: .72rem;
}
.bm-grade-bar--idle svg { width: 15px; height: 15px; }
/* 评分后的即时反馈：刚打的这一张排到了什么时候。 */
.bm-last-grade {
  margin-left: auto;
  padding-left: 10px;
  border-left: 1px solid var(--border);
  color: var(--bm-accent);
  font-size: .66rem;
  font-weight: 700;
  white-space: nowrap;
}
.bm-grades { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.bm-grade {
  display: inline-flex;
  min-width: 0;
  min-height: 40px;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 8px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
  color: var(--text-secondary);
  font: inherit;
  font-size: .74rem;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease, color 120ms ease;
}
.bm-grade svg { width: 14px; height: 14px; }
.bm-grade kbd { margin-left: 2px; }
.bm-grade:hover:not(:disabled),
.bm-grade.is-current { border-color: currentColor; }
.bm-grade--remembered:hover:not(:disabled),
.bm-grade--remembered.is-current { color: var(--success); background: var(--success-light); }
.bm-grade--fuzzy:hover:not(:disabled),
.bm-grade--fuzzy.is-current { color: var(--warning); background: var(--warning-light); }
.bm-grade--forgot:hover:not(:disabled),
.bm-grade--forgot.is-current { color: var(--danger); background: var(--danger-light); }
.bm-grade:disabled { opacity: .45; cursor: wait; }
.bm-card-history { color: var(--text-tertiary); font-size: .61rem; text-align: center; }

.bm-session-nav { display: flex; gap: 10px; align-items: center; justify-content: space-between; }
.bm-session-nav button {
  display: inline-flex;
  min-height: 36px;
  align-items: center;
  gap: 5px;
  padding: 0 12px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
  color: var(--text-secondary);
  font: inherit;
  font-size: .74rem;
  cursor: pointer;
}
.bm-session-nav button:hover:not(:disabled) { border-color: var(--bm-accent); color: var(--bm-accent); background: var(--bm-accent-soft); }
.bm-session-nav button:disabled { opacity: .35; cursor: not-allowed; }
.bm-session-nav svg { width: 15px; height: 15px; }
.bm-session-nav-mid { display: inline-flex; gap: 6px; }
/* 跳过与撤回是辅助动作，弱化处理，别和「下一张」抢注意力。 */
.bm-session-nav .bm-nav-ghost {
  min-height: 32px;
  padding: 0 10px;
  border-style: dashed;
  color: var(--text-tertiary);
  font-size: .7rem;
}
.bm-session-kbd {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin: 9px 0 0;
  color: var(--text-tertiary);
  font-size: .63rem;
}

/* ---------- 完成 / 空状态 ---------- */
.bm-stage--complete { gap: 0; }
.bm-complete {
  display: flex;
  min-height: min(56vh, 480px);
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 32px 22px;
  border: 1px solid var(--border);
  background: var(--bg-secondary);
  text-align: center;
}
.bm-complete-icon {
  display: grid;
  width: 50px;
  height: 50px;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--bm-accent) 40%, var(--border));
  color: var(--bm-accent);
}
.bm-complete-icon svg { width: 23px; height: 23px; }
.bm-complete h2 { margin: 0; color: var(--text-primary); font-size: 1.28rem; }
.bm-complete > p:not(.bm-eyebrow) { margin: 0; color: var(--text-tertiary); font-size: .77rem; }
.bm-complete-stats { display: flex; flex-wrap: wrap; gap: 7px; justify-content: center; margin-top: 3px; }
.bm-complete-stats span { padding: 4px 9px; font-size: .68rem; font-weight: 700; }
.bm-complete-stats .is-remembered { color: var(--success); background: var(--success-light); }
.bm-complete-stats .is-fuzzy { color: var(--warning); background: var(--warning-light); }
.bm-complete-stats .is-forgot { color: var(--danger); background: var(--danger-light); }
.bm-complete-next {
  margin: 4px 0 0;
  padding: 5px 10px;
  border: 1px dashed var(--border);
  color: var(--text-secondary);
  font-size: .7rem;
}
.bm-complete-streak {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin: 2px 0 0;
  color: var(--bm-accent);
  font-size: .72rem;
  font-weight: 700;
}
.bm-complete-streak svg { width: 14px; height: 14px; }
/* 连续学习天数：挂在今日大卡的角上。 */
.bm-streak {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
  padding: 2px 7px;
  background: var(--bm-accent-soft);
  color: var(--bm-accent);
  font-size: .63rem;
  font-weight: 700;
  white-space: nowrap;
}
.bm-streak svg { width: 12px; height: 12px; }
/* 今日目标已完成但还有卡可学：给一个「加量」按钮而不是死按钮。 */
.bm-today-btn--more { border-color: var(--bm-accent); background: var(--bm-accent); }
.bm-complete-actions { display: flex; gap: 8px; margin-top: 12px; }
.bm-flash-primary,
.bm-flash-secondary {
  display: inline-flex;
  min-height: 38px;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 14px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
  color: var(--text-secondary);
  font: inherit;
  font-size: .74rem;
  cursor: pointer;
}
.bm-flash-primary { border-color: var(--bm-accent); background: var(--bm-accent); color: #fff; }
.bm-flash-primary:hover { background: color-mix(in srgb, var(--bm-accent) 88%, #000); }
.bm-flash-secondary:hover { border-color: var(--bm-accent); color: var(--bm-accent); background: var(--bm-accent-soft); }
.bm-flash-primary svg,
.bm-flash-secondary svg { width: 15px; height: 15px; }

.bm-loading,
.bm-empty {
  display: flex;
  min-height: 320px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 30px 20px;
  color: var(--text-tertiary);
  text-align: center;
}
.bm-loading span,
.bm-empty > span {
  display: grid;
  width: 38px;
  height: 38px;
  place-items: center;
  border: 1px solid var(--bm-accent-line);
  color: var(--bm-accent);
}
.bm-loading span svg,
.bm-empty > span svg { width: 20px; height: 20px; }
.bm-loading span svg { animation: spin .8s linear infinite; }
.bm-loading strong,
.bm-empty h2 { margin: 2px 0 0; color: var(--text-primary); font-size: .95rem; }
.bm-loading p,
.bm-empty p { margin: 0; font-size: .75rem; }
.bm-empty .btn { margin-top: 6px; }
.bm-empty--error > span { border-color: color-mix(in srgb, var(--danger) 30%, var(--border)); color: var(--danger); }
.bm-page.is-updating { opacity: .65; pointer-events: none; transition: opacity 120ms ease; }

.bm-source-note { display: flex; align-items: center; gap: 7px; margin-top: 14px; color: var(--text-tertiary); font-size: .66rem; }
.bm-source-note svg { width: 14px; height: 14px; color: var(--bm-accent); }

/* ---------- 富文本（题目 / 答案） ---------- */
.bm-rich { overflow-wrap: anywhere; }
.bm-rich > :first-child { margin-top: 0; }
.bm-rich > :last-child { margin-bottom: 0; }
.bm-rich p { margin: .35em 0; }
.bm-rich ul,
.bm-rich ol { margin: .4em 0; padding-left: 1.45em; }
.bm-rich li + li { margin-top: .2em; }
.bm-rich blockquote { margin: .55em 0; padding-left: 10px; border-left: 2px solid var(--bm-accent-line); color: var(--text-secondary); }
.bm-rich table {
  display: block;
  max-width: 100%;
  margin: 9px 0;
  overflow-x: auto;
  font-size: .72rem;
  white-space: nowrap;
}
.bm-rich th,
.bm-rich td { padding: 6px 8px; }
.bm-rich .md-image {
  display: block;
  max-width: 100%;
  height: auto;
  max-height: 400px;
  margin: 10px auto;
  border: 1px solid var(--border-light);
  background: #fff;
  object-fit: contain;
  cursor: zoom-in;
}
.bm-rich .katex-display { max-width: 100%; overflow-x: auto; overflow-y: hidden; }
.bm-flash-question .bm-rich table,
.bm-flash-question .bm-rich img { max-height: 220px; }

/* ---------- 焦点与动效 ---------- */
.bm-panel button:focus-visible,
.bm-panel input:focus-visible,
.bm-panel select:focus-visible,
.bm-page-tile:focus-visible,
.bm-session-bar button:focus-visible,
.bm-session-nav button:focus-visible,
.bm-flashcard:focus-visible,
.bm-grade:focus-visible,
.bm-start-btn:focus-visible {
  outline: 2px solid var(--bm-accent);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .bm-page-tile,
  .bm-flashcard,
  .bm-progress-track span,
  .bm-session-track i,
  .bm-page-tile-track i { transition: none; }
}

/* ---------- 响应式 ---------- */
@media (max-width: 1080px) {
  .bm-overview { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .bm-today { grid-row: auto; grid-column: 1 / -1; }
  .bm-progress-block { grid-column: 1 / -1; }
  .bm-filter-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bm-search { grid-column: 1 / -1; }
}

@media (max-width: 720px) {
  .bm-page--workbench,
  .bm-page--session { width: calc(100% - 20px); }
  .bm-page { padding-top: 14px; }
  .bm-header { grid-template-columns: auto minmax(0, 1fr); gap: 11px; }
  .bm-source-badge { grid-column: 2; justify-self: start; max-width: 100%; }
  .bm-heading h1 { font-size: 1.32rem; }
  .bm-heading p { font-size: .72rem; }
  .bm-overview { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bm-today-main strong { font-size: 1.5rem; }
  .bm-filter-row { grid-template-columns: minmax(0, 1fr); padding: 10px 10px 2px; }
  .bm-panel-head { padding: 10px; }
  .bm-pages { padding: 8px 10px 12px; }
  .bm-page-grid { grid-template-columns: repeat(auto-fill, minmax(58px, 1fr)); max-height: 260px; }
  .bm-start-bar { position: static; padding: 10px; }
  .bm-start-info small { display: none; }
  .bm-start-btn { flex: 1 1 auto; justify-content: center; }
  .bm-session-bar { grid-template-columns: auto minmax(0, 1fr); top: calc(var(--nav-height) + 4px); }
  .bm-session-meta { grid-column: 2; }
  .bm-session-position { grid-column: 1 / -1; justify-items: stretch; }
  .bm-session-position > span,
  .bm-session-position small { text-align: right; }
  .bm-flashcard { min-height: 58vh; padding: 16px 15px 14px; }
  .bm-flash-question { min-height: 150px; padding: 20px 4px 14px; }
  .bm-flash-question .bm-prompt { font-size: 1.06rem; line-height: 1.8; }
  .bm-session-kbd { display: none; }
  .bm-session-nav button { flex: 1 1 auto; justify-content: center; }
  .bm-complete { min-height: 52vh; }
}

@media (max-width: 430px) {
  .bm-overview { gap: 6px; }
  .bm-stat { padding: 9px 8px; }
  .bm-stat strong { font-size: 1.14rem; }
  .bm-grades { gap: 4px; }
  .bm-grade { min-height: 36px; font-size: .68rem; }
  .bm-grade kbd { display: none; }
  .bm-page-grid { grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); }
  .bm-complete-actions { width: 100%; flex-direction: column; }
  .bm-panel-tools button span { display: none; }
}

/* ===== Legibility floor =====
   The 63-tile page grid plus the card chrome carried most of its labels at
   .61–.67rem (9.8–10.7px) — the smallest text in the app. Everything now sits
   at .7rem (11.2px); the page-tile meta line and status pills were checked at
   that size and still fit their fixed-width boxes. */
.bm-progress-block p,
.bm-stat span,
.bm-stat small,
.bm-field > span,
.bm-pages-title small,
.bm-pages-hint,
.bm-session-meta small,
.bm-session-position small,
.bm-card-index,
.bm-card-status,
.bm-answer-label span,
.bm-card-history,
.bm-session-kbd,
.bm-page-tile-meta,
.bm-source-note { font-size: .7rem; }
/* ==== pages/bio-recitation.css ==== */
/*
 * 生物背诵册（.br-*）：工作台 + 练习屏 + 浏览屏
 *
 * 配色沿用生物既有的绿色（与 bio-memorization 的 --bm-accent 同源），
 * 但类名独立（.br-*）—— 两个模块的 DOM 结构完全不同，共用类名只会互相牵制。
 *
 * ⚠ 所有颜色走项目既有 token（--bg-secondary / --border / --text-*），
 *   深色与壁纸模式才会自动跟上。写死 #fff/#000 在壁纸下会像贴上去的色块。
 */
.br-page {
  --br-accent: #15803d;
  --br-accent-soft: color-mix(in srgb, var(--br-accent) 9%, var(--bg-secondary));
  --br-accent-line: color-mix(in srgb, var(--br-accent) 28%, var(--border));
  margin: 0 auto;
  padding: 20px 0 56px;
}
.br-page--workbench { width: min(1180px, calc(100% - 32px)); }
.br-page--session { width: min(880px, calc(100% - 24px)); padding-bottom: 28px; }
.br-page--browse { width: min(1000px, calc(100% - 32px)); }
.br-page kbd {
  display: inline-flex;
  min-width: 17px;
  height: 17px;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
  border: 1px solid var(--border);
  border-bottom-width: 2px;
  background: var(--bg-primary);
  color: var(--text-tertiary);
  font-family: inherit;
  font-size: .67rem;
  font-weight: 700;
}

/* ---------- 页头 ---------- */
.br-header {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  margin-bottom: 14px;
}
.br-back-btn {
  display: inline-flex;
  width: 34px;
  height: 34px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  background: var(--bg-secondary);
  color: var(--text-secondary);
  cursor: pointer;
  transition: border-color 160ms ease, color 160ms ease;
}
.br-back-btn:hover { border-color: var(--br-accent); color: var(--br-accent); }
.br-back-btn svg { width: 17px; height: 17px; }
.br-heading { min-width: 0; }
.br-heading h1 {
  margin: 2px 0 0;
  color: var(--text-primary);
  font-size: 1.16rem;
  font-weight: 700;
  letter-spacing: -.01em;
}
.br-heading p { margin: 2px 0 0; color: var(--text-tertiary); font-size: .74rem; }
.br-eyebrow {
  color: var(--br-accent);
  font-size: .62rem;
  font-weight: 800;
  letter-spacing: .13em;
  text-transform: uppercase;
}
.br-header-tools { display: flex; gap: 6px; }
.br-icon-btn {
  display: inline-flex;
  width: 32px;
  height: 32px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  background: var(--bg-secondary);
  color: var(--text-secondary);
  cursor: pointer;
  transition: border-color 160ms ease, color 160ms ease;
}
.br-icon-btn:hover:not(:disabled) { border-color: var(--br-accent); color: var(--br-accent); }
.br-icon-btn:disabled { cursor: not-allowed; opacity: .4; }
.br-icon-btn svg { width: 15px; height: 15px; }

/* ---------- 概览 ---------- */
.br-overview {
  display: grid;
  grid-template-columns: minmax(230px, 300px) minmax(0, 1fr);
  gap: 10px;
  margin-bottom: 12px;
}
.br-today,
.br-stat,
.br-progress {
  border: 1px solid var(--border);
  background: var(--bg-secondary);
}
.br-today { display: grid; align-content: start; gap: 7px; padding: 12px 14px; }
.br-today.is-clear { border-left: 3px solid var(--success); }
.br-today-main { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.br-today-main .br-eyebrow { flex: 1 1 100%; }
.br-today-main strong {
  color: var(--br-accent);
  font-size: 1.86rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.br-today-unit { color: var(--text-secondary); font-size: .76rem; }
.br-today-hint { margin: 0; color: var(--text-tertiary); font-size: .67rem; }
.br-today-track { height: 4px; overflow: hidden; background: var(--bg-active); }
.br-today-track i { display: block; height: 100%; background: var(--br-accent); transition: width 200ms ease; }

.br-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
}
.br-stat { display: grid; align-content: center; padding: 10px 12px; }
.br-stat span { color: var(--text-tertiary); font-size: .66rem; }
.br-stat strong {
  margin-top: 4px;
  color: var(--text-primary);
  font-size: 1.3rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.br-stat--due strong { color: var(--danger); }
.br-stat--learning strong { color: var(--warning); }
.br-stat--mastered strong { color: var(--success); }
.br-stat--new strong { color: var(--text-secondary); }

.br-progress { grid-column: 2 / -1; padding: 12px 14px 10px; }
.br-progress-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.br-progress-head span { color: var(--text-secondary); font-size: .71rem; }
.br-progress-head strong { color: var(--br-accent); font-size: 1.02rem; font-variant-numeric: tabular-nums; }
.br-progress-track { height: 5px; margin: 8px 0 6px; overflow: hidden; background: var(--bg-active); }
.br-progress-track i { display: block; height: 100%; background: linear-gradient(90deg, var(--br-accent), #4cae68); transition: width 220ms ease; }
.br-progress p { margin: 0; color: var(--text-tertiary); font-size: .66rem; }
/*
 * 「全库覆盖」的构成明细（几册几章、可挖空多少条）是**参考信息**，
 * 不是每次进来都要看的东西 —— 但它占掉一行文字高度。
 * 窄屏上折叠起来，把空间让给「依次背诵」这个主操作。
 * ⚠ 折叠而不是删除：用户想知道「总共多少条可挖空」时还得查得到。
 */
.br-progress-more { margin: 0; }
.br-progress-more > summary {
  cursor: pointer;
  color: var(--text-tertiary);
  font-size: .66rem;
  list-style: none;
}
.br-progress-more > summary::-webkit-details-marker { display: none; }
.br-progress-more > summary::after { content: ' 明细'; color: var(--br-accent); }
.br-progress-more[open] > summary::after { content: ' 收起'; }
.br-progress-more > p { margin-top: 4px; }

/* ---------- 面板与筛选 ---------- */
.br-panel { border: 1px solid var(--border); background: var(--bg-secondary); }
.br-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 11px 14px;
  border-bottom: 1px solid var(--border-light);
}
.br-panel-title { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.br-panel-title strong { color: var(--text-primary); font-size: .92rem; }
.br-panel-note { color: var(--text-tertiary); font-size: .66rem; }

.br-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding: 11px 14px;
  border-bottom: 1px solid var(--border-light);
}
.br-filter-row:last-child { border-bottom: 0; }
.br-search {
  display: flex;
  flex: 1 1 240px;
  align-items: center;
  gap: 7px;
  min-width: 200px;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
  transition: border-color 160ms ease;
}
.br-search:focus-within { border-color: var(--br-accent); }
.br-search svg { width: 15px; height: 15px; flex: 0 0 auto; color: var(--text-tertiary); }
.br-search input {
  width: 100%;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text-primary);
  font-family: inherit;
  font-size: .78rem;
}
.br-search input::placeholder { color: var(--text-tertiary); }

.br-field {
  display: inline-flex;
  align-items: stretch;
  height: 32px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
}
.br-field > span {
  display: flex;
  align-items: center;
  padding-left: 9px;
  color: var(--text-tertiary);
  font-size: .66rem;
  font-weight: 700;
  white-space: nowrap;
}
.br-field select {
  max-width: 210px;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text-primary);
  font-family: inherit;
  font-size: .74rem;
  padding: 0 8px;
}
.br-field select:disabled { cursor: not-allowed; opacity: .5; }

/* ---------- 每日计划（自定义目标 + 复习/新学分项） ---------- */
/*
 * ⚠ 一行里放三个数字框 + 6 个快捷预设，桌面端要能排开；
 *   窄屏靠 flex-wrap 换行（见文件末尾的 @media）。
 */
.br-goal-row { align-items: center; }
.br-goal-fields { display: flex; gap: 8px; flex-wrap: wrap; }
/*
 * ⚠ 数字框要比下拉框窄：`总目标` 只填 1~500 的三位数，
 *   给 210px 会显得空荡，而且挤掉后面的预设按钮。
 */
.br-field--goal input {
  width: 62px;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text-primary);
  font-family: inherit;
  font-size: .74rem;
  font-variant-numeric: tabular-nums;
  padding: 0 8px;
  text-align: right;
}
/* 去掉数字框的上下箭头：它们占宽、且在窄屏上误触率高 */
.br-field--goal input::-webkit-outer-spin-button,
.br-field--goal input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.br-field--goal input[type=number] { -moz-appearance: textfield; appearance: textfield; }
.br-field--goal input::placeholder { color: var(--text-tertiary); }
.br-field--goal input:focus { outline: 2px solid var(--br-accent); outline-offset: -2px; }
/*
 * ⚠ 分开设时「总目标」是派生值（复习 + 新学），要变灰不可编辑 ——
 *   否则用户以为改总数能覆盖分项，改了却没效果。
 */
.br-field--goal.is-derived { opacity: .55; }
.br-field--goal.is-derived input { cursor: not-allowed; }
/* 快捷预设：小圆角按钮，当前值高亮 */
.br-goal-presets { display: flex; gap: 5px; flex-wrap: wrap; }
.br-goal-chip {
  min-width: 34px;
  height: 26px;
  padding: 0 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-primary);
  color: var(--text-secondary);
  font-family: inherit;
  font-size: .7rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.br-goal-chip:hover { border-color: var(--br-accent); color: var(--br-accent); }
.br-goal-chip.is-active {
  border-color: var(--br-accent);
  background: var(--br-accent);
  color: #fff;
  font-weight: 700;
}
/*
 * 「改成统一目标」：分开设时替代预设按钮的出口。
 * ⚠ 它和预设按钮同占一行，高度要对齐，否则那一行会跳一下。
 */
.br-goal-unsplit { height: 26px; padding: 0 12px; font-size: .7rem; }
/* 「今天到期量超出设定」的提示：要显眼，但不能像报错 */
.br-goal-overflow {
  display: block;
  margin-top: 4px;
  color: var(--br-warn, #d98b2b);
  font-size: .68rem;
  line-height: 1.45;
}
/*
 * 分开背诵时的第二个按钮（新学）。
 * ⚠ 视觉上要与「复习」区分：复习是主线（实心），新学是并行的另一条（描边），
 *   否则两个实心大按钮并排会让人以为要二选一。
 */
.br-primary-btn--alt {
  border: 1px solid var(--br-accent);
  background: transparent;
  color: var(--br-accent);
}
.br-primary-btn--alt:hover:not(:disabled) { background: color-mix(in srgb, var(--br-accent) 12%, transparent); }

/* ---------- 按钮 ---------- */
.br-primary-btn,
.br-ghost-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 34px;
  padding: 0 14px;
  border: 1px solid var(--border);
  font-family: inherit;
  font-size: .78rem;
  font-weight: 650;
  cursor: pointer;
  transition: border-color 160ms ease, background 160ms ease, color 160ms ease, filter 160ms ease;
}
.br-primary-btn {
  border-color: var(--br-accent);
  background: var(--br-accent);
  color: #fff;
}
.br-primary-btn:hover:not(:disabled) { filter: brightness(.94); }
.br-primary-btn:disabled { cursor: not-allowed; opacity: .45; }
.br-ghost-btn { background: var(--bg-primary); color: var(--text-secondary); }
.br-ghost-btn:hover:not(:disabled) { border-color: var(--br-accent); color: var(--br-accent); }
.br-ghost-btn:disabled { cursor: not-allowed; opacity: .4; }
.br-primary-btn svg,
.br-ghost-btn svg { width: 14px; height: 14px; }

/* ---------- 开始条 ---------- */
.br-start-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  margin: 12px 0;
  padding: 12px 14px;
  border: 1px solid var(--br-accent-line);
  background: color-mix(in srgb, var(--bg-secondary) 94%, var(--br-accent));
}
.br-start-info { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.br-start-info .br-eyebrow { flex: 1 1 100%; }
.br-start-info strong { color: var(--br-accent); font-size: 1.42rem; line-height: 1; font-variant-numeric: tabular-nums; }
.br-start-info span { color: var(--text-secondary); font-size: .76rem; }
.br-start-info small { flex: 1 1 100%; color: var(--text-tertiary); font-size: .66rem; }
.br-start-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------- 条目列表 ---------- */
.br-rows { margin: 0; padding: 0; list-style: none; }
.br-row { border-bottom: 1px solid var(--border-light); }
.br-row:last-child { border-bottom: 0; }
/*
 * 整行是按钮（点哪条就从哪条开始背）。
 * ⚠ 按钮要重置浏览器默认样式，否则会有灰底和系统字体 —— 与卡片风格打架。
 * ⚠ 用 button 而不是给 li 挂 click：键盘 Tab/回车/读屏都能用，且不用自己写 role。
 */
.br-row-btn {
  position: relative;
  display: block;
  width: 100%;
  /* 右侧给箭头留 22px —— 足够放下一个「›」，又小到不会把节名挤换行 */
  padding: 10px 22px 10px 14px;
  border: 0;
  background: none;
  color: inherit;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 140ms ease;
}
.br-row-btn:hover { background: var(--br-accent-soft); }
.br-row-btn:focus-visible { outline: 2px solid var(--br-accent); outline-offset: -2px; }
/*
 * 「背这条 ›」指示器。
 *
 * ⚠ 必须**绝对定位**且**竖直居中于整行**：
 *   - 留在 flex 流里时，它会把 head 从 2 行挤成 3 行（实测 42px → 65px），
 *     一屏 20 行就多 460px；
 *   - 只给它 `padding-right: 52px` 也还不够 —— 长节名（「第1节-细胞是生命活动
 *     的基本单位」）会因为少了 52px 而换行，head 仍是 58px 而不是 42px。
 *   现在用一个小箭头（~14px）+ 22px 内边距，节名基本不会因此换行。
 */
.br-row-go {
  position: absolute;
  top: 50%;
  right: 8px;
  transform: translateY(-50%);
  color: var(--br-accent);
  font-size: .82rem;
  font-weight: 700;
  line-height: 1;
  opacity: 0;
  transition: opacity 140ms ease;
  pointer-events: none;
}
.br-row-btn:hover .br-row-go,
.br-row-btn:focus-visible .br-row-go { opacity: 1; }
/* 触屏没有 hover —— 常显，否则手机上完全看不出这行能点 */
@media (hover: none) {
  .br-row-go { opacity: .55; }
}
.br-row-head { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-bottom: 5px; }
.br-row-no {
  color: var(--text-primary);
  font-size: .74rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.br-row-where { color: var(--text-tertiary); font-size: .64rem; }
.br-row-text {
  display: block;
  margin: 0;
  color: var(--text-secondary);
  font-size: .78rem;
  line-height: 1.68;
}
.br-blank-mark {
  display: inline-block;
  min-width: 3em;
  border-bottom: 1.5px solid var(--br-accent-line);
  color: var(--br-accent);
  font-style: normal;
  text-align: center;
}

.br-tag {
  display: inline-flex;
  align-items: center;
  padding: 1px 6px;
  border: 1px solid var(--border);
  background: var(--bg-tertiary);
  color: var(--text-tertiary);
  font-size: .6rem;
  font-weight: 700;
  white-space: nowrap;
}
.br-tag--cloze { border-color: var(--br-accent-line); background: var(--br-accent-soft); color: var(--br-accent); }
.br-tag--flip { border-color: color-mix(in srgb, var(--warning) 32%, var(--border)); color: var(--warning); }
.br-tag--warn { border-color: color-mix(in srgb, var(--danger) 34%, var(--border)); color: var(--danger); }
.br-tag--due { border-color: color-mix(in srgb, var(--danger) 30%, var(--border)); color: var(--danger); }
.br-tag--learning { border-color: color-mix(in srgb, var(--warning) 30%, var(--border)); color: var(--warning); }
.br-tag--mastered { border-color: color-mix(in srgb, var(--success) 30%, var(--border)); color: var(--success); }

.br-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 12px 14px;
  border-top: 1px solid var(--border-light);
}
.br-pager span { color: var(--text-tertiary); font-size: .72rem; font-variant-numeric: tabular-nums; }
.br-pager-note { margin: 0; padding: 11px 14px; border-top: 1px solid var(--border-light); color: var(--text-tertiary); font-size: .7rem; }

/* ---------- 练习屏 ---------- */
.br-session-bar {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  margin-bottom: 12px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  background: var(--bg-secondary);
}
.br-session-meta { display: grid; gap: 2px; min-width: 0; }
.br-session-meta strong {
  overflow: hidden;
  color: var(--text-primary);
  font-size: .82rem;
  font-weight: 650;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.br-session-meta small { color: var(--text-tertiary); font-size: .64rem; }
.br-session-position { display: grid; gap: 2px; justify-items: end; text-align: right; }
.br-session-position > span { color: var(--br-accent); font-size: .9rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.br-session-position small { color: var(--text-tertiary); font-size: .62rem; }
.br-session-track {
  grid-column: 1 / -1;
  height: 4px;
  overflow: hidden;
  background: var(--bg-active);
}
.br-session-track i { display: block; height: 100%; background: var(--br-accent); transition: width 200ms ease; }

.br-stage {
  display: grid;
  gap: 12px;
  /*
   * 桌面端把卡片**垂直居中**，而不是顶到页面最上面。
   *
   * 实测：视口 900px、卡片高 188px、卡片底 471px → 下方**空着 429px**，
   * 视线要在上半屏找一个很小的输入框，而下面半屏全空。居中之后
   * 卡片落在视觉中心，长时间背不容易累（一次要过几十条）。
   *
   * ⚠⚠ 高度必须**从实测布局反推**，不能拍数字。我在这里连踩三次：
   *   1. `calc(100vh - 230px)`：230 是拍的 → 文档高出视口 154px（多出滚动条，卡片没真居中）
   *   2. 拆成两个变量、`--br-session-above: 200px` → 还是差 28px
   *   3. 按 `stageTop - shellTop` 算成 128px → 这回**反向**溢出 100px
   *      原因：`shellTop` 只算了 `#page-container` 的内边距，**漏了 `.br-page`
   *      自己的 padding-bottom（28px）**，而它也在 stage 下方。
   *
   * 最终公式（在文档坐标系里量，`scrollY` 归零后）：
   *     min-height = 100vh − stage上方占用 − stage下方占用
   *   实测值：
   *     桌面  900 − 284 − 100 = 516
   *     手机  844 − 322 −  80 = 442
   *   ⚠ 上下两值都**含各自断点的页头/内边距**，所以窄屏必须分别给。
   *   改页头、会话条、`.br-page` 内边距、或 `#page-container` 内边距时，
   *   这两个数都要重新量（`tmp/ux-calc2.mjs` 那类脚本可以现算）。
   */
  --br-stage-above: 284px;
  --br-stage-below: 100px;
  min-height: calc(100vh - var(--br-stage-above) - var(--br-stage-below));
  min-height: calc(100dvh - var(--br-stage-above) - var(--br-stage-below));
  align-content: center;
}
/* 窄屏：页头换行、会话条折两行、shell 内边距也更小 —— 上下都要重新给 */
@media (max-width: 900px) {
  .br-stage { --br-stage-above: 300px; --br-stage-below: 88px; }
}
@media (max-width: 560px) {
  .br-stage { --br-stage-above: 322px; --br-stage-below: 80px; }
}
.br-card {
  display: grid;
  gap: 12px;
  padding: 18px 18px 16px;
  border: 1px solid var(--border);
  border-top: 3px solid var(--br-accent-line);
  background: var(--bg-secondary);
  box-shadow: 0 14px 38px rgba(10, 40, 20, .06);
}
.br-card.is-correct { border-top-color: var(--success); }
.br-card.is-wrong { border-top-color: var(--danger); }
.br-card-top { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.br-card-no { color: var(--text-tertiary); font-size: .7rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.br-card-body { min-width: 0; }

.br-cloze {
  margin: 0;
  color: var(--text-primary);
  font-size: 1rem;
  line-height: 2.5;
}
.br-cloze-hint { margin: 10px 0 0; color: var(--text-tertiary); font-size: .68rem; }

/* 挖空输入框：贴着文字走，宽度随答案长度给足但不夸张 */
.br-blank {
  display: inline-block;
  margin: 0 3px;
  padding: 1px 6px;
  border: 0;
  border-bottom: 1.5px solid var(--br-accent);
  background: var(--br-accent-soft);
  color: var(--text-primary);
  font-family: inherit;
  font-size: .95rem;
  font-weight: 650;
  text-align: center;
  outline: 0;
  transition: background 140ms ease, border-color 140ms ease;
}
.br-blank:focus {
  border-bottom-color: var(--br-accent);
  background: color-mix(in srgb, var(--br-accent) 16%, var(--bg-secondary));
  box-shadow: 0 2px 0 0 var(--br-accent);
}

/* 翻面卡 */
.br-flip-front { display: grid; gap: 8px; padding: 22px 0; text-align: center; }
.br-flip-prompt { margin: 0; color: var(--text-primary); font-size: 1.16rem; font-weight: 650; }
.br-flip-prompt strong { color: var(--br-accent); font-size: 1.5rem; font-variant-numeric: tabular-nums; }
/*
 * 关键词线索（`card.keywords`，模型逐条生成）。
 *
 * ⚠ 它是「记忆钩子」不是「答案列表」：所以做成小标签、灰色、不起眼，
 *   不能用 accent 色 —— 那会让人以为这些就是要背的内容。
 * ⚠ 用 `<ul>` + `flex-wrap` 而不是逗号连成一行：换行时不会把词拆断。
 */
.br-flip-keywords {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  margin: 2px 0 0;
  padding: 0;
  list-style: none;
}
.br-flip-keywords li {
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-primary);
  color: var(--text-secondary);
  font-size: .72rem;
  line-height: 1.5;
  white-space: nowrap;
}
/* 表格条目的翻面正面：把行标签当提示词（「大脑」→ 回想它的功能） */
.br-flip-label {
  margin: 0 0 6px;
  color: var(--br-accent);
  font-size: 1.42rem;
  font-weight: 700;
  line-height: 1.35;
  word-break: break-word;
}
.br-flip-where { margin: 0; color: var(--text-tertiary); font-size: .74rem; }
.br-flip-reason {
  margin: 6px auto 0;
  max-width: 30em;
  padding: 6px 10px;
  border: 1px dashed var(--border);
  background: var(--bg-primary);
  color: var(--text-tertiary);
  font-size: .68rem;
}
.br-flip-back { display: grid; gap: 10px; }
.br-flip-text { margin: 0; color: var(--text-primary); font-size: .96rem; line-height: 1.95; }
.br-flip-hl { margin: 0; color: var(--text-tertiary); font-size: .72rem; line-height: 1.9; }
.br-flip-text mark,
.br-flip-hl mark {
  padding: 0 2px;
  background: color-mix(in srgb, var(--warning) 34%, transparent);
  color: inherit;
}

/* 判分反馈 */
.br-feedback { margin-top: 14px; border: 1px solid var(--border); background: var(--bg-primary); }
.br-feedback-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--border-light);
}
.br-feedback-head strong { font-size: .84rem; }
.br-feedback-head span { color: var(--text-tertiary); font-size: .68rem; }
.br-feedback-head.is-correct strong { color: var(--success); }
.br-feedback-head.is-wrong strong { color: var(--danger); }
.br-feedback-list { margin: 0; padding: 0; list-style: none; }
.br-feedback-list li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr) auto;
  gap: 8px;
  align-items: center;
  padding: 7px 12px;
  border-bottom: 1px solid var(--border-light);
  font-size: .76rem;
}
.br-feedback-list li:last-child { border-bottom: 0; }
.br-fb-no {
  display: inline-flex;
  width: 18px;
  height: 18px;
  align-items: center;
  justify-content: center;
  background: var(--bg-tertiary);
  color: var(--text-tertiary);
  font-size: .62rem;
  font-weight: 700;
}
.br-fb-input { color: var(--text-secondary); overflow-wrap: anywhere; }
.br-fb-input i { color: var(--text-tertiary); }
.br-fb-arrow { color: var(--text-tertiary); }
.br-fb-answer { color: var(--text-primary); font-weight: 650; overflow-wrap: anywhere; }
.br-fb-note { font-size: .64rem; font-weight: 700; white-space: nowrap; }
.br-feedback-list li.is-correct .br-fb-note { color: var(--success); }
.br-feedback-list li.is-wrong .br-fb-note { color: var(--danger); }
.br-feedback-list li.is-empty .br-fb-note { color: var(--warning); }
.br-feedback-list li.is-correct .br-fb-answer { color: var(--success); }

/* 卡片操作 */
.br-card-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding-top: 4px;
}
.br-card-actions--grade { gap: 6px; }
.br-grade-hint { flex: 1 1 100%; color: var(--text-tertiary); font-size: .7rem; }
.br-grade {
  display: inline-flex;
  flex: 1 1 0;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 38px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
  color: var(--text-secondary);
  font-family: inherit;
  font-size: .8rem;
  font-weight: 650;
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease, color 150ms ease;
}
.br-grade--known:hover { border-color: var(--success); background: var(--success-light); color: var(--success); }
.br-grade--fuzzy:hover { border-color: var(--warning); background: var(--warning-light); color: var(--warning); }
.br-grade--forgot:hover { border-color: var(--danger); background: var(--danger-light); color: var(--danger); }
.br-next-note { flex: 1 1 auto; color: var(--br-accent); font-size: .74rem; font-weight: 650; }

/* 本轮小结 */
.br-summary {
  display: grid;
  gap: 10px;
  justify-items: center;
  padding: 42px 20px;
  border: 1px solid var(--border);
  background: var(--bg-secondary);
  text-align: center;
}
.br-summary-icon { font-size: 2.2rem; }
.br-summary h2 { margin: 0; color: var(--text-primary); font-size: 1.1rem; }
.br-summary-score { margin: 0; color: var(--text-secondary); font-size: .86rem; }
.br-summary-score strong { color: var(--br-accent); font-size: 1.4rem; font-variant-numeric: tabular-nums; }
.br-summary-tip { margin: 0; color: var(--text-tertiary); font-size: .7rem; }
.br-summary-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 6px; }

/* ---------- 浏览屏 ---------- */
.br-tree { padding: 6px 14px 14px; }
.br-book { border-bottom: 1px solid var(--border-light); }
.br-book:last-child { border-bottom: 0; }
.br-book > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 2px;
  cursor: pointer;
  list-style: none;
}
.br-book > summary::-webkit-details-marker { display: none; }
.br-book-name { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; min-width: 0; }
.br-book > summary strong { color: var(--text-primary); font-size: .88rem; }
.br-book > summary small { color: var(--text-tertiary); font-size: .66rem; }
.br-book > summary small b { color: var(--danger); }

/* 进度条：册 / 章 / 节 三级共用，宽度递减以体现层级 */
.br-mini-track {
  display: block;
  flex: 0 0 auto;
  width: 96px;
  height: 4px;
  overflow: hidden;
  background: var(--bg-active);
}
.br-mini-track i { display: block; height: 100%; background: var(--br-accent); transition: width 220ms ease; }
.br-mini-track--chapter { width: 70px; }
.br-mini-track--section { width: 46px; }

.br-chapter { padding: 0 0 10px 12px; }
.br-chapter h4 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 0 6px;
  color: var(--text-secondary);
  font-size: .76rem;
  font-weight: 700;
}
.br-chapter h4 > span { flex: 1 1 auto; min-width: 0; }
.br-chapter h4 small { color: var(--text-tertiary); font-size: .63rem; font-weight: 500; white-space: nowrap; }
.br-section-list { margin: 0; padding: 0; list-style: none; display: grid; gap: 4px; }
.br-section-btn {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border: 1px solid transparent;
  background: var(--bg-primary);
  color: var(--text-secondary);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease, color 150ms ease;
}
.br-section-btn:hover { border-color: var(--br-accent-line); background: var(--br-accent-soft); color: var(--br-accent); }
.br-section-name { flex: 1 1 auto; min-width: 0; font-size: .76rem; }
.br-section-meta { color: var(--text-tertiary); font-size: .64rem; white-space: nowrap; }
.br-section-meta b { color: var(--danger); }

/* ---------- 空态与加载 ---------- */
.br-empty,
.br-loading {
  display: grid;
  gap: 8px;
  justify-items: center;
  padding: 44px 20px;
  border: 1px solid var(--border);
  background: var(--bg-secondary);
  text-align: center;
}
.br-empty h2,
.br-empty h3,
.br-loading strong { margin: 0; color: var(--text-primary); font-size: 1rem; }
.br-empty p,
.br-loading p { margin: 0; color: var(--text-tertiary); font-size: .74rem; }
.br-empty--error { border-color: color-mix(in srgb, var(--danger) 34%, var(--border)); }
.br-spinner {
  width: 22px;
  height: 22px;
  border: 2px solid var(--border);
  border-top-color: var(--br-accent);
  border-radius: 50%;
  animation: br-spin 720ms linear infinite;
}
@keyframes br-spin { to { transform: rotate(360deg); } }

/* ---------- 答题方式切换 ---------- */
.br-quiz-row { gap: 10px; }
.br-quiz-label { color: var(--text-tertiary); font-size: .68rem; font-weight: 700; white-space: nowrap; }
.br-quiz-tabs { display: inline-flex; border: 1px solid var(--border); }
.br-quiz-tab {
  padding: 6px 13px;
  border: 0;
  border-right: 1px solid var(--border);
  background: var(--bg-primary);
  color: var(--text-secondary);
  font-family: inherit;
  font-size: .72rem;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.br-quiz-tab:last-child { border-right: 0; }
.br-quiz-tab:hover { background: var(--br-accent-soft); color: var(--br-accent); }
.br-quiz-tab.is-active { background: var(--br-accent); color: #fff; font-weight: 700; }
.br-quiz-tab:focus-visible { outline: 2px solid var(--br-accent); outline-offset: -2px; }
.br-quiz-note { color: var(--text-tertiary); font-size: .66rem; }

/* ---------- 四选一 / 判断题的选项 ---------- */
.br-choices {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px;
  margin-top: 14px;
}
.br-choices--judge { max-width: 320px; }
.br-choice {
  display: flex;
  align-items: center;
  gap: 9px;
  min-height: 46px;
  padding: 9px 13px;
  border: 1px solid var(--border);
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: inherit;
  font-size: .84rem;
  text-align: left;
  cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease, transform 90ms ease;
}
.br-choice:hover:not(:disabled) { border-color: var(--br-accent-line); background: var(--br-accent-soft); }
.br-choice:active:not(:disabled) { transform: scale(.985); }
.br-choice:focus-visible { outline: 2px solid var(--br-accent); outline-offset: 2px; }
.br-choice:disabled { cursor: default; }
.br-choice kbd { flex: 0 0 auto; }
.br-choice span { min-width: 0; word-break: break-word; }
.br-choice--judge { justify-content: center; font-size: .95rem; font-weight: 700; }
/* 判分后的三种状态：选中未判 / 正确 / 选错 */
.br-choice.is-picked { border-color: var(--br-accent); background: var(--br-accent-soft); }
.br-choice.is-right { border-color: var(--success); background: color-mix(in srgb, var(--success) 12%, var(--bg-primary)); }
.br-choice.is-wrong { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, var(--bg-primary)); }
/* 判断题里「填进去的那个词」要显眼，用户要盯着它判断 */
.br-quiz-given {
  padding: 1px 5px;
  border-bottom: 2px solid var(--br-accent);
  background: var(--br-accent-soft);
  color: var(--br-accent);
  font-weight: 700;
}

/* ---------- 响应式：窄屏折成一列 ---------- */
@media (max-width: 900px) {
  .br-overview { grid-template-columns: minmax(0, 1fr); }
  .br-progress { grid-column: auto; }
  .br-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .br-session-bar { grid-template-columns: auto minmax(0, 1fr); }
  .br-session-position { grid-column: 1 / -1; justify-items: start; text-align: left; }
  .br-feedback-list li { grid-template-columns: auto minmax(0, 1fr); }
  .br-fb-arrow { display: none; }
  .br-fb-note { grid-column: 2; }
}
@media (max-width: 560px) {
  /*
   * ⚠ 四格统计在手机上**保持 2×2，不要折成一列**。
   *   折成一列时四格各 63px 共 283px —— 加上今日卡(114)与全库覆盖(101)，
   *   概览区吃掉 517px，而手机视口只有 844px：**首屏一条条目都看不到**
   *   （实测首个条目距顶 1232px，要滚一屏半才开始看内容）。
   *   2×2 只要 ~140px，首屏能露出开始条与第一条。
   */
  .br-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .br-stat { padding: 7px 10px; }
  /* 数字小一点，四格才不至于把概览顶得很高 */
  .br-stat strong { font-size: 1.2rem; }
  .br-field select { max-width: 130px; }
  .br-cloze { font-size: .92rem; line-height: 2.7; }
  /* 手机上选项排一列：两列时「完全归纳法和不完全归纳法」这类长选项会被挤成三行 */
  .br-choices { grid-template-columns: minmax(0, 1fr); }
  .br-choices--judge { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: none; }
  .br-quiz-tab { padding: 6px 9px; font-size: .68rem; }
}

/* 减少动效 */
@media (prefers-reduced-motion: reduce) {
  .br-today-track i,
  .br-progress-track i,
  .br-session-track i { transition: none; }
  .br-spinner { animation-duration: 2s; }
}

/* ---------- 打卡 ---------- */

/* 工作台顶部的打卡条：一眼看到今天算不算打过卡 */
.br-checkin-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-tertiary);
  background: var(--bg-secondary);
}
.br-checkin-bar.is-ok {
  border-left-color: var(--success);
  background: color-mix(in srgb, var(--success) 7%, var(--bg-secondary));
}
.br-checkin-main { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; min-width: 0; }
.br-checkin-main strong { color: var(--text-primary); font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.br-checkin-bar.is-ok .br-checkin-main strong { color: var(--success); }
.br-checkin-sub { color: var(--text-tertiary); font-size: .7rem; }
.br-checkin-tools { display: flex; gap: 7px; flex-wrap: wrap; }

/* 打卡视图 */
.br-page--checkin { display: grid; gap: 12px; }
.br-checkin-hero {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 16px;
  border: 1px solid var(--border);
  background: var(--bg-secondary);
}
.br-checkin-hero-main { min-width: 0; }
.br-checkin-hero-main strong { display: block; font-size: 1.6rem; line-height: 1.2; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.br-checkin-hero-main p { margin: 3px 0 0; color: var(--text-tertiary); font-size: .72rem; }
.br-checkin-kpis { display: flex; gap: 18px; flex-wrap: wrap; }
.br-checkin-kpis > div { display: flex; align-items: baseline; gap: 5px; }
.br-checkin-kpis span { color: var(--text-tertiary); font-size: .68rem; }
.br-checkin-kpis strong { color: var(--br-accent); font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.br-checkin-kpis em { color: var(--text-tertiary); font-size: .66rem; font-style: normal; }
.br-checkin-cal-wrap { padding: 12px 14px 14px; }

/* 月历网格 */
.br-cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 5px; }
.br-cal-wd { text-align: center; color: var(--text-tertiary); font-size: .64rem; padding-bottom: 3px; }
.br-cal-cell {
  position: relative;
  min-height: 40px;
  padding: 4px 5px;
  border: 1px solid var(--border-light);
  background: var(--bg-primary);
  font-size: .7rem;
  color: var(--text-secondary);
}
.br-cal-cell.is-blank { border: 0; background: none; }
.br-cal-cell.is-ok {
  border-color: color-mix(in srgb, var(--success) 45%, var(--border));
  background: color-mix(in srgb, var(--success) 12%, var(--bg-primary));
}
.br-cal-cell.is-ok .br-cal-day { color: var(--success); font-weight: 700; }
.br-cal-cell.is-partial {
  border-color: color-mix(in srgb, var(--warning) 45%, var(--border));
  background: color-mix(in srgb, var(--warning) 10%, var(--bg-primary));
}
.br-cal-cell.is-today { outline: 2px solid var(--br-accent); outline-offset: -2px; }
.br-cal-day { font-variant-numeric: tabular-nums; }
.br-cal-mark { position: absolute; right: 5px; bottom: 3px; font-size: .72rem; font-weight: 700; }
.br-cal-cell.is-ok .br-cal-mark { color: var(--success); }
.br-cal-cell.is-partial .br-cal-mark { color: var(--warning); }

/* 打卡明细表 */
.br-table-wrap { overflow-x: auto; }
.br-table { width: 100%; border-collapse: collapse; font-size: .74rem; }
.br-table th,
.br-table td { padding: 7px 10px; text-align: left; border-bottom: 1px solid var(--border-light); white-space: nowrap; }
.br-table th { color: var(--text-tertiary); font-weight: 700; font-size: .66rem; background: var(--bg-primary); }
.br-table tbody tr.is-ok td { background: color-mix(in srgb, var(--success) 6%, transparent); }
.br-table tbody tr.is-miss td { background: color-mix(in srgb, var(--danger) 5%, transparent); }
.br-table td.br-num { text-align: right; font-variant-numeric: tabular-nums; }
.br-empty-row { text-align: center; color: var(--text-tertiary); padding: 18px 10px; }

/* 小号 ghost 按钮（表格里的「打印」） */
.br-ghost-btn--xs { padding: 3px 8px; font-size: .66rem; min-height: 0; }
.br-tag--ok { border-color: color-mix(in srgb, var(--success) 30%, var(--border)); color: var(--success); }

/* 骨架屏（打卡视图懒加载时） */
.br-skeleton { padding: 40px 16px; text-align: center; color: var(--text-tertiary); font-size: .78rem; }

@media (max-width: 560px) {
  .br-checkin-bar { flex-direction: column; align-items: stretch; gap: 8px; padding: 9px 12px; }
  .br-checkin-tools { justify-content: flex-start; }
  .br-checkin-hero { padding: 12px; }
  .br-checkin-hero-main strong { font-size: 1.35rem; }
  .br-checkin-kpis { gap: 12px; }
  .br-checkin-kpis strong { font-size: 1rem; }
  .br-cal { gap: 3px; }
  .br-cal-cell { min-height: 34px; padding: 3px 4px; font-size: .64rem; }
  .br-checkin-cal-wrap { padding: 10px; }
}

/* ==== pages/bio-xiaoti.css ==== */
/*
 * 生物 · 小题全刷（.xq-*）
 *
 * 工作台 + 答题屏 + 结果屏。
 *
 * ⚠ 颜色一律走项目 token（--bg-secondary / --border / --text-*），
 *   深色主题与壁纸模式才会自动跟上。
 * ⚠ 裸文字类必须同时登记进 wallpaper.css 的背衬名单。
 */

.xq-page {
  --xq-accent: #15803d;
  --xq-accent-soft: color-mix(in srgb, var(--xq-accent) 9%, var(--bg-secondary));
  --xq-accent-line: color-mix(in srgb, var(--xq-accent) 30%, var(--border));
  margin: 0 auto;
  padding: 20px 0 56px;
}
.xq-page--workbench { width: min(1080px, calc(100% - 32px)); }
.xq-page--session { width: min(880px, calc(100% - 24px)); padding-bottom: 24px; }
.xq-page--result { width: min(960px, calc(100% - 32px)); }

/* ---------- 页头 ---------- */
.xq-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px;
  align-items: end;
  margin-bottom: 18px;
}
.xq-eyebrow {
  display: block;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--xq-accent);
}
.xq-title {
  margin: 4px 0 6px;
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--text-primary);
  letter-spacing: -.01em;
}
.xq-sub {
  margin: 0;
  font-size: .78rem;
  color: var(--text-tertiary);
}
.xq-header-stats {
  display: flex;
  gap: 10px;
}
.xq-hstat {
  min-width: 72px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 8px);
  background: var(--bg-secondary);
  text-align: center;
}
.xq-hstat span {
  display: block;
  font-size: .66rem;
  color: var(--text-tertiary);
}
.xq-hstat strong {
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.xq-hstat em {
  font-style: normal;
  font-size: .68rem;
  font-weight: 400;
  color: var(--text-tertiary);
}

/* ---------- 组题卡 ---------- */
.xq-composer {
  padding: 18px 20px;
  margin-bottom: 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 12px);
  background: var(--bg-secondary);
}
.xq-composer-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 16px;
}
.xq-composer-head strong {
  font-size: .95rem;
  color: var(--text-primary);
}
.xq-composer-note {
  font-size: .7rem;
  color: var(--text-tertiary);
}
.xq-field { margin-bottom: 14px; }
.xq-field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
}
.xq-label {
  display: block;
  margin-bottom: 6px;
  font-size: .72rem;
  font-weight: 600;
  color: var(--text-tertiary);
}

/* 分段按钮 */
.xq-seg {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-primary);
}
.xq-seg-btn {
  padding: 5px 12px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: .76rem;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, color .15s;
}
.xq-seg-btn:hover { background: var(--xq-accent-soft); color: var(--text-primary); }
.xq-seg-btn.is-on {
  background: var(--xq-accent);
  color: #fff;
}

.xq-select {
  width: 100%;
  max-width: 520px;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-primary);
  color: var(--text-primary);
  font: inherit;
  font-size: .78rem;
}
.xq-select--multi { height: auto; }
.xq-hint {
  display: block;
  margin-top: 5px;
  font-size: .68rem;
  color: var(--text-tertiary);
}

.xq-composer-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.xq-today-hint {
  font-size: .74rem;
  color: var(--text-tertiary);
}
.xq-composer-actions {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.xq-btn--wrong {
  border-color: color-mix(in srgb, #ef4444 35%, var(--border));
  color: #b91c1c;
}
.xq-btn--wrong:hover:not(:disabled) {
  border-color: #ef4444;
  background: color-mix(in srgb, #ef4444 7%, transparent);
}

/* ---------- 按钮 ---------- */
.xq-btn {
  padding: 7px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 8px);
  background: var(--bg-primary);
  color: var(--text-secondary);
  font: inherit;
  font-size: .78rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color .15s, color .15s, background .15s;
}
.xq-btn:hover:not(:disabled) { border-color: var(--xq-accent-line); color: var(--text-primary); }
.xq-btn:disabled { opacity: .5; cursor: not-allowed; }
.xq-btn--primary {
  background: var(--xq-accent);
  border-color: var(--xq-accent);
  color: #fff;
}
.xq-btn--primary:hover:not(:disabled) {
  background: color-mix(in srgb, var(--xq-accent) 88%, #000);
  color: #fff;
}
.xq-btn--ghost { background: transparent; }
.xq-btn--ghost-primary { background: transparent; color: var(--xq-accent); border-color: var(--xq-accent-line); }
.xq-btn--lg { padding: 10px 22px; font-size: .86rem; }
.xq-btn--xs { padding: 3px 9px; font-size: .7rem; }

/* ---------- 面板 ---------- */
.xq-panel {
  margin-bottom: 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 12px);
  background: var(--bg-secondary);
  overflow: hidden;
}
.xq-panel-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
.xq-panel-head strong { font-size: .86rem; color: var(--text-primary); }
.xq-panel-note { font-size: .7rem; color: var(--text-tertiary); }

/* ---------- 模块树 ---------- */
.xq-modules { padding: 6px 10px 10px; }
.xq-module { border-bottom: 1px solid var(--border); }
.xq-module:last-child { border-bottom: 0; }
.xq-module-sum {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) auto minmax(80px, 1fr);
  gap: 12px;
  align-items: center;
  padding: 10px 6px;
  cursor: pointer;
  list-style: none;
}
.xq-module-sum::-webkit-details-marker { display: none; }
.xq-module-name { font-size: .82rem; font-weight: 600; color: var(--text-primary); }
.xq-module-meta { font-size: .72rem; color: var(--text-tertiary); }
.xq-module-bar {
  height: 6px;
  border-radius: 3px;
  background: var(--bg-primary);
  overflow: hidden;
}
.xq-module-fill {
  display: block;
  height: 100%;
  background: var(--xq-accent);
}
.xq-section-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 4px;
  padding: 2px 6px 10px;
}
.xq-section-item {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  padding: 6px 10px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: var(--bg-primary);
  color: var(--text-secondary);
  font: inherit;
  font-size: .74rem;
  text-align: left;
  cursor: pointer;
}
.xq-section-item:hover { border-color: var(--xq-accent-line); color: var(--text-primary); }
.xq-section-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.xq-section-meta { flex: none; font-size: .68rem; color: var(--text-tertiary); }

/* ---------- 表格 ---------- */
.xq-table-wrap { overflow-x: auto; }
.xq-table { width: 100%; border-collapse: collapse; font-size: .78rem; }
.xq-table th, .xq-table td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  text-align: left;
  white-space: nowrap;
}
.xq-table th { font-size: .7rem; font-weight: 600; color: var(--text-tertiary); }
.xq-table tbody tr:last-child td { border-bottom: 0; }
.xq-table tbody tr.is-ok { background: color-mix(in srgb, var(--xq-accent) 6%, transparent); }
.xq-table tbody tr.is-bad { background: color-mix(in srgb, #ef4444 6%, transparent); }
.xq-td-num { text-align: right; font-variant-numeric: tabular-nums; color: var(--text-secondary); }
.xq-td-mid { text-align: center; color: var(--text-secondary); }
.xq-td-parts { color: var(--text-tertiary); font-size: .72rem; }

/* ---------- 答题屏 ---------- */
.xq-session-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  margin-bottom: 10px;
}
.xq-session-title strong {
  display: block;
  font-size: .92rem;
  color: var(--text-primary);
}
.xq-session-sub { font-size: .7rem; color: var(--text-tertiary); }
.xq-clock {
  min-width: 76px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-secondary);
  font-size: 1.05rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--text-primary);
}
.xq-clock.is-warn { color: #b45309; border-color: color-mix(in srgb, #f59e0b 50%, var(--border)); }
.xq-clock.is-danger { color: #b91c1c; border-color: #ef4444; }

.xq-progress {
  height: 4px;
  margin-bottom: 14px;
  border-radius: 2px;
  background: var(--bg-secondary);
  overflow: hidden;
}
.xq-progress-fill {
  display: block;
  height: 100%;
  background: var(--xq-accent);
  transition: width .2s;
}

.xq-question {
  padding: 16px 18px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 12px);
  background: var(--bg-secondary);
}
.xq-question-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin-bottom: 12px;
}
.xq-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 5px;
  background: var(--xq-accent);
  color: #fff;
  font-size: .72rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.xq-badge--sm { font-size: .68rem; padding: 1px 6px; }
.xq-meta-chip {
  padding: 2px 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: .68rem;
  color: var(--text-tertiary);
  background: var(--bg-primary);
}

.xq-stem { margin-bottom: 16px; }
.xq-stem-img {
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
  border-radius: 8px;
  background: #fff;
  cursor: zoom-in;
}
.xq-stem-text {
  font-size: .92rem;
  line-height: 1.85;
  color: var(--text-primary);
  white-space: pre-wrap;
  word-break: break-word;
}

.xq-options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 8px;
}
.xq-options.is-multi { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.xq-opt {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-primary);
  color: var(--text-secondary);
  font: inherit;
  font-size: .84rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color .12s, background .12s, color .12s;
}
.xq-opt:hover { border-color: var(--xq-accent-line); color: var(--text-primary); }
.xq-opt.is-on {
  border-color: var(--xq-accent);
  background: var(--xq-accent-soft);
  color: var(--text-primary);
}
.xq-opt-letter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--bg-secondary);
  font-size: .8rem;
  font-weight: 800;
  color: var(--text-tertiary);
}
.xq-opt.is-on .xq-opt-letter { background: var(--xq-accent); color: #fff; }
.xq-opt-hint { font-size: .68rem; font-weight: 400; color: var(--text-tertiary); }
/* 纯文字题的选项文字（图片题的选项在题图里，没有这一层） */
/* 材料题：每个小问一组选项 */
.xq-subq {
  margin-top: 14px;
}
.xq-subq:first-child {
  margin-top: 0;
}
.xq-subq-label {
  font-size: .76rem;
  font-weight: 600;
  color: var(--text-secondary);
  margin-bottom: 8px;
  padding-left: 2px;
}
.xq-subq .xq-options {
  margin-top: 0;
}

.xq-opt-label {
  min-width: 0;
  font-size: .82rem;
  font-weight: 500;
  line-height: 1.5;
  text-align: left;
  white-space: normal;
}

.xq-dots {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin: 14px 0;
}
.xq-dot {
  width: 28px;
  height: 28px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-secondary);
  color: var(--text-tertiary);
  font: inherit;
  font-size: .7rem;
  font-weight: 700;
  cursor: pointer;
}
.xq-dot.is-done {
  border-color: var(--xq-accent-line);
  background: var(--xq-accent-soft);
  color: var(--xq-accent);
}
.xq-dot.is-cur { outline: 2px solid var(--xq-accent); outline-offset: -2px; }

.xq-session-foot {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  flex-wrap: wrap;
}

/* ---------- 结果屏 ---------- */
.xq-result-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px;
  align-items: end;
  margin-bottom: 18px;
}
.xq-result-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.xq-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
  margin-bottom: 18px;
}
.xq-stat {
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 8px);
  background: var(--bg-secondary);
}
.xq-stat span { display: block; font-size: .7rem; color: var(--text-tertiary); }
.xq-stat strong {
  font-size: 1.3rem;
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.xq-result-note {
  margin: 4px 0 0;
  font-size: .74rem;
  color: var(--text-tertiary);
  text-align: center;
}

.xq-tag {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 5px;
  font-size: .68rem;
  font-weight: 600;
}
.xq-tag--ok { background: color-mix(in srgb, var(--xq-accent) 14%, transparent); color: var(--xq-accent); }
.xq-tag--bad { background: color-mix(in srgb, #ef4444 14%, transparent); color: #b91c1c; }

/* ---------- 空态 / 骨架 ---------- */
.xq-empty { padding: 48px 20px; text-align: center; color: var(--text-tertiary); }
.xq-empty h3 { margin: 0 0 8px; color: var(--text-secondary); font-size: .95rem; }
.xq-empty p { margin: 0 0 14px; font-size: .8rem; }
.xq-skeleton { padding: 60px 20px; text-align: center; color: var(--text-tertiary); font-size: .84rem; }

/* ---------- 窄屏 ---------- */
@media (max-width: 760px) {
  .xq-page--workbench, .xq-page--result { width: calc(100% - 20px); }
  .xq-header { grid-template-columns: 1fr; align-items: start; }
  .xq-header-stats { justify-content: flex-start; }
  .xq-module-sum { grid-template-columns: minmax(0, 1fr) auto; }
  .xq-module-bar { display: none; }
  .xq-options { grid-template-columns: 1fr; }
  .xq-result-head { grid-template-columns: 1fr; align-items: start; }
  .xq-result-actions { justify-content: flex-start; }
  /* 题图在窄屏不缩成一条：给横向滚动 + 最小宽度，保证字可读 */
  .xq-stem { overflow-x: auto; }
  .xq-stem-img { min-width: 640px; }
}

/* 删除类按钮：低饱和红，hover 才明显 —— 破坏性操作不该抢视觉焦点 */
.xq-btn--danger {
  border-color: color-mix(in srgb, #ef4444 25%, var(--border));
  color: #b91c1c;
}
.xq-btn--danger:hover:not(:disabled) {
  border-color: #ef4444;
  background: color-mix(in srgb, #ef4444 8%, transparent);
}

/* ============================ 范围多选标签 ============================ */
/*
 * 用可点选标签代替 <select multiple>：原生多选要按住 Ctrl/⌘，
 * 手机上做不到（长按是系统菜单）。标签点一下切换，全平台一致。
 */
.xq-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  max-height: 240px;
  overflow-y: auto;
  padding: 2px;
  margin-top: 8px;
}
.xq-chips--dense {
  max-height: 300px;
}
.xq-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  padding: 5px 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2, rgba(255, 255, 255, .04));
  color: var(--text-secondary);
  font-size: .74rem;
  line-height: 1.3;
  cursor: pointer;
  transition: border-color .12s, background .12s, color .12s;
}
.xq-chip:hover {
  border-color: color-mix(in srgb, var(--accent, #15803d) 45%, var(--border));
  color: var(--text-primary);
}
.xq-chip.is-on {
  border-color: var(--accent, #15803d);
  background: color-mix(in srgb, var(--accent, #15803d) 16%, transparent);
  color: var(--text-primary);
  font-weight: 600;
}
.xq-chip-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.xq-chip-count {
  flex: none;
  padding: 1px 5px;
  border-radius: 999px;
  background: color-mix(in srgb, currentColor 12%, transparent);
  font-size: .66rem;
  font-variant-numeric: tabular-nums;
  opacity: .8;
}
.xq-scope-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
}
.xq-scope-total {
  font-size: .72rem;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}
.xq-scope-total strong {
  color: var(--text-primary);
  font-weight: 600;
}
.xq-link {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent, #15803d);
  font-size: .72rem;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.xq-link:hover {
  opacity: .8;
}



/* ============================ 结果页：逐题行 ============================ */
/*
 * 每行是一个 <button>（不是 <details>）：单击弹出解析窗口。
 * 用 button 而不是 div+click，键盘 Tab/Enter 天然可用。
 */
.xq-review-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px;
}
.xq-review-row {
  display: grid;
  grid-template-columns: 28px 54px minmax(140px, 1fr) 40px minmax(90px, 170px) 60px;
  gap: 8px;
  align-items: center;
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: 8px;
  background: var(--surface-1, rgba(255, 255, 255, .02));
  color: inherit;
  font-size: .78rem;
  text-align: left;
  cursor: pointer;
  transition: background .12s, border-color .12s;
}
.xq-review-row.is-ok { border-left-color: #22c55e; }
.xq-review-row.is-bad { border-left-color: #ef4444; }
.xq-review-row:hover {
  background: color-mix(in srgb, var(--accent, #15803d) 8%, transparent);
  border-color: color-mix(in srgb, var(--accent, #15803d) 35%, var(--border));
}
.xq-review-row:focus-visible {
  outline: 2px solid var(--accent, #15803d);
  outline-offset: 1px;
}
.xq-review-no {
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.xq-review-answers {
  display: flex;
  gap: 12px;
  font-size: .74rem;
  color: var(--text-secondary);
}
.xq-review-answers em {
  font-style: normal;
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.xq-review-sec {
  font-size: .72rem;
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.xq-review-more {
  justify-self: end;
  font-size: .7rem;
  color: var(--accent, #15803d);
  white-space: nowrap;
}

@media (max-width: 720px) {
  .xq-review-row {
    grid-template-columns: 22px 48px 1fr 36px 52px;
  }
  .xq-review-sec { display: none; }
}

/* ============================ 解析弹窗 ============================ */
/*
 * 用户要求「单击后显示新窗口，可随时关闭」。
 * 自绘弹层而不是 window.open：新窗口没有样式、也没法回到原位置。
 */
.xq-modal {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.xq-modal-mask {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .58);
  backdrop-filter: blur(2px);
}
.xq-modal-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(880px, 100%);
  max-height: calc(100vh - 40px);
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-0, #111);
  box-shadow: 0 18px 60px rgba(0, 0, 0, .55);
  overflow: hidden;
}
.xq-modal-head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-1, rgba(255, 255, 255, .03));
}
.xq-modal-title {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.xq-modal-sec {
  font-size: .72rem;
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.xq-modal-verdict {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
  font-size: .74rem;
  color: var(--text-secondary);
}
.xq-modal-answers em {
  font-style: normal;
  font-weight: 700;
  color: var(--text-primary);
}
.xq-modal-close {
  flex: none;
  width: 28px;
  height: 28px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
.xq-modal-close:hover {
  border-color: #ef4444;
  color: #ef4444;
}
.xq-modal-body {
  padding: 14px;
  overflow-y: auto;
}
.xq-modal-stem {
  font-size: .86rem;
  line-height: 1.8;
  color: var(--text-primary);
  white-space: pre-wrap;
  word-break: break-word;
}
.xq-modal-image img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 6px;
}
.xq-modal-options {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 10px;
}
.xq-modal-opt {
  display: flex;
  gap: 8px;
  padding: 5px 8px;
  border-radius: 6px;
  font-size: .8rem;
  line-height: 1.6;
  color: var(--text-secondary);
}
.xq-modal-opt.is-picked {
  background: color-mix(in srgb, #ef4444 10%, transparent);
}
.xq-modal-opt.is-answer {
  background: color-mix(in srgb, #22c55e 12%, transparent);
  color: var(--text-primary);
}
.xq-modal-opt-key {
  flex: none;
  font-weight: 700;
  color: var(--text-primary);
}
.xq-modal-opt-text {
  min-width: 0;
  word-break: break-word;
}
.xq-modal-analysis {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px dashed var(--border);
}
.xq-modal-analysis h3 {
  margin: 0 0 8px;
  font-size: .78rem;
  font-weight: 600;
  color: var(--text-secondary);
  letter-spacing: .02em;
}
/* ==== pages/bio-checkin-print.css ==== */
/*
 * 生物 · 打卡打印（.bcp-*）
 *
 * 独立页面：`/bio/checkin-print`，从生物工作台「打卡打印」卡片进入。
 *
 * ⚠ 颜色一律走项目 token（--bg-secondary / --border / --text-*），
 *   深色主题与壁纸模式才会自动跟上；写死色值在壁纸下会像贴片。
 * ⚠ 与「学习打卡清单」(.ck-*) 是两套样式：那边是统计看板，
 *   这边只负责选打印出口，布局更简单。
 */

.bcp-page {
  --bcp-accent: #15803d;
  --bcp-accent-soft: color-mix(in srgb, var(--bcp-accent) 9%, var(--bg-secondary));
  --bcp-accent-line: color-mix(in srgb, var(--bcp-accent) 28%, var(--border));
  margin: 0 auto;
  padding: 20px 0 56px;
  width: min(1080px, calc(100% - 32px));
}

/* ---------- 页头 ---------- */
.bcp-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px;
  align-items: end;
  margin-bottom: 18px;
}
.bcp-eyebrow {
  display: block;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bcp-accent);
}
/* 壁纸模式下 wallpaper.css 会给「直接含 h1 的容器」垫背衬；
   这个块要能容纳那层 -12px/-16px 的外扩，否则贴边发糊。 */
.bcp-title-block { min-width: 0; }
.bcp-title {
  margin: 4px 0 6px;
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--text-primary);
  letter-spacing: -.01em;
}
.bcp-sub {
  margin: 0;
  font-size: .78rem;
  color: var(--text-tertiary);
}
.bcp-header-tools {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* ---------- 按钮 ---------- */
.bcp-btn {
  padding: 7px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 8px);
  background: var(--bg-secondary);
  color: var(--text-secondary);
  font: inherit;
  font-size: .78rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color .15s, color .15s, background .15s;
}
.bcp-btn:hover { border-color: var(--bcp-accent-line); color: var(--text-primary); }
.bcp-btn:focus-visible { outline: 2px solid var(--bcp-accent); outline-offset: 2px; }
.bcp-btn--primary {
  background: var(--bcp-accent);
  border-color: var(--bcp-accent);
  color: #fff;
}
.bcp-btn--primary:hover { background: color-mix(in srgb, var(--bcp-accent) 88%, #000); color: #fff; }
.bcp-btn--xs { padding: 3px 9px; font-size: .7rem; }

/* ---------- 统计 ---------- */
.bcp-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
  margin-bottom: 18px;
}
.bcp-stat {
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 8px);
  background: var(--bg-secondary);
}
.bcp-stat span {
  display: block;
  font-size: .7rem;
  color: var(--text-tertiary);
}
.bcp-stat strong {
  font-size: 1.35rem;
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.bcp-stat em {
  margin-left: 3px;
  font-style: normal;
  font-size: .7rem;
  color: var(--text-tertiary);
}
.bcp-stat.is-hit {
  border-color: var(--bcp-accent-line);
  background: var(--bcp-accent-soft);
}
.bcp-stat.is-hit strong { color: var(--bcp-accent); }

/* ---------- 面板 ---------- */
.bcp-panel {
  margin-bottom: 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 12px);
  background: var(--bg-secondary);
  overflow: hidden;
}
.bcp-panel-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
.bcp-panel-head strong {
  font-size: .86rem;
  color: var(--text-primary);
}
.bcp-panel-note {
  font-size: .7rem;
  color: var(--text-tertiary);
}

/* ---------- 表格 ---------- */
.bcp-table-wrap { overflow-x: auto; }
.bcp-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .78rem;
}
.bcp-table th,
.bcp-table td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
  text-align: left;
  white-space: nowrap;
}
.bcp-table th {
  font-size: .7rem;
  font-weight: 600;
  color: var(--text-tertiary);
  background: color-mix(in srgb, var(--bg-primary) 60%, var(--bg-secondary));
}
.bcp-table tbody tr:last-child td { border-bottom: 0; }
.bcp-td-name { font-weight: 600; color: var(--text-primary); }
.bcp-td-num { text-align: right; font-variant-numeric: tabular-nums; color: var(--text-secondary); }
.bcp-td-mid { text-align: center; color: var(--text-secondary); }
.bcp-td-actions { white-space: nowrap; }
.bcp-td-actions .bcp-btn + .bcp-btn { margin-left: 6px; }
.bcp-td-empty { text-align: center; color: var(--text-tertiary); padding: 24px; }
.bcp-unit { margin-left: 4px; font-size: .68rem; font-weight: 400; color: var(--text-tertiary); }

/* ---------- 按天看 / 打印（日历式，与打卡日历同形态） ---------- */
.bcp-cal {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  padding: 14px 16px 4px;
}
.bcp-cal-wd {
  text-align: center;
  font-size: .68rem;
  color: var(--text-tertiary);
  padding: 2px 0;
}
.bcp-cal-cell {
  position: relative;
  display: block;
  min-height: 44px;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-primary);
  color: inherit;
  font: inherit;
  text-align: left;
}
.bcp-cal-cell.has-detail { min-height: 62px; }
.bcp-cal-cell.is-blank { border: 0; background: transparent; }
.bcp-cal-cell.is-today { outline: 2px solid var(--bcp-accent); outline-offset: -2px; }
.bcp-cal-cell.is-clickable { cursor: pointer; }
.bcp-cal-cell.is-clickable:hover {
  border-color: var(--bcp-accent-line);
  background: var(--bcp-accent-soft);
}
.bcp-cal-cell.is-clickable:focus-visible { outline: 2px solid var(--bcp-accent); outline-offset: 2px; }
.bcp-cal-day { font-size: .68rem; color: var(--text-tertiary); }
.bcp-cal-detail {
  display: block;
  margin-top: 2px;
  font-size: .62rem;
  line-height: 1.35;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  word-break: break-word;
}
.bcp-day-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  padding: 10px 16px 16px;
}
.bcp-day-actions .bcp-hint { padding: 0; flex: 1 1 260px; }
.bcp-day-manual {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  padding: 0 16px 16px;
}
/*
 * ⚠ 必须用这条压过上面的 display:flex：`[hidden]` 的浏览器默认样式
 *   只有 `display:none` 一条，优先级低于类选择器 —— 否则手动日期入口
 *   明明写了 hidden 却一直显示（实测截图里就是直接展开了）。
 */
.bcp-day-manual[hidden] { display: none; }
.bcp-day-label {
  font-size: .78rem;
  color: var(--text-secondary);
}
.bcp-day-manual input[type="date"] {
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 8px);
  background: var(--bg-primary);
  color: var(--text-primary);
  font: inherit;
  font-size: .78rem;
}
.bcp-day-manual input[type="date"]:focus-visible {
  outline: 2px solid var(--bcp-accent);
  outline-offset: 2px;
}
.bcp-hint {
  margin: 0;
  padding: 0 16px 16px;
  font-size: .72rem;
  color: var(--text-tertiary);
}

/* ---------- 说明 ---------- */
.bcp-note-list {
  margin: 0;
  padding: 14px 16px 16px 32px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: .76rem;
  line-height: 1.7;
  color: var(--text-secondary);
}

/* ---------- 空态 / 骨架 ---------- */
.bcp-empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--text-tertiary);
}
.bcp-empty h3 { margin: 0 0 8px; color: var(--text-secondary); font-size: .95rem; }
.bcp-empty p { margin: 0 0 14px; font-size: .8rem; }
.bcp-skeleton {
  padding: 60px 20px;
  text-align: center;
  color: var(--text-tertiary);
  font-size: .84rem;
}

/* ---------- 窄屏 ---------- */
@media (max-width: 760px) {
  .bcp-page { width: calc(100% - 20px); }
  .bcp-header { grid-template-columns: 1fr; align-items: start; }
  .bcp-header-tools { justify-content: flex-start; }
  .bcp-stats { grid-template-columns: repeat(2, 1fr); }
  .bcp-cal { gap: 3px; padding: 12px 12px 4px; }
  .bcp-cal-cell { min-height: 38px; padding: 3px; }
  .bcp-cal-cell.has-detail { min-height: 54px; }
  .bcp-cal-detail { font-size: .58rem; line-height: 1.3; }
  .bcp-day-manual { align-items: stretch; }
  .bcp-day-label { width: 100%; }
  .bcp-day-manual input[type="date"] { flex: 1 1 140px; }
}
/* ==== pages/practice.css ==== */
/*
 * 通用刷题模块（.pra-*）：工作台 / 答题屏 / 交卷总结 / 内置错题本
 *
 * ## 这一层覆盖什么
 *
 * 类名清单由 `docs/PRACTICE_CONTRACT.md` 第 7.5 节钉住（B 前端按它写 DOM，
 * C 按它写样式）。**清单里出现的每个类这里都必须有规则** —— 漏一个的表现
 * 不是报错，是那一块没有间距/没有边框，页面看起来「错位」。
 *
 * ## 三条硬约束
 *
 * 1. **颜色一律走 Token**（`--bg-secondary` / `--border` / `--accent-fill` /
 *    `--success` / `--warning` / `--danger` / `--radius-*` / `--shadow-*`）。
 *    写死 `#fff` / `#000` 在壁纸模式下会变成贴在照片上的实色块，而且深浅色
 *    切换时不会跟随 —— 这两类问题都不报错。
 * 2. **实底控件用 `--accent-fill` 而不是 `--accent`**：深色主题里 `--accent`
 *    是「浅蓝文字色」，拿它当按钮底色 + 白字只有 2.4:1（refine.css 顶部注释
 *    有实测记录）。文字/描边才用 `--accent`。
 * 3. **裸文字要登记**：直接铺在页面上、祖先链全透明的小字（`.pra-hint` /
 *    `.pra-meta` / `.pra-unit-meta` / `.pra-topic-meta` …）已经加进
 *    `css/pages/wallpaper.css` 的「零散小字的背衬」名单，否则壁纸亮部读不清。
 *
 * ## 答题屏的布局模型（给前端看）
 *
 * `.pra-session` 是一个两列 grid：左列题目、右列作答+流面板+结果。
 * 子元素**按类定位、不按 DOM 顺序**，所以前端可以自由排列：
 *
 *     .pra-session-head / .pra-summary / .pra-session-foot   → 跨两列
 *     .pra-question                                          → 第 1 列
 *     .pra-answer / .pra-stream-panel / .pra-grade-result
 *     / .pra-submit-row / .pra-countdown / .pra-progress-bar  → 第 2 列
 *
 * 如果前端选择自己包一层 `.pra-session-body`，它跨两列并自身变成同样的
 * 两列 grid（内部规则完全相同）。**两种都支持，别同时用**。
 * 窄屏（<=960px）统一折成一列，并把题目排到最前。
 */

/* ============================================================
   0. 模块级 Token
   ============================================================ */

.pra-page {
  /* 墨色/纸面：手写引擎（js/modules/practice/ink.js）用 getComputedStyle
     读这两个值来定笔色与橡皮擦除后的底色。挂在根上，工具条换色时只改
     这里的内联变量，不用逐个 canvas 重算。 */
  --pra-ink-paper: var(--bg-primary);
  --pra-ink-ink: var(--text-primary);

  /* 判分三态：语义色在两种主题下都有 AA 对比度，但「淡底」需要自己混。
     用 color-mix 而不是 rgba()：壁纸模式下 --bg-secondary 是半透明玻璃，
     混出来的淡底会跟着变，不会突兀。 */
  --pra-ok-soft: color-mix(in srgb, var(--success) 10%, var(--bg-secondary));
  --pra-ok-line: color-mix(in srgb, var(--success) 46%, var(--border));
  --pra-warn-soft: color-mix(in srgb, var(--warning) 12%, var(--bg-secondary));
  --pra-warn-line: color-mix(in srgb, var(--warning) 48%, var(--border));
  --pra-bad-soft: color-mix(in srgb, var(--danger) 10%, var(--bg-secondary));
  --pra-bad-line: color-mix(in srgb, var(--danger) 46%, var(--border));

  /* 答题屏两栏的断点用变量钉住，媒体查询里也引同一个值（见文末）。
     480px 是右栏的下限：再窄「提交批改」按钮会挤成两行。 */
  --pra-side: minmax(320px, 460px);

  width: min(1180px, calc(100% - 32px));
  margin: 0 auto;
  padding: 8px 0 56px;
}

/* 答题屏比工作台窄一档：两栏加起来不需要 1180px，太宽会让题目行宽超过
   可读上限（~75ch），眼睛要来回扫。
   ⚠ 前端把 `.pra-page` 与 `.pra-session` 挂在**同一个元素**上
     （`class="pra-page pra-session"`），所以这里必须用 `.pra-page.pra-session`
     这种双类写法；`.pra-page--session` 是等价的修饰符别名，两个都认。 */
.pra-page--session,
.pra-page.pra-session { width: min(1120px, calc(100% - 28px)); padding-bottom: 32px; }
.pra-page--wrongbook { width: min(1000px, calc(100% - 32px)); }

/* 深色/壁纸下「淡底」混色的基色不同，三态边线要略提亮一档，
   否则压在玻璃上会糊成一片（与 bio-recitation 的处理同源）。 */
[data-theme="dark"] .pra-page {
  --pra-ok-line: color-mix(in srgb, var(--success) 58%, var(--border));
  --pra-warn-line: color-mix(in srgb, var(--warning) 60%, var(--border));
  --pra-bad-line: color-mix(in srgb, var(--danger) 58%, var(--border));
}

/* ============================================================
   1. 页头
   ============================================================ */

.pra-header {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  margin-bottom: 18px;
}

.pra-back-btn {
  display: inline-flex;
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-secondary);
  color: var(--text-secondary);
  cursor: pointer;
  transition: color var(--transition-fast), border-color var(--transition-fast),
    background var(--transition-fast);
  /* ⚠ 壁纸模式下，标题块（`:has(> h2)`）会获得一层 `inset: -12px -16px` 的背衬，
     向左伸出 16px。窄屏折行后标题紧贴返回按钮，那层背衬会压在按钮上
     （实测 900px：背衬左缘 60px，按钮右缘 68px → 压住 8px）。
     背衬是 `z-index: -1` + `isolation: isolate` 的伪元素，而按钮原本是
     `position: static`，静态元素永远画在定位元素下面 —— 所以给按钮一个
     定位 + 正的 z-index 就能稳定压回去，且不影响任何布局尺寸。 */
  position: relative;
  z-index: 1;
}
.pra-back-btn:hover {
  border-color: var(--border-hover);
  background: var(--bg-hover);
  color: var(--text-primary);
}
.pra-back-btn:active { background: var(--bg-active); }
.pra-back-btn svg { width: 17px; height: 17px; }

.pra-title {
  min-width: 0;
  margin: 0;
  color: var(--text-primary);
  font-size: 1.18rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}
/* 页头里的副标题/计数行。允许被前端写成 <p> 或 <span>。 */
.pra-header .pra-meta { margin-top: 3px; }
.pra-header-tools {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* ============================================================
   2. 裸文字：说明、元信息
   ------------------------------------------------------------
   ⚠ 这两个类会直接铺在页面上（不在卡片里），壁纸模式下必须有背衬 ——
     已登记进 wallpaper.css 的「零散小字的背衬」名单（两处 :is 都要在）。
   ============================================================ */

.pra-hint {
  margin: 0;
  color: var(--text-tertiary);
  font-size: 0.78rem;
  line-height: 1.65;
}
.pra-hint code {
  padding: 1px 5px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 0.92em;
}
.pra-hint strong { color: var(--text-secondary); font-weight: 600; }

.pra-meta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin: 0;
  color: var(--text-tertiary);
  font-size: 0.73rem;
  line-height: 1.6;
}
.pra-meta b { color: var(--text-secondary); font-weight: 600; font-variant-numeric: tabular-nums; }

/* ============================================================
   3. 知识点 → 单元 → 难度（用户要求的组织方式）
   ------------------------------------------------------------
   为什么是三层而不是一层平铺的题库列表：

   高中知识本来就是**按知识点分块**的（函数、立体几何、语法…），
   一个知识点下有多个**单元**（一份能一次练完的卷），
   每个单元里的题再按**难度**分档。

   界面必须照这个结构长，否则用户要在几十个平铺的单元里自己找
   「我刚才在练哪个知识点」。所以外层是**知识点折叠组**（默认只展开第一个），
   组内是单元行，难度用徽章直接标在行上 —— 一眼能看出「这个单元有没有我要的难度」。
   ============================================================ */

/* ---------- 3.1 知识点折叠组 ---------- */

.pra-topic-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pra-topic {
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--bg-secondary);
  overflow: hidden;
  transition: border-color var(--transition-fast);
}
.pra-topic.is-open {
  border-color: var(--border-hover);
}

/* 组标题：整条可点，用 button 重置成块级 */
.pra-topic-head {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-width: 0;
  padding: 11px 13px;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--transition-fast);
}
.pra-topic-head:hover { background: var(--bg-hover); }
.pra-topic-head:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* 展开指示箭头：靠 .is-open 旋转，不用额外 DOM */
.pra-topic-caret {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  color: var(--text-tertiary);
  transition: transform var(--transition-base), color var(--transition-base);
}
.pra-topic.is-open .pra-topic-caret {
  transform: rotate(90deg);
  color: var(--accent);
}

.pra-topic-name {
  flex: 0 1 auto;
  min-width: 0;
  color: var(--text-primary);
  font-size: 0.92rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* 组标题右侧的计数（单元数 / 题数）。裸文字，壁纸需背衬。 */
.pra-topic-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--text-tertiary);
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
}
.pra-topic-meta span + span::before {
  content: "·";
  margin-right: 6px;
  opacity: 0.6;
}

/* 组内容。
   ⚠⚠ **收起时必须 display:none**，不能用 max-height 过渡。
      内容高度取决于单元数量（1 个单元 60px，20 个单元 1200px），
      max-height 猜小了会**截断最后几个单元**（用户以为题库少了一半），
      猜大了收起时又会有几百 px 的空白过渡延迟 —— 看起来像卡住了。
      `display` 切换没有中间态，配合 .pra-topic.is-open 控制，行为确定。 */
.pra-topic-body { display: none; }
.pra-topic.is-open .pra-topic-body { display: block; }

/*
 * 知识点描述：在 body 里的第一行。
 * ⚠ 要给它**自己的内边距** —— `.pra-unit-list` 的内边距只在它自己身上，
 *   描述没有的话会顶到卡片左边框上（实机看起来像「跑到卡片外面了」）。
 */
.pra-topic-body > .pra-hint {
  margin: 0;
  padding: 0 12px 8px;
  font-size: 0.74rem;
  line-height: 1.55;
}

/* ---------- 3.2 单元行 ---------- */

.pra-unit-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  padding: 0 10px 10px;
  list-style: none;
}

.pra-unit {
  position: relative;
  min-width: 0;
}

/* 整行可点 */
.pra-unit-pick {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-left: 3px solid transparent;
  border-radius: var(--radius-lg);
  background: var(--bg-primary);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--transition-fast), background var(--transition-fast);
}
.pra-unit-pick:hover:not(:disabled) {
  border-color: var(--border-hover);
  background: var(--bg-tertiary);
}
.pra-unit-pick:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* 选中态：左侧色条（不用整块高亮，扫列表时更清楚） */
.pra-unit.is-active .pra-unit-pick {
  border-left-color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-light);
}

/* 坏单元：整行压暗 + 红色左边线，且禁用。
   ⚠ 只让**这一个单元**不可用，同一知识点下的其它单元照常 ——
      一个 JSON 写坏了不该让整个知识点消失。 */
.pra-unit.is-broken .pra-unit-pick {
  border-left-color: var(--danger);
  opacity: 0.72;
  cursor: not-allowed;
}
.pra-unit.is-broken .pra-unit-meta { color: var(--danger); }

/* 主体：名称 / 描述 / 元信息竖排 */
.pra-unit-main {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1 1 auto;
  min-width: 0;
}

.pra-unit-name {
  color: var(--text-primary);
  font-size: 0.88rem;
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* 描述：单行截断（单元行高度一致，扫起来才快） */
.pra-unit-desc {
  overflow: hidden;
  color: var(--text-secondary);
  font-size: 0.76rem;
  line-height: 1.5;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* 元信息行（题数 / 预计时长 / 来源）。裸文字，壁纸需背衬。 */
.pra-unit-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  color: var(--text-tertiary);
  font-size: 0.72rem;
  line-height: 1.5;
}
.pra-unit-meta span + span::before {
  content: "·";
  margin-right: 6px;
  opacity: 0.6;
}

/* 坏单元的错误信息：单独一行、红色 */
.pra-unit-error {
  color: var(--danger);
  font-size: 0.74rem;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

/* 右侧：难度徽章组 + 题数 */
.pra-unit-tail {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
  padding-left: 12px;
  border-left: 1px solid var(--border-light);
}

/* ---------- 3.3 难度徽章 ----------
   三档配色**一律走 Token**（--success / --warning / --danger），
   不写死色值 —— 深色主题与壁纸模式下这三组 Token 各自有适配值，
   写死的话切主题就会出现「绿底上的黑字看不见」。 */

.pra-diff-tags {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}

.pra-diff-tag {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 7px;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  font-size: 0.68rem;
  font-weight: 600;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.pra-diff-tag strong {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* 三档配色：底色用 -light 变体，文字与描边用主色。
   这样在深色主题下也是「深底 + 亮字」，不用为每档单独写 dark 覆盖。 */
.pra-diff-tag[data-diff="basic"] {
  border-color: var(--success);
  background: var(--success-light);
  color: var(--success);
}
.pra-diff-tag[data-diff="medium"] {
  border-color: var(--warning);
  background: var(--warning-light);
  color: var(--warning);
}
.pra-diff-tag[data-diff="hard"] {
  border-color: var(--danger);
  background: var(--danger-light);
  color: var(--danger);
}

/* 该档 0 题：置灰不可选。
   ⚠ 用 opacity + 去掉配色，而不是直接隐藏 —— 用户要知道「这个单元没有困难题」，
     隐藏了会让他以为「这个单元根本没分难度」。 */
.pra-diff-tag.is-empty {
  border-color: var(--border);
  background: transparent;
  color: var(--text-tertiary);
  opacity: 0.55;
}

/* ---------- 3.4 难度筛选（单选按钮组） ---------- */

.pra-diff-filter {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-tertiary);
}

.pra-diff-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 26px;
  padding: 3px 11px;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 0.76rem;
  font-weight: 550;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.pra-diff-btn:hover:not(:disabled):not(.is-empty) { color: var(--text-primary); }
.pra-diff-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* 选中态：底色跟该档的难度色走，让「我在练基础题」这件事一眼可见 */
.pra-diff-btn.is-active {
  background: var(--bg-secondary);
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
}
.pra-diff-btn.is-active[data-diff="basic"] { color: var(--success); }
.pra-diff-btn.is-active[data-diff="medium"] { color: var(--warning); }
.pra-diff-btn.is-active[data-diff="hard"] { color: var(--danger); }

/* 该档 0 题：禁用并置灰（选了也没题，不如直接不给选） */
.pra-diff-btn.is-empty,
.pra-diff-btn:disabled {
  color: var(--text-tertiary);
  opacity: 0.5;
  cursor: not-allowed;
}

/* ---------- 3.5 窄屏 ---------- */

/*
 * 窄屏：单元行折成**两段** —— 上面是名称/描述/徽章，下面单独一行放题数。
 *
 * ⚠ 原来的写法是 `.pra-unit-pick { flex-wrap: wrap }` + `.pra-unit-tail { width: 100% }`，
 *   结果 tail 被挤到第三行、只剩一个孤零零的「3 题」悬在左下角（实机 420px 截图可见），
 *   而且 `.pra-unit-tail` 里同时装着**徽章组**和题数时会被拆散。
 *   改成显式的两行 grid：主区占满第一行，tail 占满第二行且右对齐。
 */
@media (max-width: 720px) {
  .pra-unit-pick {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
    align-items: start;
  }
  .pra-unit-main { min-width: 0; }
  .pra-unit-tail {
    width: auto;
    justify-content: flex-end;
    padding-left: 0;
    padding-top: 7px;
    border-left: 0;
    border-top: 1px solid var(--border-light);
  }
  .pra-unit-desc { white-space: normal; }
  .pra-topic-meta { font-size: 0.68rem; }
}

/* ============================================================
   3b. 通用卡片（模型面板 / 题库区块外壳仍在用 .pra-card）
   ============================================================ */

.pra-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl);
  background: var(--bg-secondary);
  box-shadow: var(--shadow-card);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast),
    transform var(--transition-fast);
}
.pra-card:hover {
  border-color: var(--border-hover);
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-1px);
}
/* 卡片本身可点（button 语义）时重置原生按钮样式 */
button.pra-card {
  width: 100%;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
button.pra-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ============================================================
   4. 按钮
   ------------------------------------------------------------
   不复用全站 .btn：刷题页的按钮密度更高（工具栏/卡片脚/总结页三处都有），
   独立一套便于按场景调高度。视觉语言与 .btn 保持一致（同样的圆角/描边/
   过渡），避免「一块新皮肤」的观感。
   ============================================================ */

.pra-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 34px;
  padding: 7px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-secondary);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.83rem;
  font-weight: 550;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    color var(--transition-fast), opacity var(--transition-fast);
}
.pra-btn:hover:not(:disabled) {
  border-color: var(--border-hover);
  background: var(--bg-hover);
}
.pra-btn:active:not(:disabled) { background: var(--bg-active); }
.pra-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pra-btn:disabled,
.pra-btn[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.42;
}
.pra-btn svg { width: 15px; height: 15px; flex: 0 0 auto; }

/* 实底主按钮：⚠ 用 --accent-fill（深色主题下 --accent 当底色白字只有 2.4:1） */
.pra-btn-primary {
  border-color: transparent;
  background: var(--accent-fill, var(--accent));
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), var(--shadow-sm);
}
.pra-btn-primary:hover:not(:disabled) {
  border-color: transparent;
  background: var(--accent-fill-hover, var(--accent-hover));
}
.pra-btn-primary:active:not(:disabled) {
  background: var(--accent-fill-active, var(--accent-dark));
}

/* 危险操作（删除错题 / 清空手写）：实底红，但默认比主按钮矮一档存在感 */
.pra-btn-danger {
  border-color: color-mix(in srgb, var(--danger) 40%, var(--border));
  background: var(--danger-light);
  color: var(--danger);
}
.pra-btn-danger:hover:not(:disabled) {
  border-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 16%, var(--bg-secondary));
  color: var(--danger);
}

/* 幽灵按钮：透明底、只留描边。用于次要动作（返回 / 取消 / 再来一组） */
.pra-btn-ghost {
  border-color: var(--border);
  background: transparent;
  color: var(--text-secondary);
}
.pra-btn-ghost:hover:not(:disabled) {
  border-color: var(--border-hover);
  background: var(--bg-hover);
  color: var(--text-primary);
}

/* 工具条容器（工作台的开始配置行 / 错题本的筛选行）。
   前端会写成 `class="pra-card pra-toolbar"`，所以这里只补横排与换行，
   卡片外观交给 .pra-card —— 两条规则叠加，不互相覆盖。 */
.pra-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.pra-toolbar > .pra-field { flex: 1 1 130px; }
.pra-toolbar > .pra-btn { flex: 0 0 auto; }

/* 小号：工具栏、列表项里的内联操作 */
.pra-btn-sm { min-height: 28px; padding: 4px 10px; font-size: 0.76rem; border-radius: var(--radius-md); }
.pra-btn-sm svg { width: 13px; height: 13px; }
.pra-btn-block { width: 100%; }

/* ============================================================
   5. 表单控件
   ============================================================ */

.pra-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.pra-field > label,
.pra-field-label {
  color: var(--text-secondary);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.pra-field-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* ⚠ 选择器要压过 refine.css 的 `select`（0,0,1）与 `input[type="text"]`（0,1,1）：
   用 .pra-field 前缀（0,2,0 / 0,2,1）而不是只写 .pra-select —— 通用规则在
   refine.css 里、本文件在它之后，单类也能赢，但 `input[type=...]` 的
   属性选择器权重更高，双类才稳妥。 */
.pra-field .pra-select,
.pra-select {
  min-height: 34px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-secondary);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.83rem;
  cursor: pointer;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.pra-field .pra-select:hover,
.pra-select:hover { border-color: var(--border-hover); }
.pra-field .pra-select:focus,
.pra-select:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: var(--focus-ring);
}

.pra-field .pra-input,
.pra-input {
  width: 100%;
  min-height: 34px;
  padding: 7px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-secondary);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.84rem;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.pra-field .pra-input::placeholder,
.pra-input::placeholder { color: var(--text-tertiary); }
.pra-field .pra-input:focus,
.pra-input:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: var(--focus-ring);
}
.pra-input[type="number"] { font-variant-numeric: tabular-nums; }

/* ============================================================
   6. 空状态
   ============================================================ */

.pra-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 44px 24px;
  border: 1px dashed var(--border-hover);
  border-radius: var(--radius-2xl);
  background: color-mix(in srgb, var(--bg-tertiary) 60%, transparent);
  text-align: center;
}
.pra-empty-icon {
  display: flex;
  width: 46px;
  height: 46px;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background: var(--accent-light);
  color: var(--accent);
}
.pra-empty-icon svg { width: 22px; height: 22px; }
.pra-empty h3 {
  margin: 0;
  color: var(--text-primary);
  font-size: 1rem;
  font-weight: 650;
}
.pra-empty p { max-width: 56ch; margin: 0; color: var(--text-tertiary); font-size: 0.82rem; line-height: 1.7; }
.pra-empty-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 4px; }
.pra-empty pre,
.pra-empty code {
  max-width: 100%;
  text-align: left;
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 0.74rem;
  overflow-x: auto;
}
/* 契约里的「查看导入格式」按钮弹出的 schema 文本。
   ⚠ 前端用的是 `.pra-schema-box`（一个 <pre> 容器）；`.pra-schema` 是同一件
      东西的别名，两个都认，避免为了一个类名再改一次 DOM。 */
.pra-schema-box,
.pra-empty .pra-schema {
  width: 100%;
  max-width: 720px;
  max-height: 320px;
  margin: 0;
  padding: 12px 14px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--code-bg);
  color: var(--code-text);
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 0.72rem;
  line-height: 1.55;
  text-align: left;
  white-space: pre;
}

/* ============================================================
   7. 工作台
   ============================================================ */

.pra-workbench {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 340px);
  gap: 18px;
  align-items: start;
}
.pra-workbench-main { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.pra-workbench-side { display: flex; flex-direction: column; gap: 12px; min-width: 0; }

.pra-panel {
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl);
  background: var(--bg-secondary);
  box-shadow: var(--shadow-card);
}
.pra-panel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.pra-panel-head h2 {
  margin: 0;
  color: var(--text-primary);
  font-size: 0.98rem;
  font-weight: 650;
  letter-spacing: -0.01em;
}
.pra-panel-head p { margin: 4px 0 0; color: var(--text-tertiary); font-size: 0.75rem; line-height: 1.6; }

/* ---------- 模型设置面板 ---------- */

.pra-model-panel { display: flex; flex-direction: column; gap: 10px; }
/* 面板头：标题在左、状态徽章在右。与 .pra-panel-head 同构，只是字号小一档
   （模型面板住在侧栏里，标题不该和主栏的 .pra-panel-head 一样大）。 */
.pra-model-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.pra-model-head h2,
.pra-model-head h3 {
  margin: 0;
  color: var(--text-primary);
  font-size: 0.96rem;
  font-weight: 650;
  letter-spacing: -0.01em;
}
.pra-model-head p { margin: 4px 0 0; color: var(--text-tertiary); font-size: 0.74rem; line-height: 1.6; }
.pra-model-head .pra-model-badge { flex: 0 0 auto; }

.pra-model-form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
/* API Key / Base URL 这类长字段独占整行 */
.pra-model-form .pra-field--wide { grid-column: 1 / -1; }
.pra-model-form-actions,
.pra-model-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  grid-column: 1 / -1;
}

/* 模型状态徽章：is-ok 绿 / is-warn 琥珀（无配置或测试失败） */
.pra-model-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--bg-tertiary);
  color: var(--text-tertiary);
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
}
.pra-model-badge::before {
  content: "";
  width: 6px;
  height: 6px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: currentColor;
}
.pra-model-badge.is-ok {
  border-color: var(--pra-ok-line);
  background: var(--pra-ok-soft);
  color: var(--success);
}
.pra-model-badge.is-warn {
  border-color: var(--pra-warn-line);
  background: var(--pra-warn-soft);
  color: var(--warning);
}

/* 模型连通性测试结果（ttft / 吞吐 / tokens） */
.pra-model-test {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  min-height: 20px;
  margin: 0;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-primary);
  color: var(--text-tertiary);
  font-size: 0.73rem;
  line-height: 1.6;
}
.pra-model-test b { color: var(--text-primary); font-weight: 600; font-variant-numeric: tabular-nums; }
.pra-model-test.is-ok {
  border-color: var(--pra-ok-line);
  background: var(--pra-ok-soft);
  color: var(--success);
}
.pra-model-test.is-warn {
  border-color: var(--pra-warn-line);
  background: var(--pra-warn-soft);
  color: var(--warning);
}
/* 空内容时（还没测过）不占高度：避免侧栏出现一条空盒子 */
.pra-model-test:empty { display: none; }

/* ---------- 统计行 ---------- */

.pra-stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(92px, 1fr));
  gap: 9px;
}
.pra-stat {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-primary);
}
.pra-stat strong {
  color: var(--text-primary);
  font-size: 1.18rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.pra-stat span { color: var(--text-tertiary); font-size: 0.7rem; line-height: 1.4; }
/* 语义化统计格：与判分三态同一套色 */
.pra-stat.is-ok strong { color: var(--success); }
.pra-stat.is-warn strong { color: var(--warning); }
.pra-stat.is-danger strong { color: var(--danger); }

/* 开始配置区（题数 / 时长 / 顺序） */
.pra-start-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
  align-items: end;
}
/*
 * ⚠ 难度筛选**不在** `.pra-start-form` 的 grid 里，它是 `.pra-field` 的直接内容、
 *   由 `.pra-panel` 这一层承载（前端把整块移出了 grid）。
 *
 * 为什么不能放进去：这张 grid 是 `repeat(auto-fit, minmax(120px, 1fr))`，
 * 1440px 下每列只有 ~177px，而四个难度按钮实测需要 **227px** ——
 * 放进去会横向溢出、压住右边的「题数」下拉框（实机截图确认过）。
 *
 * ⚠ 也**不要**试图用 `.pra-field--wide { grid-column: 1/-1 }` 救它：
 *   那条规则只对 `.pra-model-form` 有意义（那个表单的列宽是固定两列）。
 *   这里真正的修法是「别放进 grid」，不是「放进 grid 再跨列」。
 */
.pra-diff-filter { flex-wrap: wrap; }

/* 只读字段（时长）：长得像输入框，但**不是控件** —— 用户不能改。
   ⚠ 视觉上必须和下拉框区分开：给它虚线边框 + 更淡的背景，
   否则用户会去点它、发现点不动，以为界面坏了。
   时长由题库按每道题的建议用时自动算出（用户要求：不做预设）。 */
.pra-field-readonly .pra-duration-readout {
  display: flex;
  align-items: baseline;
  gap: 6px;
  min-height: 38px;
  padding: 7px 11px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-tertiary);
  cursor: default;
}
.pra-duration-readout strong {
  color: var(--text-primary);
  font-size: 0.86rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.pra-duration-readout .pra-hint {
  font-size: 0.68rem;
  white-space: nowrap;
}
.pra-start-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border-light);
}

/* ============================================================
   8. 答题屏
   ============================================================ */

.pra-session {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--pra-side);
  gap: 16px;
  align-items: start;
}
/* 跨两列的元素（页头、总结、底部操作、以及任何"整宽"的容器） */
.pra-session-head,
.pra-session-foot,
.pra-summary,
.pra-session > .pra-empty,
.pra-session > .pra-header,
.pra-session > .pra-toolbar,
.pra-session > .pra-panel,
.pra-session > .pra-hint,
.pra-session > .pra-meta { grid-column: 1 / -1; }

/* 左列：题目 */
.pra-session > .pra-question { grid-column: 1; }
/* 右列：作答 + 流面板 + 结果 + 提交 */
.pra-session > .pra-answer,
.pra-session > .pra-stream-panel,
.pra-session > .pra-grade-result,
.pra-session > .pra-submit-row,
.pra-session > .pra-countdown,
.pra-session > .pra-progress-bar,
.pra-session > .pra-session-tools { grid-column: 2; }

/* 前端选择自己包一层时：包装层跨两列，内部重复同一套两列规则 */
.pra-session-body {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: minmax(0, 1fr) var(--pra-side);
  gap: 16px;
  align-items: start;
}
.pra-session-body > .pra-question { grid-column: 1; }
.pra-session-body > .pra-answer,
.pra-session-body > .pra-stream-panel,
.pra-session-body > .pra-grade-result,
.pra-session-body > .pra-submit-row,
.pra-session-body > .pra-countdown,
.pra-session-body > .pra-progress-bar { grid-column: 2; }
.pra-session-body > .pra-session-foot,
.pra-session-body > .pra-summary { grid-column: 1 / -1; }

/* ---------- 答题屏头部：倒计时 + 进度 ---------- */

.pra-session-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border-light);
}
.pra-session-head-main { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; min-width: 0; }
.pra-session-head-main h2,
.pra-session-head h2 {
  margin: 0;
  color: var(--text-primary);
  font-size: 1.02rem;
  font-weight: 650;
  letter-spacing: -0.01em;
}
.pra-session-tools { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

/* 倒计时：等宽数字 + 三档状态。
   ⚠ 用 font-variant-numeric 而不是等宽字体：中文界面里等宽字体会把
     「剩余 12:34」的中文部分也换成 mono，很难看。 */
.pra-countdown {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--bg-secondary);
  color: var(--text-primary);
  font-size: 0.92rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  white-space: nowrap;
  transition: color var(--transition-fast), border-color var(--transition-fast),
    background var(--transition-fast);
}
.pra-countdown svg { width: 14px; height: 14px; }
/* 只剩 60 秒：琥珀 */
.pra-countdown.is-warn {
  border-color: var(--pra-warn-line);
  background: var(--pra-warn-soft);
  color: var(--warning);
}
/* 到点/最后 10 秒：红色 + 脉冲（toast 同款动效节奏） */
.pra-countdown.is-danger {
  border-color: var(--pra-bad-line);
  background: var(--pra-bad-soft);
  color: var(--danger);
  animation: praCountdownPulse 1.1s ease-in-out infinite;
}
@keyframes praCountdownPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.62; }
}

/* 进度条：与 .emm-gen-bar 同一套观感（细、胶囊、--accent-fill）
   ⚠ 壁纸模式下这条是**压在照片上**的裸元素（页头是透明容器），5px 的细条
     直接对着亮部就没了。实测（1440px + 壁纸开）像素对比度：
       轨道 vs 背景 **1.16:1**、蓝色填充 vs 背景 **1.53:1**
     —— 两者都远低于 WCAG 非文本 3:1。注意**填充也只有 1.53**，
     所以"只把轨道调深一点"是不够的，整条都得有背衬。
     修法沿用本项目既有做法（见 wallpaper.css 的「零散小字的背衬」）：
     给 `.pra-progress-row` 垫一层 `--wp-text-backing`（实测下限 94%），
     进度条与 `1 / 4` 计数一起读得清。只加背景，不动尺寸/间距。 */
.pra-progress-bar {
  position: relative;
  display: block;
  width: 100%;
  height: 5px;
  overflow: hidden;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--text-tertiary) 20%, transparent);
}
.pra-progress-fill {
  display: block;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--accent-fill, var(--accent));
  transition: width 240ms ease;
}
/* 进度文字（"3 / 10"）挂在条右边：条本身不承载文字 */
.pra-progress-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.pra-progress-row > .pra-progress-bar { flex: 1 1 auto; min-width: 60px; }

/* ⚠ `.pra-session-head` 是 `display:flex; justify-content:space-between; flex-wrap:wrap`
   的三段头（标题 / 倒计时工具 / 进度行）。进度行若保持 `flex: 0 1 auto`，
   它会和另外两段挤在**同一行最右**，`.pra-progress-bar` 只剩 `min-width:60px`
   —— 实测 1440px 下整行 94px、条 60px、填充 15px（25%），界面上就是
   「一小截蓝色胶囊」，完全看不出进度。
   所以让进度行**独占一整行**：`flex-basis:100%` 会把它挤到下一行并铺满宽度。
   （窄屏 <=960px 折成一列时，已有的 `order: -2` 会让它排在标题下面、题目上面。） */
.pra-session-head > .pra-progress-row { flex: 1 1 100%; }
/* 若前端把进度行放在 `.pra-session` 的直接子元素上（而不是头部里），
   它也要跨两列 —— 与 `.pra-progress-bar` 的既有规则保持一致。 */
.pra-session > .pra-progress-row,
.pra-session-body > .pra-progress-row { grid-column: 1 / -1; }
.pra-progress-label {
  flex: 0 0 auto;
  color: var(--text-tertiary);
  font-size: 0.73rem;
  font-variant-numeric: tabular-nums;
}

/* ---------- 题目 ---------- */

.pra-question {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  padding: 18px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl);
  background: var(--bg-secondary);
  box-shadow: var(--shadow-card);
}

.pra-question-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border-light);
}
.pra-question-type,
.pra-question-score {
  display: inline-flex;
  align-items: center;
  padding: 2px 9px;
  border-radius: var(--radius-full);
  font-size: 0.71rem;
  font-weight: 600;
  white-space: nowrap;
}
.pra-question-type {
  border: 1px solid var(--border);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
}
.pra-question-score {
  margin-left: auto;
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
  background: var(--accent-light);
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* 题目难度徽章（答题屏题头）。
   复用 `.pra-diff-tag` 的三档配色（basic→--success / medium→--warning / hard→--danger），
   但**不是** `.pra-diff-tag` 本身：题头这一枚要更醒目一点（用户答题时要能确认
   「我现在做的是困难题」），所以字号与内边距略大。
   ⚠ 配色规则必须与 `.pra-diff-tag` 保持一致 —— 同一档在两处颜色不同会让人以为
     是两个不同的东西。 */
.pra-question-diff {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  font-size: 0.71rem;
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
}
.pra-question-diff[data-diff="basic"] {
  border-color: var(--success);
  background: var(--success-light);
  color: var(--success);
}
.pra-question-diff[data-diff="medium"] {
  border-color: var(--warning);
  background: var(--warning-light);
  color: var(--warning);
}
.pra-question-diff[data-diff="hard"] {
  border-color: var(--danger);
  background: var(--danger-light);
  color: var(--danger);
}

/* 题干：Markdown + KaTeX 渲染产物。行宽上限按可读性定（~70ch）。 */
.pra-question-text {
  max-width: 72ch;
  color: var(--text-primary);
  font-size: 0.95rem;
  line-height: 1.85;
  overflow-wrap: anywhere;
}
.pra-question-text > :first-child { margin-top: 0; }
.pra-question-text > :last-child { margin-bottom: 0; }
.pra-question-text p { margin: 0 0 10px; }
.pra-question-text h1,
.pra-question-text h2,
.pra-question-text h3,
.pra-question-text h4 {
  margin: 14px 0 8px;
  font-size: 1rem;
  font-weight: 650;
  letter-spacing: -0.01em;
}
.pra-question-text ul,
.pra-question-text ol { margin: 0 0 10px; padding-left: 22px; }
.pra-question-text li { margin: 3px 0; }
.pra-question-text img { max-width: 100%; height: auto; border-radius: var(--radius-md); }
.pra-question-text table { margin: 10px 0; }
.pra-question-text blockquote {
  margin: 10px 0;
  padding: 6px 12px;
  border-left: 3px solid var(--border-hover);
  color: var(--text-secondary);
}
.pra-question-text code {
  padding: 1px 5px;
  border-radius: var(--radius-sm);
  background: var(--bg-tertiary);
  font-size: 0.9em;
}
.pra-question-text pre { margin: 10px 0; }
.pra-question-text .katex-display { margin: 10px 0; overflow-x: auto; overflow-y: hidden; }
.pra-question-text .katex { font-size: 1.02em; }

/* 选项（选择题）。用 ol 或 div 都可以，li/子项由 .pra-option 承担。 */
.pra-options {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.pra-option {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 8px 11px;
  border: 1px solid var(--border-light);
  border-radius: var(--radius-lg);
  background: var(--bg-primary);
  color: var(--text-primary);
  font-size: 0.88rem;
  line-height: 1.65;
}
.pra-option-label {
  flex: 0 0 auto;
  min-width: 20px;
  color: var(--accent);
  font-weight: 700;
}
.pra-option-text { min-width: 0; overflow-wrap: anywhere; }

/* 纯图片题：题目图点击放大（前端负责开大图窗），这里只管版式 */
.pra-question-image-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  padding: 6px;
  border: 1px solid var(--border-light);
  border-radius: var(--radius-lg);
  background: var(--bg-primary);
}
.pra-question-image {
  max-width: 100%;
  max-height: 60vh;
  border-radius: var(--radius-md);
  object-fit: contain;
  cursor: zoom-in;
}
.pra-question-image-wrap:focus-within {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* 标签（题目 tags） */
.pra-tags { display: flex; gap: 6px; flex-wrap: wrap; margin: 0; padding: 0; list-style: none; }
.pra-tag {
  padding: 1px 8px;
  border: 1px solid var(--border-light);
  border-radius: var(--radius-full);
  background: var(--bg-tertiary);
  color: var(--text-tertiary);
  font-size: 0.68rem;
  line-height: 1.6;
}

/* ---------- 作答区 ---------- */

.pra-answer {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl);
  background: var(--bg-secondary);
  box-shadow: var(--shadow-card);
}

/* ---------- 手写区 ---------- */

.pra-ink-wrap {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

/* 工具栏：图标按钮一行，当前工具高亮。
   ⚠ 允许换行：窄屏（右栏 320px）放不下 8 个工具 + 3 个小控件。 */
.pra-ink-toolbar {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  padding: 5px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-tertiary);
}
/* 工具条内的分隔（笔/橡皮 与 撤销/重做/清空 之间） */
.pra-ink-toolbar > hr,
.pra-ink-sep {
  width: 1px;
  height: 18px;
  flex: 0 0 auto;
  margin: 0 3px;
  border: 0;
  background: var(--border);
}

.pra-ink-tool {
  display: inline-flex;
  width: 30px;
  height: 30px;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast),
    border-color var(--transition-fast);
}
.pra-ink-tool svg { width: 16px; height: 16px; }
.pra-ink-tool:hover:not(:disabled) { background: var(--bg-hover); color: var(--text-primary); }
.pra-ink-tool:active:not(:disabled) { background: var(--bg-active); }
.pra-ink-tool:disabled { cursor: not-allowed; opacity: 0.36; }
.pra-ink-tool.is-active {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
  background: var(--accent-light);
  color: var(--accent);
}
.pra-ink-tool:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* 颜色 / 粗细：紧凑小控件（不是整宽 select） */
.pra-ink-color {
  width: 28px;
  height: 28px;
  flex: 0 0 auto;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-secondary);
  cursor: pointer;
}
.pra-ink-color::-webkit-color-swatch-wrapper { padding: 0; }
.pra-ink-color::-webkit-color-swatch { border: 0; border-radius: 3px; }
.pra-ink-color::-moz-color-swatch { border: 0; border-radius: 3px; }
.pra-ink-color:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* 粗细：range 输入压窄，只占 64px；滑轨用手写笔粗细的视觉暗示 */
.pra-ink-size {
  width: 64px;
  height: 28px;
  flex: 0 0 auto;
  margin: 0 2px;
  accent-color: var(--accent-fill, var(--accent));
  cursor: pointer;
}
.pra-ink-size:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 背景选择（空白 / 横线 / 方格）：紧凑 select */
.pra-ink-bg {
  height: 28px;
  flex: 0 0 auto;
  padding: 0 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-secondary);
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 0.72rem;
  cursor: pointer;
}
.pra-ink-bg:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* 画布：DPR 由 JS 设内联 width/height（内联会赢），这里只兜底尺寸与触摸行为。
   ⚠ touch-action: none 是必需的 —— 否则触控笔/手指一划就滚动页面，
     画不出线（这是移动端手写区最常踩的坑）。
   ⚠ display: block 也必需：inline canvas 底部会多出 ~4px 基线间隙，
     与外面的边框对不齐。 */
.pra-ink-canvas {
  display: block;
  /* ⚠ 宽高由 JS 写内联值（纸张尺寸 × 缩放 × DPR），这里**不要**再给
     width/height —— 否则会跟内联值打架，表现为「画布尺寸跳来跳去」。 */
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--pra-ink-paper, var(--bg-primary));
  touch-action: none;
  cursor: crosshair;
  /* 笔迹要清晰：不要给画布加 opacity/滤镜 */
}
.pra-ink-canvas:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- 画布舞台 ----------
   缩放 > 100% 时画布比容器宽/高，靠这层滚动而不是撑破布局。
   ⚠ 必须 `overflow: auto` + `min-height: 0`：在 flex 列里不写 min-height:0，
     子元素会把父级撑高、滚动条永远不出现（这是 flex 的经典坑）。 */
.pra-ink-stage {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  min-width: 0;
  min-height: 0;
  overflow: auto;
  /* 缩放后画布可能很大，滚动时不要出现「橡皮筋」抖动 */
  overscroll-behavior: contain;
  border-radius: var(--radius-lg);
}
/* 缩放 > 100% 时给一点内边距，画布边缘不贴着滚动条 */
.pra-ink-stage > .pra-ink-canvas { flex: 0 0 auto; }

/* 背景格线的 CSS 兜底（引擎若自己画在 canvas 上，这两条不生效也无妨 ——
   CSS 背景不会被 toDataURL 捕获，所以导出 PNG 的格线必须由引擎画）。 */
.pra-ink-wrap.is-lined .pra-ink-canvas,
.pra-ink-wrap[data-ink-bg="lined"] .pra-ink-canvas {
  background-image: repeating-linear-gradient(
    180deg,
    transparent 0,
    transparent 31px,
    color-mix(in srgb, var(--border) 85%, transparent) 31px,
    color-mix(in srgb, var(--border) 85%, transparent) 32px
  );
}
.pra-ink-wrap.is-grid .pra-ink-canvas,
.pra-ink-wrap[data-ink-bg="grid"] .pra-ink-canvas {
  background-image:
    repeating-linear-gradient(
      180deg,
      transparent 0,
      transparent 31px,
      color-mix(in srgb, var(--border) 75%, transparent) 31px,
      color-mix(in srgb, var(--border) 75%, transparent) 32px
    ),
    repeating-linear-gradient(
      90deg,
      transparent 0,
      transparent 31px,
      color-mix(in srgb, var(--border) 75%, transparent) 31px,
      color-mix(in srgb, var(--border) 75%, transparent) 32px
    );
}

/* 手写区底部的说明/状态（"笔迹会自动随作答提交"） */
.pra-ink-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  color: var(--text-tertiary);
  font-size: 0.71rem;
}

/* ---------- 缩放控件 ----------
   形态是「− 100% +」一个整体，百分比本身就是「回到 100%」按钮。 */
.pra-ink-zoom {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-tertiary);
}
.pra-ink-zoom .pra-ink-zoom-btn {
  width: 24px;
  min-width: 24px;
  height: 24px;
  min-height: 24px;
  padding: 0;
  border: 0;
  background: transparent;
}
.pra-ink-zoom-btn svg { width: 13px; height: 13px; }
.pra-ink-zoom-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.pra-ink-zoom-label {
  min-width: 44px;
  padding: 2px 4px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 0.7rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.pra-ink-zoom-label:hover { background: var(--bg-secondary); color: var(--text-primary); }
.pra-ink-zoom-label:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* 全屏按钮：靠右推到工具栏末端，且与普通工具用不同底色（它是「视图」不是「工具」） */
.pra-ink-fullscreen-btn { margin-left: auto; }
.pra-ink-fullscreen-btn.is-active {
  border-color: var(--accent);
  background: var(--accent-light);
  color: var(--accent);
}

/* ---------- 全屏手写（「铺满窗口」，不是浏览器原生全屏） ----------
   ⚠ 为什么不用 requestFullscreen：原生全屏会隐掉地址栏，用户容易不知道怎么退出，
     而且会和「Esc 回工作台」的键位打架。这里用固定定位铺满视口，视觉等价、
     退出语义清晰（Esc 先退全屏，再按才回工作台）。 */
.pra-answer.is-ink-fullscreen {
  position: fixed;
  inset: 0;
  z-index: 900;
  display: flex;
  flex-direction: column;
  padding: 10px 12px 8px;
  border: 0;
  border-radius: 0;
  background: var(--bg-primary);
  box-shadow: none;
}
.pra-answer.is-ink-fullscreen .pra-ink-wrap {
  flex: 1 1 auto;
  min-height: 0;
  height: 100%;
}
.pra-answer.is-ink-fullscreen .pra-ink-stage {
  flex: 1 1 auto;
  min-height: 0;
}
/* 全屏时纸张宽度固定（不跟着窗口拉伸，否则笔迹会被横向拉变形），居中显示 */
.pra-answer.is-ink-fullscreen .pra-ink-stage > .pra-ink-canvas {
  margin: 0 auto;
  box-shadow: var(--shadow-card);
}
/* 全屏时底部说明可以让位给画布 */
.pra-answer.is-ink-fullscreen .pra-ink-foot { flex: 0 0 auto; }

/* 全屏时工具栏加大：离得远、手在动，小图标点不准 */
.pra-answer.is-ink-fullscreen .pra-ink-toolbar {
  padding: 8px 10px;
  gap: 6px;
  flex: 0 0 auto;
}
.pra-answer.is-ink-fullscreen .pra-ink-tool {
  width: 34px;
  min-width: 34px;
  height: 34px;
  min-height: 34px;
}
.pra-answer.is-ink-fullscreen .pra-ink-tool svg { width: 19px; height: 19px; }
.pra-answer.is-ink-fullscreen .pra-ink-color { width: 34px; height: 30px; }
.pra-answer.is-ink-fullscreen .pra-ink-size { width: 130px; }
.pra-answer.is-ink-fullscreen .pra-ink-bg { min-height: 30px; font-size: 0.78rem; }
.pra-answer.is-ink-fullscreen .pra-ink-zoom-label { min-width: 52px; font-size: 0.76rem; }
.pra-answer.is-ink-fullscreen .pra-ink-zoom-btn { width: 30px; min-width: 30px; height: 30px; min-height: 30px; }
.pra-answer.is-ink-fullscreen .pra-ink-zoom-btn svg { width: 16px; height: 16px; }

/* 全屏时锁住页面滚动，避免背景跟着画布一起滚 */
body.pra-ink-fullscreen-lock { overflow: hidden; }

/* ---------- 全屏时的题干浮层（用户要求「保留可折叠题干」） ----------
   ⚠ 用**浮层**而不是固定侧栏：固定侧栏会永久吃掉画布宽度，而写长解答最缺宽度。
     浮层默认展开、可收起，收起后画布吃满整宽。
   ⚠ `pointer-events` 只开在浮层自身，否则它下面那片区域写不了字。
   ⚠⚠ `top` 必须**避开工具栏**：工具栏在全屏时高约 50~54px，浮层从 8px 开始会
     直接盖住右边的全屏/加页按钮（实测 1440px 与 900px 都盖住了）。
     这里用 `top: calc(100% ...)` 不现实（浮层在 wrap 内），所以直接给足偏移。 */
.pra-stem-peek {
  position: absolute;
  top: 60px;
  right: 8px;
  z-index: 5;
  width: min(360px, 42vw);
  max-height: calc(46% - 40px);
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--bg-secondary) 96%, transparent);
  box-shadow: var(--shadow-card-hover);
  overflow: hidden;
  pointer-events: auto;
}
.pra-stem-peek-head {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 6px 10px;
  border: 0;
  border-bottom: 1px solid var(--border-light);
  background: transparent;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 0.74rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.pra-stem-peek-head:hover { background: var(--bg-hover); }
.pra-stem-peek-caret {
  width: 0;
  height: 0;
  flex: 0 0 auto;
  border-left: 4px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform var(--transition-fast);
}
.pra-stem-peek.is-open .pra-stem-peek-caret { transform: rotate(90deg); }
.pra-stem-peek-hint { margin-left: auto; color: var(--text-tertiary); font-weight: 400; font-size: 0.68rem; }
.pra-stem-peek-body {
  padding: 8px 10px 10px;
  overflow: auto;
  overscroll-behavior: contain;
  color: var(--text-primary);
  font-size: 0.78rem;
  line-height: 1.65;
}
.pra-stem-peek:not(.is-open) .pra-stem-peek-body { display: none; }
.pra-stem-peek-image {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
}
.pra-stem-peek-text :is(p, ul, ol) { margin: 0 0 6px; }
.pra-stem-peek-text :is(p, ul, ol):last-child { margin-bottom: 0; }

/* 全屏时浮层与画布的关系：`.pra-ink-wrap` 要 `position: relative` 才能定位浮层 */
.pra-answer.is-ink-fullscreen .pra-ink-wrap { position: relative; }

/* 窄屏：浮层不能盖住工具栏，改为「不悬浮」—— 进正常文档流、把画布往下推。
   ⚠ 窄屏下工具栏本身要换行占好几行，浮层再用 absolute 压在顶部，
     会直接盖住工具按钮（实测 420px 全屏截图里工具栏被整个遮住）。 */
@media (max-width: 720px) {
  .pra-stem-peek {
    position: static;
    width: auto;
    max-height: 34%;
    margin: 0 0 6px;
    flex: 0 0 auto;
  }
  .pra-answer.is-ink-fullscreen { padding: 8px 8px 6px; }
  /* 窄屏全屏时工具栏可以横向滚动，避免挤成三行把画布压没 */
  .pra-answer.is-ink-fullscreen .pra-ink-toolbar {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
  }
  .pra-answer.is-ink-fullscreen .pra-ink-fullscreen-btn { margin-left: 0; }
}

/* ---------- 提交行 ---------- */

.pra-submit-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.pra-submit-row .pra-btn-primary { flex: 1 1 auto; }
.pra-submit-row .pra-hint { flex: 1 1 100%; }
/* 提交中的转圈：放在按钮里的 .pra-spinner */
.pra-spinner {
  display: inline-block;
  width: 13px;
  height: 13px;
  flex: 0 0 auto;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: praSpin 640ms linear infinite;
}
@keyframes praSpin { to { transform: rotate(360deg); } }

/* ============================================================
   9. 实时流面板（批改 SSE）
   ------------------------------------------------------------
   双通道：思考（.is-think，弱化色斜体）与正文（主色）。
   两个 <pre> 都限高可滚；自动滚底由 JS 负责（scrollTop = scrollHeight）。
   ============================================================ */

.pra-stream-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl);
  background: color-mix(in srgb, var(--accent) 4%, var(--bg-secondary));
  box-shadow: var(--shadow-card);
}
.pra-stream-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.pra-stream-head h3,
.pra-stream-head strong {
  margin: 0;
  color: var(--text-primary);
  font-size: 0.85rem;
  font-weight: 650;
}
/* 实时状态点：正在流式输出时闪烁 */
.pra-stream-dot {
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--accent);
  animation: praStreamPulse 1.2s ease-in-out infinite;
}
@keyframes praStreamPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.82); }
}
/* 流结束（done / error）后停掉闪烁 */
.pra-stream-panel.is-done .pra-stream-dot,
.pra-stream-panel.is-error .pra-stream-dot { animation: none; opacity: 0.5; }
.pra-stream-panel.is-error { border-color: var(--pra-bad-line); }

/* 指标卡：复用 .emm-gen-stats 的排版（auto-fit 格子 + 等宽数字） */
.pra-stream-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(78px, 1fr));
  gap: 6px;
}
.pra-stream-metric {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-primary);
}
.pra-stream-metric strong {
  color: var(--text-primary);
  font-size: 0.9rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
.pra-stream-metric span { color: var(--text-tertiary); font-size: 0.66rem; line-height: 1.35; }
/* 速度/首字延迟这类"跑起来才有意义"的指标：有值后转主色 */
.pra-stream-metric.is-live strong { color: var(--accent); }

/* 双通道容器 */
.pra-stream-panes {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.pra-stream-pane {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.pra-stream-pane-label {
  color: var(--text-tertiary);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.06em;
}

/* ⚠ 等宽字体 + pre-wrap：模型输出里的缩进/公式排版要保住，
   但长行必须折行（否则面板会横向滚）。
   max-height 是必需的：不封顶时流式输出会把下面的结果卡顶到屏幕外。 */
.pra-stream-out {
  margin: 0;
  padding: 9px 11px;
  max-height: 210px;
  overflow-y: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: ui-monospace, "Cascadia Mono", "SF Mono", Consolas, "Courier New", monospace;
  font-size: 0.73rem;
  line-height: 1.62;
  white-space: pre-wrap;
  word-break: break-word;
  overflow-wrap: anywhere;
}
/* 思考通道压暗：它是草稿，不该和正文抢注意力 */
.pra-stream-pane.is-think .pra-stream-out {
  color: var(--text-tertiary);
  font-style: italic;
  background: color-mix(in srgb, var(--bg-tertiary) 70%, var(--bg-primary));
}
/* 正文通道：用主色 + 略大的字号，是"真正的答案" */
.pra-stream-pane:not(.is-think) .pra-stream-out {
  color: var(--text-primary);
  font-size: 0.75rem;
}
/* 空面板（还没收到 delta）显示占位：用 :empty 让前端不必额外插节点 */
.pra-stream-out:empty::before {
  content: attr(data-placeholder);
  color: var(--text-tertiary);
  font-style: normal;
}
.pra-stream-panel .pra-stream-out:empty::before { content: "等待模型输出…"; }

/* ============================================================
   10. 批改结果
   ------------------------------------------------------------
   三态：correct 绿 / partial 琥珀 / wrong 红。
   做法是「左边线 + 淡底 + 分数徽章同色」，不换整个卡片的底色 ——
   整块染色会让下面的错点列表读起来很累。
   ============================================================ */

.pra-grade-result {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-tertiary);
  border-radius: var(--radius-2xl);
  background: var(--bg-secondary);
  box-shadow: var(--shadow-card);
}
.pra-grade-result.is-correct {
  border-left-color: var(--success);
  border-color: var(--pra-ok-line);
  background: color-mix(in srgb, var(--success) 4%, var(--bg-secondary));
}
.pra-grade-result.is-partial {
  border-left-color: var(--warning);
  border-color: var(--pra-warn-line);
  background: color-mix(in srgb, var(--warning) 4%, var(--bg-secondary));
}
.pra-grade-result.is-wrong {
  border-left-color: var(--danger);
  border-color: var(--pra-bad-line);
  background: color-mix(in srgb, var(--danger) 4%, var(--bg-secondary));
}

.pra-grade-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
/* 已加入错题本的提示 */
.pra-grade-wrongbook {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: auto;
  color: var(--text-tertiary);
  font-size: 0.71rem;
}

/* 分数徽章：大号数字 + 满分。三态由父级 .pra-grade-result 的修饰类驱动，
   所以徽章自己不需要额外的 is-* 类（前端只切父级一个类）。 */
.pra-score-badge {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
  padding: 5px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  white-space: nowrap;
}
.pra-score-badge strong { font-size: 1.28rem; font-weight: 700; }
.pra-score-badge span,
.pra-score-badge small { color: var(--text-tertiary); font-size: 0.74rem; font-weight: 500; }
.pra-grade-result.is-correct .pra-score-badge {
  border-color: var(--pra-ok-line);
  background: var(--pra-ok-soft);
  color: var(--success);
}
.pra-grade-result.is-partial .pra-score-badge {
  border-color: var(--pra-warn-line);
  background: var(--pra-warn-soft);
  color: var(--warning);
}
.pra-grade-result.is-wrong .pra-score-badge {
  border-color: var(--pra-bad-line);
  background: var(--pra-bad-soft);
  color: var(--danger);
}

/* verdict 文字标签（"正确 / 部分正确 / 错误"） */
.pra-verdict {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: var(--radius-full);
  font-size: 0.74rem;
  font-weight: 650;
  white-space: nowrap;
}
.pra-grade-result.is-correct .pra-verdict {
  background: var(--pra-ok-soft);
  color: var(--success-ink, var(--success));
}
.pra-grade-result.is-partial .pra-verdict {
  background: var(--pra-warn-soft);
  color: var(--warning-ink, var(--warning));
}
.pra-grade-result.is-wrong .pra-verdict {
  background: var(--pra-bad-soft);
  color: var(--danger-ink, var(--danger));
}

/* 一句话总评 */
.pra-summary {
  margin: 0;
  color: var(--text-primary);
  font-size: 0.87rem;
  line-height: 1.75;
  overflow-wrap: anywhere;
}
.pra-grade-result .pra-summary { font-weight: 500; }

/* 错点列表：每条「错在哪 / 为什么错 / 怎么改」三段 */
.pra-mistakes {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.pra-mistake {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 9px 12px;
  border: 1px solid var(--border-light);
  border-left: 2px solid var(--pra-bad-line);
  border-radius: var(--radius-md);
  background: var(--bg-primary);
}
.pra-mistake > strong,
.pra-mistake-point {
  color: var(--text-primary);
  font-size: 0.83rem;
  font-weight: 650;
  line-height: 1.55;
}
.pra-mistake > p,
.pra-mistake-detail,
.pra-mistake-fix {
  margin: 0;
  color: var(--text-secondary);
  font-size: 0.78rem;
  line-height: 1.7;
  overflow-wrap: anywhere;
}
.pra-mistake-fix { color: var(--success); }
.pra-mistake-fix::before {
  content: "改：";
  font-weight: 600;
  opacity: 0.85;
}

/* 模型给出的正确答案 / 下一步建议 */
.pra-model-answer,
.pra-advice {
  margin: 0;
  padding: 9px 12px;
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md);
  background: var(--bg-primary);
  color: var(--text-secondary);
  font-size: 0.81rem;
  line-height: 1.72;
  overflow-wrap: anywhere;
}
.pra-model-answer > strong,
.pra-advice > strong {
  display: block;
  margin-bottom: 3px;
  color: var(--text-tertiary);
  font-size: 0.69rem;
  font-weight: 650;
  letter-spacing: 0.04em;
}

/* 结果卡里的图（模型答案图 / 学生手写图） */
.pra-result-image {
  max-width: 100%;
  max-height: 40vh;
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md);
  object-fit: contain;
}

/* ============================================================
   11. 交卷总结
   ------------------------------------------------------------
   ⚠ `.pra-summary` 在契约里有两个身份：批改结果里的「一句话总评」（纯文本），
     和交卷总结的根容器。这里用 :has(.pra-summary-grid) 区分 ——
     含总结网格时自动变成卡片，否则保持纯文本。所以**交卷总结必须**
     写成 <div class="pra-summary"><div class="pra-summary-grid">…</div></div>。
   ============================================================ */

.pra-summary:has(.pra-summary-grid) {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 22px 24px;
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl);
  background: var(--bg-secondary);
  box-shadow: var(--shadow-card);
  text-align: center;
}
.pra-summary:has(.pra-summary-grid) > h2 {
  margin: 0;
  color: var(--text-primary);
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: -0.015em;
}
.pra-summary-score {
  margin: 0;
  color: var(--text-secondary);
  font-size: 0.86rem;
  font-variant-numeric: tabular-nums;
}
.pra-summary-score strong { color: var(--accent); font-size: 1.42rem; font-weight: 700; }

.pra-summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
  gap: 9px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.pra-summary-item {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 11px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-primary);
  text-align: center;
}
.pra-summary-item strong {
  color: var(--text-primary);
  font-size: 1.24rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.pra-summary-item span { color: var(--text-tertiary); font-size: 0.7rem; }
.pra-summary-item.is-correct strong { color: var(--success); }
.pra-summary-item.is-partial strong { color: var(--warning); }
.pra-summary-item.is-wrong strong { color: var(--danger); }

.pra-summary-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 4px;
}

/* 逐题结果小列表（交卷总结里的"每题得分"） */
.pra-summary-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: left;
}
.pra-summary-list li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md);
  background: var(--bg-primary);
  color: var(--text-secondary);
  font-size: 0.79rem;
}
.pra-summary-list li > span:first-child { color: var(--text-tertiary); font-variant-numeric: tabular-nums; }
.pra-summary-list li > strong { margin-left: auto; font-variant-numeric: tabular-nums; }
.pra-summary-list li.is-correct > strong { color: var(--success); }
.pra-summary-list li.is-partial > strong { color: var(--warning); }
.pra-summary-list li.is-wrong > strong { color: var(--danger); }

/* ============================================================
   12. 内置错题本
   ============================================================ */

.pra-wrongbook {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

/* 筛选行 */
.pra-wrong-filter {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--bg-secondary);
}
.pra-wrong-filter .pra-input { flex: 1 1 180px; width: auto; min-width: 140px; }

.pra-wrong-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.pra-wrong-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--danger);
  border-radius: var(--radius-xl);
  background: var(--bg-secondary);
  cursor: pointer;
  transition: border-color var(--transition-fast), background var(--transition-fast);
}
.pra-wrong-item:hover { border-color: var(--border-hover); background: var(--bg-hover); }
.pra-wrong-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 部分正确也是"有错才进"，用琥珀区分 */
.pra-wrong-item.is-partial { border-left-color: var(--warning); }
/* 已掌握：压暗 + 绿边 */
.pra-wrong-item.is-mastered {
  border-left-color: var(--success);
  opacity: 0.68;
}
.pra-wrong-item.is-mastered .pra-wrong-title { text-decoration: line-through; }

.pra-wrong-main { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1 1 auto; }
.pra-wrong-title {
  margin: 0;
  color: var(--text-primary);
  font-size: 0.86rem;
  font-weight: 600;
  line-height: 1.55;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.pra-wrong-sub { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; color: var(--text-tertiary); font-size: 0.71rem; }
.pra-wrong-actions { display: flex; align-items: center; gap: 5px; flex: 0 0 auto; }
/* 未掌握/已掌握徽章 */
.pra-wrong-status {
  flex: 0 0 auto;
  padding: 2px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--bg-tertiary);
  color: var(--text-tertiary);
  font-size: 0.68rem;
  white-space: nowrap;
}
.pra-wrong-status.is-mastered {
  border-color: var(--pra-ok-line);
  background: var(--pra-ok-soft);
  color: var(--success);
}

/* ---------- 详情大窗 ----------
   ⚠ 视觉必须与 `.emm-window` 那套一致（B 前端把详情挂 document.body）：
     遮罩 rgba(0,0,0,.45)、窗口 --bg-secondary / 1px --border / 12px 圆角 /
     同一条 0 20px 60px 阴影。**不发明新的视觉语言** —— 只换类名，
     因为刷题模块不 import 英语页的样式，但观感要是同一套。
   ⚠ 滚动交给 .pra-wrong-detail-body（内外两层滚动条会让鼠标滚到边缘就卡住）。 */

.pra-wrong-detail-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(0, 0, 0, 0.45);
  animation: praOverlayIn 140ms ease both;
}
@keyframes praOverlayIn { from { opacity: 0; } to { opacity: 1; } }

.pra-wrong-detail {
  display: flex;
  flex-direction: column;
  width: min(940px, 100%);
  max-height: min(86vh, 100%);
  box-sizing: border-box;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl);
  background: var(--bg-secondary);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.24);
  animation: praWindowIn 160ms cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}
@keyframes praWindowIn {
  from { opacity: 0; transform: translateY(6px) scale(0.995); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
/* 三档尺寸：与 .emm-window-overlay 的 data-size 一致（md / lg / full） */
.pra-wrong-detail-overlay[data-size="md"] .pra-wrong-detail { width: min(760px, 100%); max-height: min(78vh, 100%); }
.pra-wrong-detail-overlay[data-size="lg"] .pra-wrong-detail { width: min(1100px, 100%); max-height: min(90vh, 100%); }
.pra-wrong-detail-overlay[data-size="full"] { padding: 0; }
.pra-wrong-detail-overlay[data-size="full"] .pra-wrong-detail {
  width: 100%;
  height: 100vh;
  max-height: 100vh;
  border: 0;
  border-radius: 0;
}

.pra-wrong-detail-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex: 0 0 auto;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
}
.pra-wrong-detail-title { min-width: 0; }
.pra-wrong-detail-title h2 {
  margin: 0;
  color: var(--text-primary);
  font-size: 1.05rem;
  font-weight: 650;
  letter-spacing: -0.015em;
}
.pra-wrong-detail-title p {
  margin: 5px 0 0;
  color: var(--text-tertiary);
  font-size: 0.75rem;
  line-height: 1.6;
}
.pra-wrong-detail-tools {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}
.pra-wrong-detail-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px 20px 20px;
}
/* 窗内列表不再自带滚动条（滚动交给 body） */
.pra-wrong-detail-body .pra-wrong-list,
.pra-wrong-detail-body .pra-mistakes { max-height: none; overflow: visible; }

/* 详情里的三段：学生答案 / 模型答案 / 手写图 */
.pra-wrong-answer,
.pra-wrong-model,
.pra-wrong-handwriting {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding: 12px 14px;
  border: 1px solid var(--border-light);
  border-radius: var(--radius-lg);
  background: var(--bg-primary);
  color: var(--text-primary);
  font-size: 0.85rem;
  line-height: 1.75;
  overflow-wrap: anywhere;
}
.pra-wrong-answer > strong,
.pra-wrong-model > strong,
.pra-wrong-handwriting > strong {
  color: var(--text-tertiary);
  font-size: 0.69rem;
  font-weight: 650;
  letter-spacing: 0.05em;
}
/* 学生答案：琥珀左边线（"这是你的作答，可能不对"） */
.pra-wrong-answer { border-left: 2px solid var(--pra-warn-line); }
/* 模型答案：绿色左边线 */
.pra-wrong-model { border-left: 2px solid var(--pra-ok-line); }
.pra-wrong-handwriting { border-left: 2px solid var(--accent); }
.pra-wrong-handwriting img,
.pra-wrong-handwriting canvas {
  max-width: 100%;
  max-height: 46vh;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: #fff;
  object-fit: contain;
}
.pra-wrong-handwriting img { cursor: zoom-in; }

/* 详情里的题目图 */
.pra-wrong-question-image {
  max-width: 100%;
  max-height: 46vh;
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md);
  object-fit: contain;
}

/* 打开详情大窗时锁页面滚动（前端给 body 加类；两个名字都支持） */
body.pra-window-open,
body.pra-modal-open { overflow: hidden; }

/* ============================================================
   13. 通用状态类（契约 7.5 末尾）
   ------------------------------------------------------------
   ⚠ 状态一律由 JS 切类表达，**不要用内联 style**（canvas 尺寸与进度条
     宽度这类纯数值除外）。
   ============================================================ */

.pra-page .is-hidden { display: none !important; }
/*
 * ⚠⚠ **不要**给 `.is-empty` 加 `display:none`（这条曾经是 `display:none !important`，
 * 实测把所有难度徽章和难度筛选按钮整块藏掉了）。
 *
 * `.is-empty` 在契约 7.5 里是**语义修饰**，意思是「这一档 0 题」，它有两种完全相反
 * 的正确表现，取决于用在哪：
 *   - `.pra-diff-tag.is-empty`：**要显示**（置灰 0.55），用户得知道「这个单元没有困难题」；
 *     藏了他会以为「这个单元根本没分难度」。
 *   - `.pra-diff-btn.is-empty`：**要显示**（置灰 + disabled），四个按钮少一个会让人以为
 *     界面坏了，而不是「这档没题」。
 *
 * 所以这里只保留「不隐藏」的中性表达。真要隐藏空容器，用 `:empty` 或 `.is-hidden`。
 */
.pra-page .is-loading { cursor: progress; }
/* 加载中的容器整体降透明 + 禁点，避免重复提交 */
.pra-page .is-loading > * { opacity: 0.55; pointer-events: none; }
.pra-page .is-loading::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 18px;
  height: 18px;
  margin: -9px 0 0 -9px;
  border: 2px solid var(--border-hover);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: praSpin 640ms linear infinite;
}
/* .is-loading 需要定位上下文才能居中放转圈 */
.pra-btn.is-loading,
.pra-panel.is-loading,
.pra-card.is-loading,
.pra-answer.is-loading,
.pra-grade-result.is-loading { position: relative; }
/* 按钮里的转圈不遮内容（按钮本身就有 spinner 子元素时用这个） */
.pra-btn.is-loading::after { width: 13px; height: 13px; margin: -6px 0 0 -6px; border-width: 2px; }
.pra-btn.is-loading > * { opacity: 0.7; }

/* 通用状态色（用于没有专门修饰类的元素） */
.pra-page .is-ok { color: var(--success); }
.pra-page .is-warn { color: var(--warning); }
.pra-page .is-danger { color: var(--danger); }
.pra-page .is-active { color: var(--accent); }

/* 骨架屏（工作台首屏加载） */
.pra-skeleton {
  border-radius: var(--radius-2xl);
  background: linear-gradient(
    90deg,
    var(--bg-tertiary) 25%,
    color-mix(in srgb, var(--bg-tertiary) 55%, var(--bg-hover)) 50%,
    var(--bg-tertiary) 75%
  );
  background-size: 400% 100%;
  animation: praSkeleton 1.1s ease-in-out infinite;
}
@keyframes praSkeleton {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ============================================================
   14. 深色 / 壁纸适配
   ------------------------------------------------------------
   绝大部分适配由 Token 自动完成；这里只处理两类「Token 表达不了」的：
   1. 流面板与详情窗在深色下要压暗（半透明色在深底上会发灰）；
   2. 手写画布必须**永远是浅色纸面** —— 深色主题里把纸改成深色，
      墨色与纸面的对比是对的，但用户导出 PNG 交给模型批改时，
      深底浅字在多数视觉模型上识别率明显更差（且打印出来是黑块）。
      所以纸面固定浅色，墨色固定深色，见下。
   ============================================================ */

[data-theme="dark"] .pra-stream-panel {
  background: color-mix(in srgb, var(--accent) 9%, var(--bg-secondary));
}
[data-theme="dark"] .pra-stream-out {
  background: color-mix(in srgb, var(--bg-primary) 82%, #fff 5%);
}
[data-theme="dark"] .pra-stream-pane.is-think .pra-stream-out {
  background: color-mix(in srgb, var(--bg-tertiary) 88%, #fff 3%);
}
[data-theme="dark"] .pra-wrong-detail-overlay { background: rgba(0, 0, 0, 0.62); }

/* 手写纸面：两种主题都用浅色（理由见上）。用固定浅色而不是 --bg-secondary，
   因为壁纸模式会把它改成半透明玻璃，透出壁纸后笔迹对比度不可控。 */
.pra-page .pra-ink-canvas {
  background-color: #fdfdfb;
  --pra-ink-paper: #fdfdfb;
}
/* 深色主题下画布边框要更明显（浅纸压在深背景上，1px --border 几乎看不见） */
[data-theme="dark"] .pra-page .pra-ink-canvas {
  border-color: color-mix(in srgb, var(--border-hover) 80%, transparent);
}
/* 格线颜色：画布已固定浅纸，格线也必须用浅纸上的深灰，不能跟随主题 Token
   （深色主题的 --border 是白色半透明，画在浅纸上等于没有）。 */
.pra-page .pra-ink-wrap.is-lined .pra-ink-canvas,
.pra-page .pra-ink-wrap[data-ink-bg="lined"] .pra-ink-canvas,
.pra-page .pra-ink-wrap.is-grid .pra-ink-canvas,
.pra-page .pra-ink-wrap[data-ink-bg="grid"] .pra-ink-canvas {
  --pra-ink-rule: rgba(22, 24, 29, 0.14);
}

/* 壁纸模式：刷题页的承载面板要加模糊，否则半透明底会像"没画完的色块" */
html.has-wallpaper .pra-card,
html.has-wallpaper .pra-panel,
html.has-wallpaper .pra-question,
html.has-wallpaper .pra-answer,
html.has-wallpaper .pra-grade-result,
html.has-wallpaper .pra-stream-panel,
html.has-wallpaper .pra-wrong-detail,
html.has-wallpaper .pra-wrong-item,
html.has-wallpaper .pra-wrong-filter,
html.has-wallpaper .pra-empty {
  backdrop-filter: blur(22px) saturate(140%);
  -webkit-backdrop-filter: blur(22px) saturate(140%);
}

/* ---------- 进度行在壁纸模式下的背衬 ----------
 * ⚠ 这一条是**实测**驱动的，不是"看起来更保险"：
 *   页头是透明容器，5px 的进度条直接压在照片上。1440px + 壁纸开实测像素对比度
 *     轨道 vs 背景 1.16:1、蓝色填充 vs 背景 1.53:1（WCAG 非文本要求 3:1）。
 *   **填充也只有 1.53** —— 所以只调轨道透明度没用，整条都要垫。
 *   做法沿用 wallpaper.css 的「零散小字的背衬」：`--wp-text-backing`
 *   是项目实测过的可读性下限（94%），且已随 `--ui-opacity` 有过兜底。
 *   只加背景，不动尺寸/间距（背景不参与布局，零位移）。 */
html.has-wallpaper .pra-progress-row {
  position: relative;
  isolation: isolate;
  padding: 5px 8px;
  border-radius: var(--radius-full);
}
html.has-wallpaper .pra-progress-row::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  border-radius: inherit;
  background: var(--wp-text-backing);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
/* 垫了背衬之后轨道不必再靠"半透明灰"去叠照片，回到正常的浅灰即可 ——
   20% 的 `--text-tertiary` 在 94% 背衬上已经够看（实测见 docs 里的记录）。 */
html.has-wallpaper .pra-progress-bar {
  background: color-mix(in srgb, var(--text-tertiary) 26%, transparent);
}
/* 详情大窗铺在最上层，模糊略强一点（与 .emm-window 同源） */
html.has-wallpaper .pra-wrong-detail {
  border-color: color-mix(in srgb, var(--rd-line-strong) 62%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 16%, transparent),
    var(--rd-shadow);
}
[data-theme="light"] html.has-wallpaper .pra-wrong-detail {
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 55%, transparent),
    0 1px 2px color-mix(in srgb, #000 8%, transparent),
    var(--rd-shadow);
}

/* ============================================================
   15. 响应式
   ============================================================ */

/* 答题屏两栏 → 一列。⚠ 960px 是契约给的断点；折成一列后**题目必须排最前**
   （DOM 里 .pra-answer 可能在 .pra-question 之前，不显式排序就会先看到作答区）。 */
@media (max-width: 960px) {
  .pra-session,
  .pra-session-body {
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
  }
  .pra-session > .pra-question,
  .pra-session-body > .pra-question { grid-column: 1; order: -3; }
  .pra-session > .pra-session-head,
  .pra-session-body > .pra-session-head { order: -4; }
  .pra-session > .pra-progress-bar,
  .pra-session-body > .pra-progress-bar { order: -2; }
  .pra-session > .pra-answer,
  .pra-session-body > .pra-answer,
  .pra-session > .pra-stream-panel,
  .pra-session-body > .pra-stream-panel,
  .pra-session > .pra-grade-result,
  .pra-session-body > .pra-grade-result,
  .pra-session > .pra-submit-row,
  .pra-session-body > .pra-submit-row,
  .pra-session > .pra-countdown,
  .pra-session-body > .pra-countdown { grid-column: 1; }
  /* 工作台侧栏折到下方 */
  .pra-workbench { grid-template-columns: minmax(0, 1fr); }
  .pra-workbench-side {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 12px;
  }
}

@media (max-width: 720px) {
  .pra-page,
  .pra-page--session,
  .pra-page.pra-session,
  .pra-page--wrongbook { width: calc(100% - 20px); padding-bottom: 32px; }
  .pra-header { grid-template-columns: auto minmax(0, 1fr); row-gap: 8px; }
  .pra-header-tools { grid-column: 1 / -1; justify-content: flex-start; }
  .pra-title { font-size: 1.06rem; }
  .pra-model-form { grid-template-columns: minmax(0, 1fr); }
  .pra-question,
  .pra-answer,
  .pra-grade-result,
  .pra-stream-panel { padding: 13px 14px; }
  .pra-question-text { font-size: 0.9rem; line-height: 1.78; }
  .pra-ink-canvas { height: clamp(200px, 30vh, 300px); }
  .pra-stream-out { max-height: 168px; font-size: 0.7rem; }
  .pra-summary:has(.pra-summary-grid) { padding: 16px 14px; }
  .pra-summary-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* 错题项折成上下两段，操作按钮另起一行 */
  .pra-wrong-item { flex-wrap: wrap; }
  .pra-wrong-actions { width: 100%; justify-content: flex-end; }
  /* 手机上的详情大窗就是全屏抽屉（留白给不出信息） */
  .pra-wrong-detail-overlay { padding: 0; }
  .pra-wrong-detail {
    width: 100%;
    height: 100vh;
    max-height: 100vh;
    border: 0;
    border-radius: 0;
  }
  .pra-wrong-detail-head { padding: 14px 14px 12px; }
  .pra-wrong-detail-body { padding: 12px 14px 18px; }
  .pra-empty { padding: 32px 16px; }
}

@media (max-width: 420px) {
  .pra-countdown { font-size: 0.84rem; padding: 4px 10px; }
  .pra-btn { font-size: 0.79rem; padding: 6px 11px; }
  .pra-ink-tool { width: 28px; height: 28px; }
  .pra-ink-toolbar { gap: 3px; padding: 4px; }
}

/* ============================================================
   16. 减少动效 / 打印
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  .pra-countdown.is-danger,
  .pra-stream-dot { animation: none; }
  .pra-progress-fill,
  .pra-card,
  .pra-wrong-item { transition: none; }
  .pra-card:hover { transform: none; }
  .pra-wrong-detail,
  .pra-wrong-detail-overlay { animation: none; }
  .pra-skeleton { animation: none; }
}

@media print {
  .pra-header-tools,
  .pra-submit-row,
  .pra-ink-toolbar,
  .pra-stream-panel,
  .pra-wrong-detail-overlay,
  .pra-btn { display: none !important; }
  .pra-page { width: 100%; }
  .pra-session { display: block; }
  .pra-question,
  .pra-answer,
  .pra-grade-result { break-inside: avoid; border: 1px solid #ccc !important; box-shadow: none !important; }
}
/* ==== pages/eng-maimemo.css ==== */
/* ==========================================================================
   墨墨词库复习（/eng 及其子页面）
   页头复用 css/english.css 的 .eng-* 结构，内容区统一 emm- 前缀。
   深色模式规则见文末 [data-theme="dark"]。
   ========================================================================== */

.emm-page { min-height: calc(100vh - 60px); padding-bottom: 64px; }
.emm-header { border-bottom: 1px solid var(--border); }
.emm-header-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.emm-icon-btn { width: 40px; height: 40px; flex: 0 0 40px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-secondary); color: var(--text-primary); cursor: pointer; transition: all .15s ease; }
.emm-icon-btn:hover { border-color: var(--eng-color); color: var(--eng-color); }
.emm-icon-btn svg { width: 18px; height: 18px; }

/* ---------- 页签 ---------- */
.emm-tabs { width: min(1180px, calc(100% - 48px)); margin: 18px auto 0; display: flex; gap: 4px; overflow-x: auto; border-bottom: 1px solid var(--border); }
.emm-tab { flex: 0 0 auto; padding: 10px 16px; border: 0; border-bottom: 2px solid transparent; background: transparent; color: var(--text-tertiary); font: inherit; font-size: 14px; font-weight: 600; cursor: pointer; transition: color .15s ease, border-color .15s ease; }
.emm-tab:hover { color: var(--text-primary); }
.emm-tab.is-active { color: var(--eng-ink, var(--eng-color)); border-bottom-color: var(--eng-color); }

.emm-body { width: min(1180px, calc(100% - 48px)); margin: 26px auto 0; }
.emm-kicker { display: block; color: var(--text-tertiary); font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; }
.emm-muted { color: var(--text-tertiary); font-size: 13px; }
.emm-loading { padding: 48px 0; text-align: center; color: var(--text-tertiary); font-size: 14px; }
.emm-error-text { margin: 12px 0 0; color: #dc2626; font-size: 14px; line-height: 1.7; }

/* ---------- 首页 hero ---------- */
.emm-hero { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 32px; align-items: center; padding: 32px; border: 1px solid var(--border); border-radius: 14px; background: var(--bg-secondary); }
.emm-hero-main h2 { margin: 10px 0 12px; font-size: 27px; line-height: 1.35; color: var(--text-primary); }
.emm-hero-main h2 em { font-style: normal; color: var(--eng-color); }
.emm-hero-main > p { margin: 0; max-width: 620px; color: var(--text-secondary); font-size: 14px; line-height: 1.8; }
.emm-hero-actions { display: flex; flex-wrap: wrap; gap: 10px; margin: 22px 0 12px; }
.emm-hero-actions svg { width: 16px; height: 16px; }
.emm-sync-note { color: var(--text-tertiary); font-size: 12px; }
.emm-hero-progress { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 20px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-primary); text-align: center; }
.emm-progress-ring { width: 128px; height: 128px; display: grid; place-items: center; border-radius: 50%; background: conic-gradient(var(--eng-color) calc(var(--p, 0) * 1%), var(--eng-light-2) 0); position: relative; }
.emm-progress-ring::after { content: ''; position: absolute; inset: 10px; border-radius: 50%; background: var(--bg-primary); }
.emm-progress-ring strong { position: relative; z-index: 1; color: var(--text-primary); font-size: 30px; line-height: 1; }
.emm-progress-ring strong small { color: var(--text-tertiary); font-size: 15px; font-weight: 500; }
.emm-progress-label { margin: 6px 0 0; color: var(--text-secondary); font-size: 13px; font-weight: 600; }
.emm-progress-time { margin: 0; color: var(--text-tertiary); font-size: 11px; }

/* ---------- 统计 ---------- */
.emm-stats { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 1px; margin-top: 18px; border: 1px solid var(--border); border-radius: 10px; background: var(--border); overflow: hidden; }
.emm-stats.is-compact { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 12px; }
.emm-stat { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; min-height: 84px; padding: 14px 8px; background: var(--bg-secondary); text-align: center; }
.emm-stats.is-compact .emm-stat { min-height: 70px; }
.emm-stat strong { color: var(--text-primary); font-size: 23px; line-height: 1; }
.emm-stat span { color: var(--text-tertiary); font-size: 11px; }
.emm-stat.is-warn strong { color: #d97706; }
.emm-stat.is-danger strong { color: #dc2626; }

.emm-grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; margin-top: 18px; }
.emm-panel { padding: 20px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-secondary); }
.emm-panel > header { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
.emm-panel > header h3 { margin: 0; color: var(--text-primary); font-size: 15px; }
.emm-panel > header span { color: var(--text-tertiary); font-size: 11px; }
.emm-kind-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.emm-kind-list li { display: flex; align-items: center; justify-content: space-between; padding: 8px 12px; border-radius: 8px; background: var(--bg-primary); color: var(--text-secondary); font-size: 13px; }
.emm-kind-list li strong { color: #dc2626; }
.emm-kind-list li.is-empty { justify-content: flex-start; color: var(--text-tertiary); }

/* ---------- 模块入口 ---------- */
.emm-entries { margin-top: 28px; }
.emm-section-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 14px; }
.emm-section-head h2 { margin: 0; color: var(--text-primary); font-size: 18px; }
.emm-entry-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.emm-entry { display: flex; align-items: center; gap: 14px; padding: 18px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-secondary); color: inherit; text-align: left; cursor: pointer; font: inherit; transition: border-color .15s ease, transform .15s ease; }
.emm-entry:hover { border-color: var(--eng-color); transform: translateY(-1px); }
.emm-entry-icon { width: 42px; height: 42px; flex: 0 0 42px; display: grid; place-items: center; border-radius: 11px; background: var(--eng-light); color: var(--eng-color); }
.emm-entry-icon svg { width: 20px; height: 20px; }
.emm-entry-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.emm-entry-body strong { color: var(--text-primary); font-size: 15px; }
.emm-entry-body small { color: var(--text-tertiary); font-size: 12px; line-height: 1.6; }
.emm-entry-arrow { color: var(--text-tertiary); flex: 0 0 auto; }
.emm-entry-arrow svg { width: 16px; height: 16px; }

/* ---------- 空态 ---------- */
.emm-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 320px; padding: 40px 24px; border: 1px dashed var(--border); border-radius: 12px; color: var(--text-tertiary); text-align: center; }
.emm-empty > svg { width: 30px; height: 30px; }
.emm-empty h2 { margin: 14px 0 6px; color: var(--text-primary); font-size: 18px; }
.emm-empty p { margin: 0 0 16px; max-width: 460px; font-size: 13px; line-height: 1.7; }

/* ---------- 工具条 ---------- */
.emm-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 18px; }
.emm-toolbar.is-center { justify-content: space-between; }
.emm-toolbar-right { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.emm-toolbar-right .btn { display: inline-flex; align-items: center; gap: 6px; }
.emm-toolbar-right .btn svg { width: 15px; height: 15px; }
.emm-search { display: flex; align-items: center; gap: 8px; min-width: 260px; flex: 1 1 260px; max-width: 360px; padding: 0 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-secondary); }
.emm-search svg { width: 16px; height: 16px; color: var(--text-tertiary); flex: 0 0 auto; }
.emm-search input { width: 100%; height: 40px; border: 0; background: transparent; color: var(--text-primary); font: inherit; font-size: 14px; outline: none; }
.emm-filter-row { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.emm-filter { padding: 7px 13px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg-secondary); color: var(--text-secondary); font: inherit; font-size: 12.5px; cursor: pointer; transition: all .15s ease; }
/* --eng-color (#3b82f6) as text only reaches 3.68:1; use the fill token for the
   solid active state and --eng-ink for accent text on tinted surfaces. */
.emm-filter:hover { border-color: var(--rd-blue-strong, var(--eng-color)); color: var(--eng-ink, var(--eng-color)); }
.emm-filter.is-active { background: var(--rd-blue-strong, var(--eng-color)); border-color: var(--rd-blue-strong, var(--eng-color)); color: #fff; }
.emm-select { height: 38px; padding: 0 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-secondary); color: var(--text-primary); font: inherit; font-size: 13px; cursor: pointer; }
.emm-count { color: var(--text-tertiary); font-size: 12px; white-space: nowrap; }
.emm-inline-stats { display: flex; gap: 18px; }
.emm-inline-stats > div { display: flex; flex-direction: column; align-items: center; }
.emm-inline-stats strong { color: var(--text-primary); font-size: 18px; }
.emm-inline-stats span { color: var(--text-tertiary); font-size: 11px; }

/* ---------- 词条标签 ---------- */
.emm-chip { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 999px; background: var(--bg-primary); border: 1px solid var(--border); color: var(--text-tertiary); font-size: 11px; white-space: nowrap; }
.emm-chip.is-sticking { border-color: #dc2626; color: #dc2626; }
.emm-chip.is-familiar { border-color: var(--rd-green-strong); color: var(--rd-green-strong); }
.emm-chip.is-today { border-color: var(--eng-color); color: var(--eng-ink, var(--eng-color)); }
.emm-chip.is-wrong { border-color: #d97706; color: #d97706; }
.emm-chip.is-meaning { border-style: dashed; color: var(--text-secondary); }

/* ---------- 词库：全局预览卡片网格 ----------
   用户要求「修改词库展示形式，改成全局预览卡片的形式」。
   旧版是单列窄栏（`minmax(0,1fr) 360px`，实测列表只有 736px），一个词占一整行、
   40 个词要滚好几屏，右边那 360px 还常年空着。改成卡片网格之后同样一屏能看 4~6 倍。

   ⚠ `auto-fill` 而不是 `auto-fit`：`auto-fit` 会把不足一行的卡片**拉宽填满**
     （3 个词时每张变成 1/3 屏宽，看起来像坏了），`auto-fill` 保持卡片宽度一致。
   ⚠ `minmax(190px, 1fr)`：190px 是能放下「generation 2 次」+ 两行释义的下限，
     再窄拼写就要断词了。 */
.emm-word-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 10px; margin: 0; padding: 0; list-style: none;
}
.emm-word-card {
  display: flex; flex-direction: column; gap: 7px;
  padding: 12px 13px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--bg-secondary); cursor: pointer; transition: border-color .15s ease, background .15s ease, transform .12s ease;
}
.emm-word-card:hover { background: var(--bg-primary); border-color: color-mix(in srgb, var(--eng-color) 40%, var(--border)); transform: translateY(-1px); }
.emm-word-card:focus-visible { outline: 2px solid var(--eng-color); outline-offset: 2px; }
.emm-word-card.is-selected { border-color: var(--eng-color); background: var(--eng-light); }
/* ⚠⚠ **拼写与次数徽标不能挤在同一行抢宽度**（实测踩到）：
     卡片 215px 宽，徽标固定占 60px，长词只剩 119px，而
     `entrepreneurial` 单行需要 132px → 被 `overflow-wrap: anywhere`
     从**词中间**硬断成 `entrepreneuri` + `al`（截图上一眼可见的破相）。
   改成 `flex-wrap: wrap`：放得下就并排（绝大多数词），放不下徽标**整体换到下一行**，
   拼写保持完整。这比把字号调小或让词断掉都好 —— 拼写是卡片上最重要的信息。 */
.emm-word-card-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 8px; }
/* ⚠ `min-width: 0` 让长词可以换行而不是撑破卡片；`overflow-wrap: anywhere`
   只在**万不得已**（一个词比整张卡还长）时才从中间断。 */
.emm-word-card-head strong { min-width: 0; color: var(--text-primary); font-size: 16px; font-family: Georgia, 'Times New Roman', serif; overflow-wrap: anywhere; }
/* ⚠ 释义夹到两行：长度不可控（「虫子」到三行都有），不夹住卡片高度会参差不齐。 */
.emm-word-card-meaning {
  margin: 0; color: var(--text-secondary); font-size: 12.5px; line-height: 1.55;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.emm-word-card-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; margin-top: auto; }
.emm-word-stat { padding: 1px 6px; border-radius: 5px; background: var(--bg-primary); color: var(--text-tertiary); font-size: 10.5px; white-space: nowrap; }
.emm-word-stat.is-wrong { background: color-mix(in srgb, #dc2626 14%, transparent); color: #b91c1c; }
.emm-word-stat.is-due { background: color-mix(in srgb, var(--eng-color) 16%, transparent); color: var(--eng-color); }

/* 「生成次数」徽标 —— 用户明确要求显示的那个数字。
   ⚠ 三态各有各的样子，不能糊成一种（服务端为此专门返回 null 而不是 0）：
      · is-unknown → 「—」，中性灰（**不知道**，不是 0）
      · is-zero    → 「没生成过」，弱化灰（确实没被选过）
      · 默认 / is-many → 「生成 N 次」，练过多轮的给强调色（用户就是靠它看该轮到谁） */
.emm-word-count { flex: 0 0 auto; padding: 1px 7px; border-radius: 999px; font-size: 10.5px; white-space: nowrap; border: 1px solid transparent; }
.emm-word-count.is-unknown { background: transparent; border-color: var(--border); color: var(--text-tertiary); }
.emm-word-count.is-zero { background: var(--bg-primary); color: var(--text-tertiary); }
.emm-word-count.is-many { background: color-mix(in srgb, var(--eng-color) 18%, transparent); border-color: color-mix(in srgb, var(--eng-color) 35%, transparent); color: var(--eng-color); font-weight: 600; }
.emm-grid-hint { margin: 0 0 12px; color: var(--text-tertiary); font-size: 12px; line-height: 1.7; }
.emm-grid-hint b { color: var(--text-secondary); }
.emm-list-end { margin: 16px 0 0; color: var(--text-tertiary); font-size: 12px; text-align: center; }

/* 词库的错词本列表仍是单列（那条线没有改成卡片，保持原样）。 */
.emm-word-list, .emm-wrong-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 1px; border: 1px solid var(--border); border-radius: 10px; background: var(--border); overflow: hidden; }
.emm-word-row { display: flex; align-items: center; gap: 12px; padding: 14px 16px; background: var(--bg-secondary); cursor: pointer; transition: background .15s ease; }
.emm-word-row:hover { background: var(--bg-primary); }
.emm-word-row.is-selected { background: var(--eng-light); box-shadow: inset 3px 0 0 var(--eng-color); }
.emm-word-main { flex: 1; min-width: 0; }
.emm-word-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.emm-word-head strong { color: var(--text-primary); font-size: 16px; font-family: Georgia, 'Times New Roman', serif; }
.emm-word-meaning { margin: 4px 0 0; color: var(--text-secondary); font-size: 13px; line-height: 1.6; }
.emm-word-meta { margin: 4px 0 0; color: var(--text-tertiary); font-size: 11.5px; }
.emm-word-arrow { color: var(--text-tertiary); flex: 0 0 auto; }
.emm-word-arrow svg { width: 16px; height: 16px; }
.emm-more { display: block; width: 100%; margin-top: 12px; }

/* ---------- 单词详情（弹窗）----------
   ⚠ 详情从「右侧常驻栏」改成**居中大窗**（用户选定）。外壳复用 `.emm-window`
   那一套（见 `listWindow.js`），所以这里只补词库特有的排版。 */
.emm-word-window { --emm-window-w: min(680px, 100%); }
/* ⚠ 正文的起点是**释义**（拼写已在窗口标题栏，不重复画）。 */
.emm-word-detail-meaning { margin: 0; color: var(--text-secondary); font-size: 14px; line-height: 1.7; }
.emm-detail-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.emm-detail-facts { margin: 16px 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.emm-detail-facts > div { padding: 9px 11px; border-radius: 8px; background: var(--bg-primary); }
.emm-detail-facts dt { color: var(--text-tertiary); font-size: 11px; }
.emm-detail-facts dd { margin: 3px 0 0; color: var(--text-primary); font-size: 13px; font-weight: 600; }
.emm-detail-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.emm-detail-section { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border); }
.emm-detail-section h4 { margin: 0 0 10px; color: var(--text-primary); font-size: 13px; }
.emm-detail-section h4 span { color: var(--text-tertiary); font-weight: 400; }
.emm-phrase-list, .emm-history-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.emm-phrase-list li { padding: 10px 12px; border-left: 3px solid var(--eng-light-2); background: var(--bg-primary); border-radius: 0 8px 8px 0; }
.emm-phrase-list p { margin: 0; color: var(--text-primary); font-size: 13px; line-height: 1.6; }
.emm-phrase-list small { color: var(--text-tertiary); font-size: 12px; }
.emm-history-list li { display: grid; grid-template-columns: 1fr auto auto; gap: 8px; align-items: center; padding: 7px 11px; border-radius: 8px; background: var(--bg-primary); font-size: 12px; color: var(--text-secondary); }
.emm-history-list li.is-correct strong { color: var(--rd-green-strong); }
.emm-history-list li.is-wrong strong { color: #dc2626; }
.emm-history-list small { color: var(--text-tertiary); }

/* ---------- 词库范围 / 提示 ---------- */
.emm-notice { margin: 18px 0 0; padding: 13px 16px; border: 1px solid var(--border); border-left: 3px solid #d97706; border-radius: 8px; background: var(--bg-secondary); color: var(--text-secondary); font-size: 13px; line-height: 1.75; }
.emm-filter-num { margin-left: 5px; opacity: .72; font-size: 11px; }
.emm-panel.is-scope { margin-top: 18px; }
.emm-scope-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.emm-scope-list.is-inline { flex-direction: row; flex-wrap: wrap; gap: 10px; }
.emm-scope-list li { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 12px; border-radius: 8px; background: var(--bg-primary); font-size: 13px; }
.emm-scope-list.is-inline li { min-width: 160px; }
.emm-scope-list strong { color: var(--text-primary); font-weight: 600; }
.emm-scope-list small { color: var(--text-tertiary); font-size: 11px; }
.emm-scope-note { margin: 12px 0 0; }
.emm-danger-link { margin-top: 18px; padding: 0; border: 0; background: transparent; color: #dc2626; font: inherit; font-size: 12px; cursor: pointer; text-decoration: underline; }

/* ---------- 练习卡片 ---------- */
.emm-progress { margin-bottom: 14px; }
.emm-progress-bar { height: 6px; border-radius: 999px; background: var(--eng-light-2); overflow: hidden; }
.emm-progress-bar span { display: block; height: 100%; background: var(--eng-color); transition: width .25s ease; }
.emm-progress p { margin: 8px 0 0; color: var(--text-tertiary); font-size: 12px; }
.emm-stage { min-width: 0; }
.emm-card { display: flex; flex-direction: column; min-height: 420px; padding: 28px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-secondary); }
.emm-card > header { display: flex; align-items: center; justify-content: space-between; gap: 12px; color: var(--text-tertiary); font-size: 12px; }
.emm-kind { color: var(--eng-color); font-weight: 700; }
.emm-source { color: var(--text-tertiary); }
.emm-card-wait { align-items: center; justify-content: center; text-align: center; gap: 8px; }
.emm-card-wait h2 { margin: 10px 0 0; color: var(--text-primary); font-size: 22px; font-family: Georgia, 'Times New Roman', serif; }
.emm-card-wait p { margin: 0; color: var(--text-secondary); font-size: 14px; }
.emm-card-wait small { color: var(--text-tertiary); font-size: 12px; }
.emm-spinner { width: 30px; height: 30px; border: 3px solid var(--eng-light-2); border-top-color: var(--eng-color); border-radius: 50%; animation: emm-spin .8s linear infinite; }
@keyframes emm-spin { to { transform: rotate(360deg); } }
.emm-card-word { margin: 26px 0 10px; color: var(--text-primary); font: 700 32px/1.2 Georgia, 'Times New Roman', serif; overflow-wrap: anywhere; }
.emm-card-word.is-instruction { font-family: inherit; font-size: 17px; }
.emm-card-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.emm-prompt { max-width: 720px; margin: 0 0 10px; color: var(--text-primary); font-size: 19px; line-height: 1.85; white-space: pre-wrap; }
.emm-hint { max-width: 640px; margin: 0 0 22px; color: var(--text-tertiary); font-size: 13px; line-height: 1.7; }
.emm-answer-label { margin-bottom: 7px; color: var(--text-tertiary); font-size: 12px; }
.emm-answer-input { width: 100%; box-sizing: border-box; resize: vertical; padding: 13px 14px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-primary); color: var(--text-primary); font: inherit; font-size: 15px; line-height: 1.6; }
.emm-answer-input:focus { outline: 2px solid var(--eng-light-2); border-color: var(--eng-color); }
.emm-answer-input:disabled { opacity: .7; }
.emm-card-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: auto; padding-top: 22px; }
.emm-card-actions .btn { display: inline-flex; align-items: center; gap: 6px; }
.emm-card-actions svg { width: 15px; height: 15px; }

.emm-result { margin-top: 16px; padding: 16px; border-left: 3px solid var(--rd-green-strong); background: rgba(22, 163, 74, .07); }
.emm-result.is-wrong { border-left-color: #dc2626; background: rgba(220, 38, 38, .07); }
.emm-result strong { color: var(--rd-green-strong); font-size: 14px; }
.emm-result.is-wrong strong { color: #dc2626; }
.emm-result p { margin: 7px 0 0; color: var(--text-secondary); font-size: 13px; line-height: 1.7; }
.emm-result-hint b { color: var(--text-primary); }
.emm-reference { margin-top: 12px; padding: 12px; border-radius: 8px; background: var(--bg-primary); }
.emm-reference span { color: var(--text-tertiary); font-size: 11px; }
.emm-reference p { margin: 5px 0 0; color: var(--text-primary); font-size: 14px; line-height: 1.7; white-space: pre-wrap; }
.emm-result small { display: block; margin-top: 10px; color: var(--text-tertiary); font-size: 12px; line-height: 1.6; }

/* ---------- 长难句 ---------- */
.emm-sentence { margin: 20px 0 14px; padding: 18px 20px; border-radius: 10px; background: var(--bg-primary); color: var(--text-primary); font: 400 19px/1.9 Georgia, 'Times New Roman', serif; }
.emm-step { margin-top: 22px; }
.emm-step h3 { margin: 0 0 12px; color: var(--text-primary); font-size: 15px; }
.emm-question-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 18px; }
.emm-question-prompt { display: flex; gap: 9px; margin: 0 0 10px; color: var(--text-primary); font-size: 14px; line-height: 1.7; }
.emm-question-prompt span { flex: 0 0 22px; height: 22px; display: grid; place-items: center; border-radius: 50%; background: var(--eng-light); color: var(--eng-color); font-size: 12px; font-weight: 700; }
.emm-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.emm-option { display: flex; align-items: flex-start; gap: 9px; padding: 11px 13px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); color: var(--text-secondary); font-size: 13.5px; line-height: 1.6; cursor: pointer; transition: border-color .15s ease; }
.emm-option:hover { border-color: var(--eng-color); }
.emm-option input { margin-top: 3px; accent-color: var(--eng-color); }
.emm-option.is-picked { border-color: var(--eng-color); background: var(--eng-light); color: var(--text-primary); }
.emm-option.is-correct { border-color: var(--rd-green-strong); background: rgba(22, 163, 74, .09); color: var(--text-primary); }
.emm-option.is-wrong { border-color: #dc2626; background: rgba(220, 38, 38, .08); }
.emm-question-explain { margin: 9px 0 0; padding: 10px 12px; border-radius: 8px; background: var(--bg-primary); color: var(--text-tertiary); font-size: 12.5px; line-height: 1.7; }
.emm-analysis { padding: 16px; border-radius: 10px; background: var(--bg-primary); }
.emm-analysis > p { margin: 0 0 12px; color: var(--text-secondary); font-size: 13.5px; line-height: 1.8; }
.emm-analysis b { color: var(--text-primary); }
.emm-segments { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.emm-segments li { display: grid; grid-template-columns: minmax(0, 1.2fr) auto; gap: 4px 12px; padding: 10px 12px; border-radius: 8px; background: var(--bg-secondary); }
.emm-segments code { color: var(--text-primary); font-size: 12.5px; overflow-wrap: anywhere; }
.emm-segments span { align-self: start; padding: 2px 8px; border-radius: 999px; background: var(--eng-light); color: var(--eng-color); font-size: 11px; white-space: nowrap; }
.emm-segments small { grid-column: 1 / -1; color: var(--text-tertiary); font-size: 12px; line-height: 1.6; }

/* ---------- 错词本 ---------- */
.emm-wrong-row { display: flex; align-items: center; gap: 16px; padding: 16px; background: var(--bg-secondary); }
.emm-wrong-actions { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex: 0 0 auto; }
.emm-wrong-actions .emm-danger-link { margin-top: 0; }

/* ---------- 弹窗 ---------- */
.emm-dialog-overlay { position: fixed; inset: 0; z-index: 2000; display: grid; place-items: center; padding: 20px; background: rgba(0, 0, 0, .45); }
.emm-dialog { width: min(540px, 100%); padding: 24px; box-sizing: border-box; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-secondary); box-shadow: 0 20px 60px rgba(0, 0, 0, .24); }
.emm-dialog-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; }
.emm-dialog h2 { margin: 0 0 6px; color: var(--text-primary); font-size: 20px; }
.emm-dialog-head p { margin: 0 0 20px; color: var(--text-tertiary); font-size: 12px; line-height: 1.7; }
.emm-dialog label { display: block; margin-bottom: 7px; color: var(--text-secondary); font-size: 13px; font-weight: 600; }
.emm-dialog textarea { width: 100%; padding: 12px; box-sizing: border-box; resize: vertical; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-primary); color: var(--text-primary); font: inherit; }
.emm-dialog-note { margin: 12px 0 0; color: var(--text-tertiary); font-size: 12px; line-height: 1.7; }
.emm-dialog-actions { display: flex; justify-content: flex-end; gap: 9px; margin-top: 18px; }

/* ---------- 响应式 ---------- */
@media (max-width: 1000px) {
  .emm-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .emm-hero { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 760px) {
  .emm-body, .emm-tabs { width: calc(100% - 28px); }
  .emm-body { margin-top: 18px; }
  .emm-hero { padding: 22px; }
  .emm-hero-main h2 { font-size: 22px; }
  .emm-grid-2, .emm-entry-grid, .emm-options { grid-template-columns: minmax(0, 1fr); }
  .emm-stats, .emm-stats.is-compact { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .emm-card { padding: 20px; min-height: 380px; }
  .emm-card-word { margin-top: 18px; font-size: 26px; }
  .emm-prompt { font-size: 17px; }
  .emm-toolbar-right { width: 100%; margin-left: 0; flex-wrap: wrap; }
  .emm-search { max-width: none; }
  .emm-wrong-row { flex-direction: column; align-items: stretch; }
  .emm-wrong-actions { flex-direction: row; align-items: center; justify-content: flex-end; }
  .emm-detail-facts { grid-template-columns: minmax(0, 1fr); }
  /* ⚠ 窄屏把卡片下限降到 150px：190px 在 375px 宽的屏上只能排 1 列，
     一屏看 2 个词，「全局预览」的意义就没了。150px 能排 2 列。 */
  .emm-word-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
}

/* ---------- 打印出口（/eng/paper 工作台） ----------
   打印件本身由服务端渲染成独立文档，样式写在 utils/englishMaimemoPaper.js 的
   PAPER_CSS 里，与本文件无关；这里只管工作台这一屏。 */
.emm-paper-layout { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 22px; align-items: start; }
.emm-paper-form { display: flex; flex-direction: column; gap: 18px; padding: 22px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-secondary); }
.emm-paper-field { margin: 0; padding: 0; border: 0; }
.emm-paper-field > label, .emm-paper-field > legend { display: block; margin-bottom: 9px; padding: 0; color: var(--text-secondary); font-size: 13px; font-weight: 600; }
.emm-paper-field > legend span { margin-left: 6px; color: var(--text-tertiary); font-size: 12px; font-weight: 400; }
.emm-paper-field input[type="text"] { width: 100%; padding: 10px 12px; box-sizing: border-box; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-primary); color: var(--text-primary); font: inherit; font-size: 14px; }
/* ===== 打印出口：可打印任务清单 =====
   ⚠ 用户要求「打印就是打印一整个任务，短句和长难句任务分开，打印的时候就提供
     选择打印哪个」—— 所以这里取代了原来的「题型勾选框 + 数字输入框 + 日历」。
   原来的 .emm-paper-types / .emm-paper-type / .emm-paper-nums / .emm-cal-* 已删除。 */
.emm-paper-tasks { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; list-style: none; }
.emm-paper-task { margin: 0; }
.emm-paper-task-pick {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px;
  width: 100%; padding: 12px; box-sizing: border-box;
  border: 1px solid var(--border); border-radius: 9px;
  background: var(--bg-primary); color: var(--text-primary);
  font: inherit; text-align: left; cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.emm-paper-task-pick:hover { border-color: var(--eng-ink, var(--eng-color)); }
/* 选中态：与题型卡片同一套视觉语言（边框加粗 + 淡色底），别引入新配色。 */
.emm-paper-task.is-on .emm-paper-task-pick {
  border-color: var(--rd-blue-strong, var(--eng-color));
  background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 8%, var(--bg-primary));
}
.emm-paper-task-pick strong { color: var(--text-primary); font-size: 13.5px; }
.emm-paper-task-meta { margin-left: auto; color: var(--text-tertiary); font-size: 12px; }
/* 类型徽章：两条线用不同色调，一眼看出印的是哪种材料。 */
.emm-paper-task-kind {
  flex: 0 0 auto; padding: 2px 8px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600;
  background: var(--bg-secondary); color: var(--text-secondary);
}
.emm-paper-task-kind.is-micro {
  background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 14%, var(--bg-secondary));
  color: var(--eng-ink, var(--eng-color));
}
/* 阅读练习：第三种材料，单独一个色调，避免和长难句混在一起认错。 */
.emm-paper-task-kind.is-reading {
  background: color-mix(in srgb, #16a34a 16%, var(--bg-secondary));
  color: #15803d;
}
/**
 * 真题练习报告：第四种材料。
 *
 * ⚠ 它和前三种的性质不同 —— 前三种是「生成台产物，印的时候不调模型」，
 *   这一种是「题组的作答记录，挖生僻词会调模型」。所以用**紫色**与它们区分，
 *   让用户在点之前就知道这是另一类东西。
 * ⚠ `.is-reading` 的样式保留着没删：历史题组可能还在存储里，万一读到也不会裸样式。
 */
.emm-paper-task-kind.is-exam {
  background: color-mix(in srgb, #7c3aed 16%, var(--bg-secondary));
  color: #6d28d9;
}
.emm-paper-radios { display: flex; flex-wrap: wrap; gap: 8px; }
.emm-paper-radios.is-column { flex-direction: column; }
.emm-paper-radios label { display: flex; align-items: flex-start; gap: 8px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); color: var(--text-secondary); font-size: 13px; cursor: pointer; }
.emm-paper-radios label:hover { border-color: var(--eng-ink, var(--eng-color)); }
.emm-paper-radios label span { display: flex; flex-direction: column; gap: 2px; }
.emm-paper-radios label b { color: var(--text-primary); font-size: 13.5px; }
.emm-paper-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.emm-paper-actions svg { width: 16px; height: 16px; }
.emm-paper-note { margin: 0; color: var(--text-tertiary); font-size: 12px; line-height: 1.75; }
.emm-paper-side { display: flex; flex-direction: column; gap: 16px; }
.emm-paper-done { display: flex; flex-direction: column; gap: 12px; padding: 16px; border: 1px solid var(--rd-blue-strong, var(--eng-color)); border-radius: 10px; background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 7%, var(--bg-primary)); }
.emm-paper-done strong { color: var(--text-primary); font-size: 14px; }
.emm-paper-done p { margin: 5px 0 0; color: var(--text-secondary); font-size: 12.5px; line-height: 1.7; }
.emm-paper-done-sections { color: var(--text-tertiary); }
.emm-paper-warn { color: #b45309 !important; }
.emm-paper-done-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.emm-paper-wait { padding: 18px 0; text-align: center; }
.emm-paper-wait p { margin: 12px 0 4px; color: var(--text-primary); font-size: 14px; }
.emm-paper-wait small { color: var(--text-tertiary); font-size: 12px; }
.emm-paper-fail { padding: 14px; border: 1px solid #dc2626; border-radius: 9px; }
.emm-paper-fail strong { color: #dc2626; font-size: 13.5px; }
.emm-paper-fail p { margin: 6px 0 0; color: var(--text-secondary); font-size: 12.5px; line-height: 1.7; }
/* 打印用的隐藏 iframe：装一份打印页，点「一键打印」时同步打它。
   ⚠ 用「移出视口」而不是 display:none —— 有些浏览器不给 display:none 的
   iframe 渲染排版，打印出来会是空白。1px + 透明既不影响布局，也保证真的渲染。 */
.emm-paper-frame { position: fixed; right: 0; bottom: 0; width: 1px; height: 1px;
  border: 0; opacity: 0; pointer-events: none; }

@media (max-width: 1000px) {
  .emm-paper-layout { grid-template-columns: minmax(0, 1fr); }
}
.emm-paper-preset { margin: 0; padding: 10px 12px; border: 1px dashed var(--border); border-radius: 9px; color: var(--text-secondary); font-size: 12.5px; line-height: 1.7; }
/* ===== 打印出口：墨墨「某天背过的词」日报（2026-10-29） =====
   ⚠ 与上面的任务清单**刻意分开**：词源不同（墨墨学习记录 vs 生成台产物），
     而且这一条**会调模型**补释义 —— 视觉上要能一眼看出是另一类操作。 */
.emm-paper-daily { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.emm-paper-daily-day { display: flex; flex-direction: column; gap: 6px; flex: 1 1 200px; min-width: 0; }
.emm-paper-daily-day > span { color: var(--text-secondary); font-size: 12px; font-weight: 600; }
/* ⚠ select 的字体必须显式继承：浏览器默认给 13.3px 的系统字体，
   与旁边按钮的字号差一截，看起来像是没样式。 */
.emm-paper-daily select {
  width: 100%; padding: 10px 12px; box-sizing: border-box;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-primary); color: var(--text-primary);
  font: inherit; font-size: 14px; cursor: pointer;
}
.emm-paper-daily select:hover { border-color: var(--eng-ink, var(--eng-color)); }
/* 按钮与下拉框等高：默认按钮的内边距更大，不对齐会显得错位。 */
.emm-paper-daily .btn { flex: 0 0 auto; min-height: 42px; }
.emm-paper-daily .btn svg { width: 16px; height: 16px; }
@media (max-width: 560px) {
  /* 窄屏一行放不下「下拉框 + 按钮」：让按钮占满一行，别挤成两个小方块。 */
  .emm-paper-daily { flex-direction: column; align-items: stretch; }
  .emm-paper-daily .btn { width: 100%; }
}
.emm-link-btn { padding: 0; border: 0; background: transparent; color: var(--rd-blue-strong, var(--eng-color)); font: inherit; font-size: 12.5px; text-decoration: underline; cursor: pointer; }
.emm-link-btn:hover { color: var(--eng-ink, var(--eng-color)); }

/* ---------- Token 弹窗：字段标题行 + 「获取 Token」外链 ----------
   ⚠ 链接色必须走 `--eng-ink`：`--rd-blue-strong` 在深色下是 #2f5fbe，压在弹窗底
   #101113 上只有 3.15:1，低于 AA 的 4.5:1（实测）。--eng-ink 深色 #7aa8f8 /
   浅色 #1d4ed8 是英语模块专为「浅底小字」准备文字蓝，两边都达标。 */
.emm-field-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 7px; }
.emm-field-head label { margin-bottom: 0; }
.emm-token-link { display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px; border-radius: 6px; color: var(--eng-ink, var(--eng-color)); font-size: 12.5px; font-weight: 600; text-decoration: none; white-space: nowrap; }
.emm-token-link:hover { color: var(--eng-color); text-decoration: underline; }
.emm-token-link svg { width: 14px; height: 14px; }

/* ---------- 语境填空：模式切换 / 错词本分类 ---------- */
.emm-filter-label { color: var(--text-tertiary); font-size: 12px; font-weight: 600; }
/* 「已通过」标记：淡绿底 + 小字（11px，按 AA 要 4.5:1）。
   ⚠ --rd-green-strong(#15803d) 在**深浅两个主题里都是同一支深绿**，直接当文字色配它自己的
   14% 淡底，实测只有 4.15:1 —— 深色主题里更是几乎糊在底上。
   按项目惯例引入 ink 变量：深色用亮绿、浅色用更深一档的绿，两边都过 AA。 */
.emm-chip.is-passed {
  border-color: var(--rd-green-strong, #16a34a);
  background: color-mix(in srgb, var(--rd-green-strong, #16a34a) 14%, transparent);
  color: var(--emm-passed-ink, var(--rd-green-strong, #16a34a));
}
[data-theme="dark"] .emm-chip.is-passed { --emm-passed-ink: #4ade80; }
[data-theme="light"] .emm-chip.is-passed { --emm-passed-ink: #146c37; }
.emm-wrong-actions .emm-danger-link { margin-top: 0; }
.emm-wrong-list li.is-passed { border-left: 3px solid var(--rd-green-strong, #16a34a); }

/* ---------- 考查范围：错题日历 ----------
   有错题的日期按当天词数着色（深浅区分），没记录的是普通底色；
   悬停/聚焦显示详情（原生 title + aria-label）。悬停详情用 title 而不是自绘气泡，
   是为了零 JS、零定位问题，鼠标和读屏都能拿到同一份文字。 */

/* ---------- 生成台 ----------
   两栏按「先挑词，再生成，再看结果」的顺序摊开：
     左栏 = 自定义模型 + 题库（按日期）+ 进行中 + 质量检查
     右栏 = 选词
   ⚠ 为什么「选词」单独占右栏，而「进行中/质量检查」挪去左栏：
     实测面板高度 选词 1448px、模型 452px、题库 442px、质量检查 203px、进行中 102px。
     选词一个面板就比左栏所有内容加起来还高，所以它单独一栏、其余四个叠在另一栏，
     两栏高度才接近（约 1240 vs 1450）—— 否则必然有一栏底下空一大片。
     而「进行中 / 质量检查」讲的都是**左栏那个日期任务**的生成过程与结果，
     跟题库同侧本来就比跟选词同侧更顺。
   ⚠ 宽度给了右栏（选词）略大的一份：它里面的候选词表、理由标签、勾选预览表
     是这一页最宽的内容，挤窄了会折行折得很难看。
   窄屏（<=1100px）折成一列，用 `order` 把顺序摆回「模型 → 选词 → 题库 → 进行中 → 质量检查」*/
/* 主区 + 右侧进度栏。
   ⚠ 右侧栏是**窄**的那一列（进度是按批次折叠的短列表），所以比例是 1fr : 320px，
      不是「两栏等宽」—— 等宽会把主面板压得放不下一行题目。 */
.emm-gen-layout { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 16px; align-items: start; }
.emm-gen-main, .emm-gen-side, .emm-gen-rail { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.emm-gen-rail { position: sticky; top: 12px; }
.emm-gen-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; margin-bottom: 10px; }
.emm-gen-toolbar svg { width: 15px; height: 15px; }
.emm-gen-toolbar .btn { display: inline-flex; align-items: center; gap: 6px; }
.emm-gen-panel { display: flex; flex-direction: column; gap: 11px; }

/* ============================ 生成台 v2：双面板 / 选词小窗 / 批次进度 ============================
 * 以下是重写后的生成台样式。类名都以 `emm-gen-` 开头，与旧的 `emm-gen-*` 同名者
 * 取「后定义生效」—— 所以这里不在同一文件里重复定义已有类。
 */

/* ---- 醒目的两选一：语境填空 / 长难句 ---- */
.emm-gen-modes { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; }
.emm-gen-mode { display: flex; align-items: flex-start; gap: 12px; padding: 15px 16px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-primary); color: var(--text-secondary); font: inherit; text-align: left; cursor: pointer; transition: border-color .15s ease, background .15s ease; }
.emm-gen-mode:hover { border-color: var(--eng-ink, var(--eng-color)); }
.emm-gen-mode.is-active { border-color: var(--rd-blue-strong, var(--eng-color)); background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 8%, var(--bg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 35%, transparent); }
.emm-gen-mode.is-done .emm-gen-mode-stat { color: var(--rd-green-strong, #16a34a); }
.emm-gen-mode-icon { flex: 0 0 34px; display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; border-radius: 9px; background: color-mix(in srgb, var(--eng-ink, var(--eng-color)) 12%, transparent); color: var(--eng-ink, var(--eng-color)); }
.emm-gen-mode-icon svg { width: 19px; height: 19px; }
.emm-gen-mode-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.emm-gen-mode-text strong { color: var(--text-primary); font-size: 15px; }
.emm-gen-mode-text span { color: var(--text-tertiary); font-size: 12px; line-height: 1.6; }
.emm-gen-mode-stat { margin-left: auto; flex: 0 0 auto; color: var(--text-tertiary); font-size: 12px; white-space: nowrap; }

/* ---- 面板头 ---- */
.emm-gen-panel-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; }
.emm-gen-panel-head h2 { margin: 0; color: var(--text-primary); font-size: 16px; }
.emm-gen-panel-head p { margin: 6px 0 0; max-width: 74ch; color: var(--text-tertiary); font-size: 12.5px; line-height: 1.65; }
.emm-gen-panel-head code { padding: 1px 5px; border-radius: 4px; background: var(--bg-secondary); font-size: 12px; }
.emm-gen-panel { padding: 16px; border: 1px solid var(--border); border-radius: 11px; background: var(--bg-secondary); }

/* ---- 进度条 ---- */
.emm-gen-progress { display: flex; align-items: center; gap: 10px; }
.emm-gen-bar { display: block; flex: 1 1 auto; height: 7px; min-width: 60px; border-radius: 999px; background: color-mix(in srgb, var(--text-tertiary) 22%, transparent); overflow: hidden; }
.emm-gen-bar > i { display: block; height: 100%; border-radius: 999px; background: var(--rd-blue-strong, var(--eng-color)); transition: width .3s ease; }
.emm-gen-progress-label { flex: 0 0 auto; color: var(--text-secondary); font-size: 12.5px; font-variant-numeric: tabular-nums; }

/* ---- 统计格子 ---- */
.emm-gen-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 9px; }
.emm-gen-tile { display: flex; flex-direction: column; gap: 3px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); }
.emm-gen-tile strong { color: var(--text-primary); font-size: 18px; font-variant-numeric: tabular-nums; }
.emm-gen-tile span { color: var(--text-tertiary); font-size: 11.5px; }
.emm-gen-tile.is-ok strong { color: var(--rd-green-strong, #16a34a); }
.emm-gen-tile.is-warn strong { color: #d97706; }
.emm-gen-tile.is-bad strong { color: #dc2626; }

/* ---- 审查实时全流程（审查台边跑边显示） ----
 *
 * ⚠ 逐项列表**限高 + 可滚**：一次全库审查最多 60 项，全铺开会把下面的
 *   审查结果顶到屏幕外 —— 这正是用户先前抱怨产物区时的那类问题。 */
.emm-gen-live {
  display: flex; flex-direction: column; gap: 8px;
  margin: 10px 0; padding: 11px 12px;
  border: 1px solid var(--border); border-radius: 10px;
  background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 4%, var(--bg-primary));
}
.emm-gen-live-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.emm-gen-live-count { color: var(--text-primary); font-size: 13.5px; font-variant-numeric: tabular-nums; }
.emm-gen-live-bar { flex: 0 0 auto; }
.emm-gen-live-stage { margin: 0; }
.emm-gen-live-stage b { color: var(--text-primary); }
/* 「计数收尾中」那行说明：把「徽章说完成、计数还差一格」解释清楚。
 * 不加粗不抢眼 —— 它是解释，不是告警。 */
.emm-gen-live-trailing { margin: 0; color: #b45309; }
.emm-gen-live-trailing b { color: var(--text-primary); }

.emm-gen-live-items {
  display: flex; flex-direction: column; gap: 4px;
  max-height: 230px; overflow-y: auto;
  margin: 0; padding: 0; list-style: none;
}
.emm-gen-live-item {
  display: flex; align-items: baseline; gap: 8px;
  padding: 5px 8px; border-radius: 7px;
  border-left: 3px solid transparent;
  background: var(--bg-primary);
  font-size: 12px;
}
.emm-gen-live-item.is-ok { border-left-color: color-mix(in srgb, #16a34a 55%, transparent); }
.emm-gen-live-item.is-warn { border-left-color: color-mix(in srgb, #d97706 60%, transparent); }
.emm-gen-live-item.is-bad { border-left-color: color-mix(in srgb, #dc2626 60%, transparent); }
/* 序号等宽：否则一到两位数，右边缘就参差不齐 */
.emm-gen-live-no {
  flex: 0 0 auto; min-width: 20px; color: var(--text-tertiary);
  font-variant-numeric: tabular-nums; text-align: right;
}
.emm-gen-live-title { flex: 1 1 auto; min-width: 0; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.emm-gen-live-verdict { flex: 0 0 auto; color: var(--text-secondary); }
.emm-gen-live-item.is-warn .emm-gen-live-verdict { color: #b45309; }
.emm-gen-live-item.is-bad .emm-gen-live-verdict { color: #b91c1c; }
.emm-gen-live-meta { flex: 0 0 auto; color: var(--text-tertiary); font-variant-numeric: tabular-nums; }

/* ---- 重试的子进度 ----
 *
 * ⚠ 用户要求「重试失败任务不要切换监控数据，直接在原来的基础上更新」：
 *   主进度条停在**原记录**上（60/60 不动），重试到第几个由这条细条表示。
 *   做成更细、更浅的一条，免得两条同样粗细的进度条让人以为主进度在倒退。 */
.emm-gen-live-retry { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.emm-gen-live-retry > .emm-gen-hint { flex: 0 0 auto; }
.emm-gen-live-retry-bar { flex: 1 1 auto; height: 4px; }
.emm-gen-live-retry-bar > i { background: var(--rd-blue-strong, var(--eng-color)); opacity: .7; }

/* 深色 / 壁纸：用项目既有选择器（写成 body.is-dark 这类不存在的类名不会报错，只是永不命中） */
[data-theme="dark"] .emm-gen-live { background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 9%, var(--bg-primary)); }
[data-theme="dark"] .emm-gen-live-item { background: color-mix(in srgb, var(--bg-primary) 80%, #fff 6%); }
html.has-wallpaper .emm-gen-live { backdrop-filter: blur(8px); }

/* ---- 「实时流输出」小窗口 ----
 *
 * 显示模型此刻正在写什么（思考 / 正文分列）+ 实时速度。
 * ⚠ 两个 <pre> 都限高可滚，并靠 JS 自动滚到底部 —— 流是往下长的。 */
.emm-gen-live-stream-btn { margin-left: auto; padding: 3px 10px; font-size: 12px; }
/* 小窗：比选词窗窄得多，它只是一条「看模型写字」的监视器 */
.emm-gen-stream { width: min(720px, 92vw); max-height: 86vh; }
.emm-gen-stream .emm-window-body { display: flex; flex-direction: column; gap: 10px; }
.emm-gen-stream-pane { display: flex; flex-direction: column; gap: 4px; }
.emm-gen-stream-label { color: var(--text-tertiary); font-size: 11.5px; letter-spacing: .08em; }
.emm-gen-stream-out {
  margin: 0; padding: 9px 11px;
  max-height: 190px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-secondary);
  color: var(--text-primary);
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 11.5px; line-height: 1.5;
  white-space: pre-wrap; word-break: break-word;
}
/* 思考通道压暗：它是草稿，不该和正文抢注意力 */
.emm-gen-stream-out.is-think { color: var(--text-tertiary); font-style: italic; }
[data-theme="dark"] .emm-gen-stream-out { background: color-mix(in srgb, var(--bg-secondary) 70%, #000 30%); }
html.has-wallpaper .emm-gen-stream { backdrop-filter: blur(10px); }

/* ---- 按钮行 ---- */
.emm-gen-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.emm-gen-actions svg { width: 15px; height: 15px; }
.emm-gen-actions .btn { display: inline-flex; align-items: center; gap: 6px; }
.emm-gen-actions .btn:disabled { opacity: .5; cursor: not-allowed; }

/* ---- 表单 ---- */
.emm-gen-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px; }
.emm-gen-field { display: flex; flex-direction: column; gap: 5px; color: var(--text-secondary); font-size: 12px; }
.emm-gen-field--wide { grid-column: 1 / -1; }
.emm-gen-field input, .emm-gen-field select { padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-primary); color: var(--text-primary); font: inherit; font-size: 13px; }

/* ---- 复选框型字段（第 59 轮：专有名词屏蔽开关）----
 *
 * ⚠ `.emm-gen-field` 默认是 `flex-direction: column`，套在复选框上会把
 *   方块和文字排成上下两行、还撑满整个格子。这里改成横排。
 *
 * ⚠⚠ **第一版写成 `flex: 0 0 auto` 是错的**（实测截图抓到）：
 *   父容器是 `grid-template-columns: repeat(auto-fit, minmax(170px, 1fr))`，
 *   它的直接子项宽度由**网格**决定，`flex` 属性对网格子项**无效** ——
 *   于是这个字段仍然被分到 170px 宽的格子里，
 *   「屏蔽专有名词」被挤成「屏蔽专有命」+「词」两行。
 *
 *   ✅ 正确做法是用网格属性 `justify-self` / `width`：
 *     `grid-column: span 1` + `width: max-content` 让它按内容撑开，
 *     同时 `max-width: 100%` 兜住窄屏（否则长文案会溢出容器）。
 */
.emm-gen-field.emm-gen-toggle {
  /* ⚠ 网格子项要用 grid 属性，不能用 flex 的 flex-basis */
  width: max-content;
  max-width: 100%;
  grid-column: span 1;
  flex-direction: row;
  align-items: center;
  gap: 7px;
  align-self: end;
  padding-bottom: 8px;
  cursor: pointer;
  /** ⚠ 文案不许折行：折成两行会让复选框和文字错位，视觉上很乱。 */
  white-space: nowrap;
}
.emm-gen-field.emm-gen-toggle input[type="checkbox"] {
  /* ⚠ 覆盖上面那条 `.emm-gen-field input` 的 padding/border（那是给文本框的） */
  padding: 0;
  border: none;
  border-radius: 0;
  background: none;
  width: 15px;
  height: 15px;
  margin: 0;
  accent-color: var(--accent, #4f8cff);
  cursor: pointer;
}
.emm-gen-toggle-hint { color: var(--text-tertiary); font-size: 11px; font-style: normal; white-space: nowrap; }

/* ---- 语法勾选 ----
 *
 * 视觉目标（用户要求「优化语法选择的视觉效果」）：这是一张 8 组 × 40+ 项的清单，
 * 原先是清一色裸 checkbox，扫不出「哪些练过、哪些还没碰」。
 * 现在每一项是一个**胶囊**，靠三件事表达状态，不靠颜色堆砌：
 *   1. 左侧色条 = 练过（`--eng-color`）/ 未练（透明，视觉上「更轻」）；
 *   2. 右上角数字胶囊 = 历史生成批次数（`未练` 时压暗，不抢注意力）；
 *   3. 勾选时整块高亮 + 勾选框变主题色，一眼看出这次要练哪几个。
 * 排序（练过的在前）在 JS 里做，这里只管样子。
 */
.emm-gen-grammar { margin: 0; padding: 12px 14px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); }
.emm-gen-grammar legend { padding: 0 6px; color: var(--text-secondary); font-size: 12px; }
/* 标题右侧的总进度：一眼知道整张清单碰过多少 */
.emm-gen-grammar-progress { margin-left: 6px; padding: 1px 7px; border-radius: 999px; background: var(--bg-secondary); color: var(--text-tertiary); font-size: 11px; }
.emm-gen-grammar-group { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 8px; }
.emm-gen-grammar-label { flex: 0 0 76px; padding-top: 4px; color: var(--text-tertiary); font-size: 12px; }
/* 分组小计「已练/总数」 */
.emm-gen-grammar-group-count { display: block; margin-top: 1px; color: var(--text-tertiary); font-size: 10.5px; font-style: normal; opacity: .75; }
.emm-gen-grammar-items { display: flex; flex: 1; flex-wrap: wrap; gap: 6px; }

.emm-gen-check {
  position: relative; display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 8px 4px 9px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-primary); color: var(--text-secondary);
  font-size: 12.5px; line-height: 1.35; cursor: pointer;
  transition: border-color .12s, background-color .12s, color .12s;
}
.emm-gen-check:hover { border-color: var(--eng-color); color: var(--text-primary); }
.emm-gen-check input { margin: 0; accent-color: var(--eng-color); }

/* 练过的：左侧一道主题色条，底色略实，视觉重量更高 */
.emm-gen-check.is-used { border-left: 3px solid var(--eng-color); }
/* 未练的：虚化边框 + 压暗文字，明显「更轻」，让练过的先跳出来 */
.emm-gen-check.is-fresh { border-style: dashed; color: var(--text-tertiary); }

/* 已勾选：整块高亮（同时盖过 is-used / is-fresh 的底色） */
.emm-gen-check.is-on {
  border-color: var(--eng-color);
  background: color-mix(in srgb, var(--eng-color) 12%, var(--bg-primary));
  color: var(--text-primary); font-weight: 600;
}
.emm-gen-check.is-on.is-used { border-left-color: var(--eng-color); }

/* 次数胶囊。⚠ 用等宽数字，否则一列数字宽度不齐、右边缘会参差 */
.emm-gen-grammar-count {
  min-width: 18px; padding: 1px 5px; border-radius: 999px;
  background: color-mix(in srgb, var(--eng-color) 14%, var(--bg-secondary));
  color: var(--eng-color); font-size: 10.5px; font-weight: 600;
  text-align: center; font-variant-numeric: tabular-nums;
}
/* 「未练」不抢注意力：压成中性灰底 */
.emm-gen-grammar-count.is-zero { background: var(--bg-secondary); color: var(--text-tertiary); font-weight: 400; }

/* 深色 / 壁纸下 `color-mix` 的底色要更实一点，否则勾选高亮看不出来。
 * ⚠ 选择器用**项目既有约定**：深色是 `[data-theme="dark"]`（不是 body.is-dark），
 *   壁纸是 `html.has-wallpaper`（写 `background-image` 时会被壁纸盖住）。
 *   两者都不带 `background` 简写，只改 `background-color`，避免清掉壁纸。 */
[data-theme="dark"] .emm-gen-check.is-on,
html.has-wallpaper .emm-gen-check.is-on { background-color: color-mix(in srgb, var(--eng-color) 22%, var(--bg-primary)); }
/* 壁纸模式下卡片是半透明的，实色胶囊会像补丁 —— 跟着做成玻璃 */
html.has-wallpaper .emm-gen-check,
html.has-wallpaper .emm-gen-grammar { backdrop-filter: blur(8px); background-color: color-mix(in srgb, var(--bg-primary) 72%, transparent); }

/* ---- 词条列表 / 筹码 ---- */
.emm-gen-subhead { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-top: 4px; }
.emm-gen-subhead h3 { margin: 0; color: var(--text-primary); font-size: 13.5px; }
.emm-gen-subhead span { color: var(--text-tertiary); font-size: 12px; }

/* 「产物」区：标题 + 组/句数 + 折叠按钮。
 * ⚠ 比通用 subhead 多一个按钮，`space-between` 会把计数挤到中间 —— 改成
 *   「标题占满、计数与按钮靠右」，三个元素才排得整齐。 */
.emm-gen-subhead--products { align-items: center; }
.emm-gen-subhead--products h3 { flex: 1 1 auto; min-width: 0; }
.emm-gen-subhead--products > span { flex: 0 0 auto; }
.emm-gen-products-toggle { flex: 0 0 auto; padding: 2px 9px; font-size: 12px; }
/* 折叠区与上方标题贴紧：这里是同一块内容的两半，不该有段落间距 */
.emm-gen-products { margin-top: 8px; }
.emm-gen-products[hidden] { display: none; }
.emm-gen-words { display: flex; flex-direction: column; gap: 0; margin: 0; padding: 0; list-style: none; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); overflow: hidden; }
.emm-gen-word { display: flex; align-items: center; gap: 10px; padding: 8px 11px; border-bottom: 1px solid var(--border); }
.emm-gen-word:last-child { border-bottom: 0; }
.emm-gen-word-main { display: flex; align-items: baseline; gap: 9px; flex: 1 1 auto; min-width: 0; }
.emm-gen-word-main strong { color: var(--text-primary); font-size: 13.5px; }
.emm-gen-word-main span { color: var(--text-tertiary); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.emm-gen-word-side { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.emm-gen-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.emm-gen-chip { padding: 2px 8px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg-secondary); color: var(--text-secondary); font-size: 12px; }
.emm-gen-badge { padding: 2px 7px; border-radius: 999px; background: color-mix(in srgb, var(--text-tertiary) 16%, transparent); color: var(--text-secondary); font-size: 11px; white-space: nowrap; }
.emm-gen-badge.is-ok { background: color-mix(in srgb, #16a34a 16%, transparent); color: #15803d; }
.emm-gen-badge.is-warn { background: color-mix(in srgb, #d97706 18%, transparent); color: #b45309; }
.emm-gen-badge.is-bad { background: color-mix(in srgb, #dc2626 15%, transparent); color: #b91c1c; }
.emm-gen-badge.is-live { background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 16%, transparent); color: var(--rd-blue-strong, var(--eng-color)); }
.emm-gen-empty, .emm-gen-muted { margin: 0; color: var(--text-tertiary); font-size: 12.5px; line-height: 1.65; }
.emm-gen-note { margin: 0; padding: 9px 11px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-primary); color: var(--text-secondary); font-size: 12.5px; line-height: 1.6; }

/* ---- 批次列表 ---- */
.emm-gen-tasks { display: flex; flex-direction: column; gap: 7px; margin: 0; padding: 0; list-style: none; }
.emm-gen-task { display: flex; align-items: center; gap: 9px; padding: 9px 11px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); }
.emm-gen-task.is-active { border-color: var(--rd-blue-strong, var(--eng-color)); background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 7%, var(--bg-primary)); }
.emm-gen-task-pick { display: flex; flex-direction: column; gap: 5px; flex: 1 1 auto; min-width: 0; padding: 0; border: 0; background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.emm-gen-task-pick strong { color: var(--text-primary); font-size: 13.5px; }
.emm-gen-task-pick span { color: var(--text-tertiary); font-size: 11.5px; }

/* 批次上「当时勾选的语法」标签。
 * ⚠ 必须写在 `.emm-gen-task-pick span` **之后**：那条规则会把所有后代 span
 *   染成 tertiary 小字，标签需要自己的字号与颜色，靠顺序+更具体的选择器盖回来。 */
.emm-gen-grammar-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.emm-gen-task-pick .emm-gen-grammar-tags .emm-gen-grammar-tag {
  padding: 1px 6px; border: 1px solid color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 30%, transparent);
  border-radius: 5px; background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 9%, transparent);
  color: var(--rd-blue-strong, var(--eng-color)); font-size: 10.5px; line-height: 1.6; white-space: nowrap;
}
.emm-gen-task-pick .emm-gen-grammar-tags .emm-gen-grammar-tag.is-more {
  border-style: dashed; background: transparent; color: var(--text-tertiary);
}
/* 当前批次高亮时标签跟着提亮，否则在蓝底上糊成一片 */
.emm-gen-task.is-active .emm-gen-grammar-tag { background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 16%, transparent); }

/* 批次行上的「重试 N 项」按钮。
 * ⚠ 不能让它被 flex 压扁（默认 `flex-shrink: 1` 会把「重试 3 项」挤成两行），
 *   也不要撑开——它是次要动作，视觉上要让位给批次名。 */
.emm-gen-task-retry { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; padding: 3px 9px; font-size: 11.5px; }
.emm-gen-task-retry svg { width: 13px; height: 13px; }
/**
 * **「补漏词」按钮**（第 53 轮，用户要求「无法凑在一起的选词，单独生成短句」）。
 *
 * ⚠ 与「重试」并排出现，但**语义不同**：
 *   · 重试 = 有词组没出句子（失败态）；
 *   · 补漏词 = 句子都出了，但有词没用上（正常态的尾巴）。
 *   ⚠ 所以颜色要能区分：用**中性偏冷**的描边，不要和重试的强调色撞；
 *     它是个「收尾」动作，不该比「重试」更抢眼。
 */
.emm-gen-task-fill { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; padding: 3px 9px; font-size: 11.5px; border-color: color-mix(in srgb, var(--eng-color, var(--rd-blue-strong)) 45%, var(--border)); color: var(--text-secondary); }
.emm-gen-task-fill:hover { color: var(--text-primary); border-color: var(--eng-color, var(--rd-blue-strong)); }
.emm-gen-task-fill svg { width: 13px; height: 13px; }

/* 批次行下方的**失败原因**。
 * ⚠⚠ 必须 `flex-basis: 100%` 让它**独占一行**：`.emm-gen-task` 是 flex 行，
 *   不换行的话这段文字会挤在「重试」与「删除」之间，把整行撑得很难看，
 *   而失败原因往往是一整句（「模型返回的分组不合规（每组至少要 2 个词…）」）。
 * ⚠ `flex-wrap: wrap` 加在父级上，否则 `flex-basis: 100%` 不会换行。 */
.emm-gen-task { flex-wrap: wrap; }
.emm-gen-task-error {
  flex: 1 0 100%; margin: 2px 0 0; padding: 5px 8px;
  border-radius: 6px; background: color-mix(in srgb, var(--danger, #d9534f) 10%, transparent);
  color: var(--danger, #d9534f); font-size: 11.5px; line-height: 1.5;
  /* 长原因截断成两行，完整内容在 title 里（批次行不该被一段报错撑成一大块） */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* ---- 词组分组 ---- */
.emm-gen-groups { display: flex; flex-direction: column; gap: 9px; margin: 0; padding: 0; list-style: none; }
.emm-gen-groups > li { display: flex; align-items: flex-start; gap: 10px; padding: 9px 11px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); }
.emm-gen-group-no { flex: 0 0 22px; display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%; background: color-mix(in srgb, var(--eng-ink, var(--eng-color)) 14%, transparent); color: var(--eng-ink, var(--eng-color)); font-size: 11.5px; }
.emm-gen-groups--wide { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 10px; }

/* ---- 右侧进度栏：按批次折叠 ---- */
.emm-gen-rail { padding: 14px; border: 1px solid var(--border); border-radius: 11px; background: var(--bg-secondary); }
.emm-gen-rail-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.emm-gen-rail-head h2 { margin: 0; color: var(--text-primary); font-size: 14px; }
.emm-gen-batches { display: flex; flex-direction: column; gap: 9px; margin: 0; padding: 0; list-style: none; }
.emm-gen-batch { display: flex; flex-direction: column; gap: 6px; padding: 10px 11px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); }
.emm-gen-batch.is-live { border-color: var(--rd-blue-strong, var(--eng-color)); }
.emm-gen-batch-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.emm-gen-batch-head strong { color: var(--text-primary); font-size: 12.5px; }
.emm-gen-batch-meta, .emm-gen-batch-now { margin: 0; color: var(--text-tertiary); font-size: 11.5px; line-height: 1.55; }
.emm-gen-batch-now { color: var(--rd-blue-strong, var(--eng-color)); }
/**
 * token 消耗 / 实时吞吐量（用户要求进度里显示）。
 * ⚠ 用等宽数字（`tabular-nums`）：这些数字每秒都在变，
 *   比例字体下宽度会跳，整行跟着抖，盯着看很晕。
 * ⚠ 单独一行而不是塞进 meta 里：meta 那一行已经很长（进度/失败/档位/语法），
 *   再把两个每秒变化的数字混进去，读的时候找不到重点。
 */
.emm-gen-batch-metrics {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin: 0;
  color: var(--text-secondary);
  font-size: 11.5px;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
}
.emm-gen-batch.is-live .emm-gen-batch-metrics { color: var(--rd-blue-strong, var(--eng-color)); }

/**
 * 批次卡片可点（用户要求：去掉页面里那份「词库生成进度」列表，
 * 改成点右侧进度栏的卡片再在窗口里浏览全部）。
 *
 * ⚠ 卡片外壳仍是 `<li>`，可点的内层是 `<button>`：
 *   `<button>` 内部不能嵌 `<button>`（HTML 非法，浏览器会把内层挪出去），
 *   而卡片里将来可能还要放操作按钮。所以把「可点区域」做成一整块内层按钮。
 * ⚠ 必须显式 reset 按钮的默认样式（字体/背景/内边距/对齐），
 *   否则卡片会长得像一个表单按钮，和其余卡片不是一套语言。
 */
.emm-gen-batch > .emm-gen-batch-inner {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
  margin: 0;
  padding: 10px 11px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--bg-primary);
  color: inherit;
  font: inherit;
  text-align: left;
}
/* 不可点时外壳自己撑样式（以前的结构），保持视觉一致。 */
.emm-gen-batch:not(.is-clickable) { padding: 0; border: 0; background: none; }
.emm-gen-batch.is-clickable > .emm-gen-batch-inner { cursor: pointer; }
.emm-gen-batch.is-clickable > .emm-gen-batch-inner:hover {
  border-color: var(--rd-blue-strong, var(--eng-color));
  background: color-mix(in srgb, var(--eng-color) 6%, var(--bg-primary));
}
.emm-gen-batch.is-clickable > .emm-gen-batch-inner:focus-visible {
  outline: 2px solid var(--rd-blue-strong, var(--eng-color));
  outline-offset: 1px;
}
/** 「点开浏览全部明细」那一行：只在可点卡片上出现。 */
.emm-gen-batch-more {
  display: flex;
  align-items: center;
  gap: 5px;
  margin: 0;
  color: var(--rd-blue-strong, var(--eng-color));
  font-size: 11px;
}
.emm-gen-batch-more svg { width: 12px; height: 12px; }

/**
 * 失败词的原因那一行。
 * ⚠ 必须显示出来：只标一个「失败」徽章，用户不知道是模型超时、
 *   还是题目不合规，也就无法判断「重试」有没有意义。
 */
.emm-gen-word-error {
  display: block;
  color: #b91c1c;
  font-size: 11px;
  line-height: 1.5;
  word-break: break-word;
}
[data-theme="dark"] .emm-gen-word-error { color: #fca5a5; }

/* ---- 审查结果 ---- */
.emm-gen-issues { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; list-style: none; }
.emm-gen-issues > li { padding: 9px 11px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); }
.emm-gen-issues > li > strong { display: block; margin-bottom: 5px; color: var(--text-primary); font-size: 13px; }
.emm-gen-issues ul { margin: 0; padding-left: 18px; color: var(--text-secondary); font-size: 12.5px; line-height: 1.65; }
.emm-gen-issue-fail { margin: 0; color: #b45309; font-size: 12.5px; }

/* ---- 段落解析（第二步产物） ---- */
.emm-gen-segments { margin: 6px 0 0; padding-left: 20px; color: var(--text-secondary); font-size: 12.5px; line-height: 1.75; }

/* ---- 短句记词（micro）的产物 ----
   ⚠ 不发明新的颜色体系：句长徽章复用 `.emm-gen-badge` 的色板，
     超长提示用与别处一致的告警橙（`#d97706` 那一支，见上方 `.emm-gen-badge.is-warn`）。
   这三条只补「这条线独有的两处信息」：句长、以及这个词在这句里的用法。 */
.emm-micro-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 7px 0 0; }
/* 句长徽章：等宽数字，一列下来右边缘才齐（与语法次数胶囊同一个理由）。 */
.emm-micro-length {
  padding: 2px 7px; border-radius: 999px;
  background: var(--bg-secondary); color: var(--text-tertiary);
  font-size: 11px; white-space: nowrap; font-variant-numeric: tabular-nums;
}
/* ⚠ 超上限要**一眼看到**：这条线的价值就是「短」，超长的句子服务端不会丢掉，
   所以界面必须自己标出来，否则它混在正常句子里看不出来。 */
.emm-micro-length.is-over {
  background: color-mix(in srgb, #d97706 18%, transparent);
  color: #b45309; font-weight: 600;
}
/* 用法提示：本条线特有的一行（长难句没有这个字段）。 */
.emm-micro-usage {
  margin: 6px 0 0; padding-left: 9px;
  border-left: 2px solid var(--border);
  color: var(--text-secondary); font-size: 12.5px; line-height: 1.7;
}
.emm-micro-usage b { margin-right: 5px; color: var(--text-tertiary); font-weight: 500; }
/* 超长的那一条整块加个左边框，滚过去时能立刻定位到是哪几句。 */
.emm-micro-line.is-over { border-left: 3px solid #d97706; padding-left: 10px; }

/* ---- 页签 ---- */
.emm-gen-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.emm-gen-tab { padding: 5px 12px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg-primary); color: var(--text-secondary); font: inherit; font-size: 12.5px; cursor: pointer; }
.emm-gen-tab.is-active { border-color: var(--rd-blue-strong, var(--eng-color)); color: var(--rd-blue-strong, var(--eng-color)); }

/* ---- 选词小窗 ---- */
.emm-gen-select { width: min(820px, 100%); }
.emm-gen-select-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.emm-gen-select-row .emm-gen-field { flex: 0 0 190px; }
.emm-gen-select-result { margin-top: 14px; }
/* 自定义词输入框：整行铺开，等宽字体便于核对拼写（用户多半是照抄单词表）。 */
.emm-gen-custom-input { display: block; margin-bottom: 12px; }
.emm-gen-custom-input textarea {
  width: 100%; box-sizing: border-box; resize: vertical;
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-primary); color: var(--text-primary);
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 13px; line-height: 1.7;
}
.emm-gen-custom-input textarea:disabled { opacity: .6; }
/* 「没认出来」那一块：用橙色系，与「认出来的」视觉上分开但不刺眼。 */
.emm-gen-custom-rejected { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--border); }
.emm-gen-custom-rejected .emm-gen-word strong { color: #b45309; }
.emm-gen-select-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex: 0 0 auto; padding: 13px 20px; border-top: 1px solid var(--border); background: var(--bg-secondary); }
.emm-gen-select-foot .emm-gen-hint { flex: 1 1 auto; }
.emm-gen-picked { min-height: 34px; padding: 7px 10px; border: 1px dashed var(--border); border-radius: 8px; background: var(--bg-primary); }
.emm-gen-hint { margin: 0; color: var(--text-tertiary); font-size: 12px; line-height: 1.65; }
.emm-gen-hint b.is-error { color: #dc2626; }
.emm-gen-hint b.is-warning { color: #d97706; }
.emm-gen-hint.is-ok { color: var(--rd-green-strong, #16a34a); }
/**
 * 警告条：用于「没配复核模型就不能审查」这类**会让功能不可用**的前置条件。
 * ⚠ 必须比 hint 显眼：hint 是浅灰的小字，用户会直接跳过；
 *   而「点了按钮没反应」的原因恰恰写在这里，看不见就会以为功能坏了。
 */
.emm-gen-warn {
  margin: 0;
  padding: 9px 12px;
  border: 1px solid #fcd34d;
  border-left: 3px solid #d97706;
  border-radius: 8px;
  background: #fffbeb;
  color: #92400e;
  font-size: 12.5px;
  line-height: 1.7;
}
.emm-gen-warn b { color: #b45309; }
[data-theme="dark"] .emm-gen-warn { border-color: #78350f; border-left-color: #d97706; background: #2a1f0a; color: #fcd34d; }
[data-theme="dark"] .emm-gen-warn b { color: #fbbf24; }

/**
 * 「测试连通」的结果块：显示在模型表单**下方**（用户要求「在测试界面下方
 * 直接显示首字延迟、吞吐量等数字」）。
 * ⚠ 和 `.emm-gen-warn` 一样要显眼：toast 几秒就消失，而用户要拿这些数字
 *   对比不同模型/不同时段的速度，所以必须留在页面上。
 * 复用 `.emm-gen-stats` 的统计块排版，视觉与全库进度一览一致。
 */
.emm-gen-testout {
  margin-top: 11px;
  padding: 11px 12px;
  border: 1px solid color-mix(in srgb, var(--eng-color) 30%, transparent);
  border-radius: 9px;
  background: color-mix(in srgb, var(--eng-color) 6%, transparent);
}
.emm-gen-testout-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 9px; }
.emm-gen-testout .emm-gen-hint { margin: 8px 0 0; }
[data-theme="dark"] .emm-gen-testout {
  border-color: color-mix(in srgb, var(--eng-color) 38%, transparent);
  background: color-mix(in srgb, var(--eng-color) 10%, transparent);
}

/**
 * 难度档位选择器。
 * ⚠ 三档横排，窄屏自动折行 —— 用 grid auto-fit 而不是固定 3 列，
 *   否则 320px 宽时三张卡会挤成读不出字的一条。
 */
.emm-gen-tier { display: flex; flex-direction: column; gap: 7px; }
.emm-gen-tier-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 6px; }
.emm-gen-tier-head > span { color: var(--text-primary); font-size: 13px; font-weight: 600; }
.emm-gen-tier-head > small { color: var(--text-tertiary); font-size: 11.5px; }
.emm-gen-tier-opts { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px; }
.emm-gen-tier-btn { display: flex; flex-direction: column; gap: 3px; padding: 9px 11px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); color: var(--text-secondary); font: inherit; text-align: left; cursor: pointer; }
.emm-gen-tier-btn:hover { border-color: var(--eng-ink, var(--eng-color)); }
.emm-gen-tier-btn.is-active { border-color: var(--rd-blue-strong, var(--eng-color)); background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 12%, var(--bg-primary)); }
.emm-gen-tier-btn strong { color: var(--text-primary); font-size: 13px; }
.emm-gen-tier-btn small { color: var(--text-tertiary); font-size: 11px; line-height: 1.5; }

/* 高考范围复核：面板 + 越界标记 */
.emm-gen-scope { border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); padding: 9px 11px; }
.emm-gen-scope > summary { color: var(--text-secondary); font-size: 12.5px; cursor: pointer; }
.emm-gen-scope > * + * { margin-top: 8px; }
.emm-gen-scope-list { display: flex; flex-direction: column; gap: 7px; margin: 0; padding: 0; list-style: none; }
.emm-gen-scope-list > li { padding: 8px 10px; border: 1px solid var(--border); border-left: 3px solid #d97706; border-radius: 8px; background: var(--bg-secondary, var(--bg-primary)); font-size: 12px; }
.emm-gen-scope-list > li > strong { color: var(--text-primary); }
.emm-gen-scope-list > li > small { color: var(--text-tertiary); margin-left: 6px; }
.emm-gen-scope-list ul { margin: 5px 0 0; padding-left: 16px; color: var(--text-secondary); }
.emm-gen-scope-list ul li { margin-top: 3px; line-height: 1.6; }
.emm-chip.is-scope { border-color: #d97706; color: #d97706; }
/* 结构健康度（读不通）与范围提示（超纲）是两类问题，颜色要分得开：
 * 前者是「句子本身要改」，后者是「用词越界」，混成一个颜色用户分不清该先看哪个。 */
.emm-chip.is-structure { border-color: #dc2626; color: #dc2626; }
.emm-gen-scope-note { display: block; margin-top: 3px; color: var(--text-tertiary); font-size: 11.5px; line-height: 1.55; }

/* 模型设置：生成 / 复核两个标签页 */
.emm-gen-tabs { display: flex; gap: 6px; }
.emm-gen-tab { padding: 7px 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-primary); color: var(--text-secondary); font: inherit; font-size: 12.5px; cursor: pointer; }
.emm-gen-tab:hover { border-color: var(--eng-ink, var(--eng-color)); }
.emm-gen-tab.is-active { border-color: var(--rd-blue-strong, var(--eng-color)); background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 12%, var(--bg-primary)); color: var(--text-primary); font-weight: 600; }
.emm-gen-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; }
.emm-gen-form > label, .emm-gen-form-row > label { display: flex; flex-direction: column; gap: 5px; color: var(--text-secondary); font-size: 12px; }
.emm-gen-form input, .emm-gen-form select { width: 100%; padding: 8px 10px; box-sizing: border-box; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-primary); color: var(--text-primary); font: inherit; font-size: 13px; }
.emm-gen-form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.emm-gen-form-actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.emm-gen-form-actions .emm-gen-check-deep { display: inline-flex; align-items: center; gap: 6px; color: var(--text-secondary); font-size: 12.5px; }

/* 任务列表：一天一个按钮 */
.emm-gen-taskbar { display: flex; flex-wrap: wrap; gap: 8px; }

/**
 * 模型预设：多套配置 + 备注，点卡片即切换。
 *
 * ⚠ 卡片用 `display: grid` 而不是 `flex-direction: column`：备注可能折成多行，
 *   列布局下每条会被交叉轴 stretch 拉成整行宽（同一个坑在 `.emm-gen-score`
 *   上踩过 —— 徽标被拉成一根 370px 的进度条）。这里用 grid 明确分行。
 */
.emm-gen-presets { display: flex; flex-direction: column; gap: 9px; padding: 11px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-primary); }
.emm-gen-presets-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.emm-gen-presets-head strong { font-size: 13px; color: var(--text-primary); }
.emm-gen-presets-head .emm-gen-hint { flex: 1 1 200px; min-width: 0; }
.emm-gen-preset-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px; margin: 0; padding: 0; list-style: none; }
.emm-gen-preset { position: relative; display: flex; align-items: stretch; gap: 4px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-secondary); overflow: hidden; }
.emm-gen-preset.is-active { border-color: var(--rd-blue-strong, var(--eng-color)); background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 10%, var(--bg-secondary)); }
/* 左侧主题色条标「使用中」：只靠边框颜色在小屏上不够醒目 */
.emm-gen-preset.is-active::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--rd-blue-strong, var(--eng-color)); }
.emm-gen-preset-pick { flex: 1 1 auto; min-width: 0; display: grid; gap: 3px; padding: 9px 10px; border: 0; background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.emm-gen-preset-pick:disabled { opacity: .55; cursor: not-allowed; }
.emm-gen-preset-pick:focus-visible { outline: 2px solid var(--rd-blue-strong, var(--eng-color)); outline-offset: -2px; }
.emm-gen-preset-name { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; color: var(--text-primary); font-size: 13px; font-weight: 600; }
.emm-gen-preset-on { padding: 1px 6px; border-radius: 999px; background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 18%, transparent); color: var(--rd-blue-strong, var(--eng-color)); font-size: 10.5px; font-weight: 600; }
.emm-gen-preset-meta { color: var(--text-tertiary); font-size: 11.5px; overflow-wrap: anywhere; }
.emm-gen-preset-note { color: var(--text-secondary); font-size: 11.5px; line-height: 1.5; overflow-wrap: anywhere; }
.emm-gen-preset-flags { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 2px; }
.emm-gen-preset-ops { display: flex; flex-direction: column; justify-content: center; gap: 4px; padding: 6px 6px 6px 0; }
.emm-gen-preset-ops .emm-icon-btn { width: 26px; height: 26px; flex: 0 0 26px; border-radius: 7px; }
.emm-gen-preset-ops .emm-icon-btn svg { width: 14px; height: 14px; }
.emm-gen-preset-ops .emm-icon-btn.is-danger:hover { border-color: #dc2626; color: #dc2626; }
.emm-gen-preset-empty { grid-column: 1 / -1; padding: 10px; border: 1px dashed var(--border); border-radius: 9px; color: var(--text-tertiary); font-size: 12px; line-height: 1.6; }
.emm-gen-presets-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.emm-gen-presets-actions .btn { display: inline-flex; align-items: center; gap: 6px; }
.emm-gen-preset-editor { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; padding: 10px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-secondary); }
.emm-gen-preset-editor .emm-gen-field { display: flex; flex-direction: column; gap: 5px; color: var(--text-secondary); font-size: 12px; }
.emm-gen-preset-editor .emm-gen-field--wide { grid-column: 1 / -1; }
.emm-gen-preset-editor input { width: 100%; padding: 8px 10px; box-sizing: border-box; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-primary); color: var(--text-primary); font: inherit; font-size: 13px; }
.emm-gen-preset-editor .emm-gen-actions { grid-column: 1 / -1; }

/**
 * 日期选择器：显式显示「生成到哪一天」。
 * ⚠ 必须有它：日期原先只能从**已有任务**的按钮里选，全新安装时一个按钮都没有，
 *   既看不出要生成到哪天、也无法指定（配合「先选一个日期」的前置检查就是死锁）。
 */
.emm-gen-daypick { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px; padding: 9px 11px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); }
.emm-gen-daypick > label { display: flex; flex-direction: column; gap: 5px; color: var(--text-secondary); font-size: 12px; }
.emm-gen-daypick input { padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-primary); color: var(--text-primary); font: inherit; font-size: 13px; }
.emm-gen-daypick-note { flex: 1 1 180px; color: var(--text-tertiary); font-size: 11.5px; line-height: 1.6; }
.emm-gen-daypick-note b { color: var(--text-primary); }
.emm-gen-days { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 8px; }
.emm-gen-day { display: flex; flex-direction: column; gap: 3px; padding: 10px 11px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); color: var(--text-secondary); font: inherit; text-align: left; cursor: pointer; }
.emm-gen-day:hover { border-color: var(--eng-ink, var(--eng-color)); }
.emm-gen-day.is-active { border-color: var(--rd-blue-strong, var(--eng-color)); background: color-mix(in srgb, var(--rd-blue-strong, var(--eng-color)) 10%, var(--bg-primary)); }
.emm-gen-day strong { color: var(--text-primary); font-size: 13px; }
.emm-gen-day span, .emm-gen-day small { color: var(--text-tertiary); font-size: 11.5px; }
.emm-gen-day em { color: #d97706; font-size: 11.5px; font-style: normal; }

.emm-gen-detail { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.emm-gen-detail > header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.emm-gen-detail h4 { margin: 0; color: var(--text-primary); font-size: 14px; }
.emm-gen-detail-actions { display: flex; flex-wrap: wrap; gap: 6px; }

.emm-gen-words { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; list-style: none; }
.emm-gen-words li { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 10px; border: 1px solid var(--border); border-left-width: 3px; border-radius: 8px; background: var(--bg-primary); }
.emm-gen-words li.is-ready { border-left-color: #16a34a; }
.emm-gen-words li.is-failed { border-left-color: #dc2626; }
.emm-gen-words li.is-pending { border-left-color: var(--border); }
.emm-gen-words li.is-selected { border-left-color: #d97706; }
/* 候选词：左侧色条表示「有遗忘信号」，与任务里的状态色区分开。 */
.emm-gen-words li.is-pick { border-left-color: var(--eng-ink, var(--eng-color)); }
.emm-gen-word-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.emm-gen-word-main strong { color: var(--text-primary); font-size: 13px; }
.emm-gen-word-main span { color: var(--text-secondary); font-size: 12px; }
.emm-gen-word-main small { color: var(--text-tertiary); font-size: 11px; }

/* ---- 选词面板 ---- */

/**
 * 选词的主操作行。
 * ⚠ 它必须排在筛选条件**前面**：条件是可选的，默认收起，
 *   直接点这里就是「遗忘从高到低随机选 N 个」。
 */
.emm-gen-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.emm-gen-actions-hint { flex: 1 1 200px; min-width: 0; }

/* 筛选条件：默认折叠，展开时才占版面。 */
.emm-gen-filters-box { border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); }
.emm-gen-filters-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; width: 100%; padding: 9px 11px; border: 0; background: none; color: var(--text-secondary); font: inherit; font-size: 12.5px; text-align: left; cursor: pointer; }
.emm-gen-filters-head:hover { color: var(--text-primary); }
.emm-gen-filters-head b.is-warning { color: #d97706; }
.emm-gen-filters-caret { margin-left: auto; color: var(--text-tertiary); font-size: 11.5px; }
.emm-gen-filters-box .emm-gen-filters { padding: 0 11px 11px; }

.emm-gen-filters { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; }
.emm-gen-filters > label, .emm-gen-filters .emm-gen-form-row > label { display: flex; flex-direction: column; gap: 5px; color: var(--text-secondary); font-size: 12px; }
.emm-gen-filters input, .emm-gen-filters select { width: 100%; padding: 8px 10px; box-sizing: border-box; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-primary); color: var(--text-primary); font: inherit; font-size: 13px; }
.emm-gen-filters .emm-gen-form-actions { grid-column: 1 / -1; }
.emm-gen-filters .emm-gen-hint { grid-column: 1 / -1; }

/* 忘记频率分：醒目但不能抢走词本身的位置。
   ⚠ `align-self: flex-start` 是必需的：父级 `.emm-gen-word-main` 是
     `display: flex; flex-direction: column`，交叉轴默认 `stretch`，
     会把 `display: inline-block` 的徽标**拉成整行宽的一条**
     （实测 370px 宽，本该是个约 30px 的小药丸）—— 看起来像一根进度条，
     既不像分数、也把词义挤下去了。窗口变宽后这个问题格外明显。 */
.emm-gen-score { display: inline-block; align-self: flex-start; min-width: 26px; padding: 1px 6px; border-radius: 999px; background: color-mix(in srgb, var(--eng-ink, var(--eng-color)) 14%, var(--bg-primary)); color: var(--text-primary); font-size: 11px; font-weight: 600; text-align: center; }

.emm-gen-candidates { border: 1px solid var(--border); border-radius: 9px; padding: 10px 12px; background: var(--bg-primary); }
.emm-gen-candidates summary { cursor: pointer; color: var(--text-primary); font-size: 12.5px; font-weight: 600; }
.emm-gen-candidates > .emm-gen-words { margin-top: 10px; }

.emm-gen-preview { display: flex; flex-direction: column; gap: 9px; padding: 11px 12px; border: 1px solid color-mix(in srgb, var(--eng-ink, var(--eng-color)) 40%, var(--border)); border-radius: 9px; background: color-mix(in srgb, var(--eng-ink, var(--eng-color)) 6%, var(--bg-primary)); }
.emm-gen-preview > header { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px; }
.emm-gen-preview > header strong { color: var(--text-primary); font-size: 13px; }
.emm-gen-preview > header span { color: var(--text-tertiary); font-size: 11.5px; }
.emm-gen-picked { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.emm-gen-picked li label { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg-primary); cursor: pointer; font-size: 12px; }
.emm-gen-picked li label:hover { border-color: var(--eng-ink, var(--eng-color)); }
.emm-gen-picked-word { color: var(--text-primary); font-weight: 600; }
.emm-gen-picked small { color: var(--text-tertiary); font-size: 11px; }

.emm-gen-sentences { color: var(--text-secondary); font-size: 12px; }
.emm-gen-sentences summary { cursor: pointer; color: var(--text-primary); font-size: 12.5px; }
.emm-gen-sentences ul { margin: 8px 0 0; padding-left: 18px; }
.emm-gen-sentences li { margin-bottom: 7px; }
.emm-gen-sentences p { margin: 0 0 2px; color: var(--text-primary); }
.emm-gen-sentences small { color: var(--text-tertiary); }

/* 长难句预览（只读页） */
.emm-sent-days { display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 0; }
.emm-sent-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; margin: 12px 0 8px; }
.emm-sent-toolbar-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.emm-sent-toggle { display: inline-flex; align-items: center; gap: 6px; color: var(--text-secondary); font-size: 12px; cursor: pointer; }
.emm-sent-list { display: flex; flex-direction: column; gap: 12px; margin: 0; padding: 0; list-style: none; counter-reset: sent; }
.emm-sent-card { padding: 14px 16px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-primary); }
.emm-sent-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 8px; }
.emm-sent-index { color: var(--text-tertiary); font-size: 11.5px; }
.emm-sent-translation { margin: 8px 0 0; color: var(--text-secondary); font-size: 13px; line-height: 1.75; }
.emm-sent-meta { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0 0; color: var(--text-secondary); font-size: 12px; line-height: 1.7; }
.emm-sent-meta b { margin-right: 4px; color: var(--text-tertiary); font-weight: 500; }
/* 范围提示：条目级列出越界原因，橙色左边框与「生成于…」的灰色元信息区分开。 */
.emm-sent-scope { margin: 6px 0 0; padding-left: 16px; border-left: 3px solid #d97706; color: var(--text-secondary); font-size: 11.5px; line-height: 1.6; }
.emm-link-btn { padding: 0; border: 0; background: none; color: var(--eng-color, var(--rd-blue-strong)); font: inherit; text-decoration: underline; cursor: pointer; }

/* ---------- 补漏短句（第 53 轮） ---------- */
/**
 * ⚠⚠ 用户要求「无法凑在一起的选词，单独生成短句，保证选词全部生成」。
 *
 * ⚠ 视觉上要**一眼看出它不是长难句**：
 *   · 左边框换成绿色系（长难句是蓝色系）——「补上了」的语义；
 *   · 「短句」小标签用同样的绿色。
 *   ⚠ 不能只靠文案区分：长难句和短句混在同一列里，
 *     若颜色一样，用户会以为长难句变短了。
 */
.emm-sent-card.is-short { border-left: 3px solid rgba(22, 163, 74, .6); }
.emm-chip.is-short-tag {
  border-color: rgba(22, 163, 74, .45);
  color: #15803d;
  background: rgba(22, 163, 74, .1);
}
[data-theme="dark"] .emm-chip.is-short-tag { color: #4ade80; }

/* ---------- 整批的考察词覆盖情况（第 52 轮） ---------- */
/**
 * ⚠⚠ 用户报「选了 70 个词，但解析中考察词数量远没有 70」。
 *   根因是**预览页只显示前 8 句**（在那 8 句里数必然偏少），
 *   而不是词没用上。所以这里把「整批用了几个 / 共几个」直接写出来，
 *   并**解释**「下面只显示前 N 句」这件事 —— 不解释用户永远会以为是丢词。
 *
 * ⚠ 这一条要**显眼但不吵**：它是用户核对词数的依据，
 *   不能像错误提示那样红，也不能灰到看不见。
 */
.emm-sent-coverage {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px;
  margin: 0 0 10px; padding: 8px 12px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-secondary);
  font-size: 12px; line-height: 1.7; color: var(--text-secondary);
}
.emm-sent-coverage-main { font-size: 13px; }
.emm-sent-coverage-main b { color: var(--text-primary); font-weight: 650; }
.emm-sent-coverage-hint { color: var(--text-tertiary); font-size: 11.5px; }
.emm-sent-coverage-missed { color: var(--text-tertiary); font-size: 11.5px; }
.emm-sent-coverage-missed b { color: #b45309; font-weight: 600; margin-right: 4px; }

/* ---------- 考察词 / 固定搭配 标注（用户要求「考察词进行标注」） ---------- */
/**
 * ⚠⚠ 标记现在是 **`<button>`**（用户要求「做成可点开卡片小窗的形式」），
 *   所以样式要**同时**写 `.emm-mark-word` 与图例里的 `<mark class="emm-mark-word">`。
 *
 * ⚠⚠⚠ **按钮必须显式清掉浏览器默认样式**，否则会带上边框、内边距、
 *   浅灰背景和 `font: 400 13.333px Arial` —— 在一句 Georgia 19px 的英文里
 *   会显得又小又灰，一眼就看得出「这几个词不是句子的一部分」。
 *   实测：不清 `font` 的话字号会从 19px 掉到 13.3px。
 */
button.emm-mark-word, button.emm-mark-phrase {
  padding: 1px 3px; margin: 0; border: 0; border-radius: 3px;
  font: inherit; line-height: inherit; color: inherit;
  background: none; cursor: pointer; text-align: inherit;
  -webkit-appearance: none; appearance: none;
}
.emm-mark-word { padding: 1px 3px; border-radius: 3px; background: rgba(37, 99, 235, .16); box-shadow: inset 0 -2px 0 rgba(37, 99, 235, .45); color: inherit; font-weight: 600; }
.emm-mark-phrase { padding: 1px 3px; border-radius: 3px; background: rgba(217, 119, 6, .16); box-shadow: inset 0 -2px 0 rgba(217, 119, 6, .45); color: inherit; font-weight: 600; }
/* 可点击的标记要有**悬停/聚焦反馈**，否则用户不知道它能点。 */
button.emm-mark-word:hover, button.emm-mark-phrase:hover { filter: brightness(1.35); }
button.emm-mark-word:focus-visible, button.emm-mark-phrase:focus-visible {
  outline: 2px solid var(--eng-color, var(--rd-blue-strong)); outline-offset: 1px;
}
/* 图例：跟句子下面，说明两种底色各是什么。 */
.emm-sent-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 6px 0 0; color: var(--text-tertiary); font-size: 11.5px; line-height: 1.7; }
.emm-legend-item { display: inline-flex; align-items: baseline; gap: 5px; }
.emm-legend-item .emm-mark-word, .emm-legend-item .emm-mark-phrase { font-weight: 500; }

/* ---------- 标记的卡片小窗（用户要求「做成可点开卡片小窗的形式」） ---------- */
/**
 * ⚠⚠ **贴在词旁边的浮层，不是居中大窗**（理由见 `sentences.js` 里那段注释）：
 *   用户是「读句子时顺手点一个词」，期望看一眼就继续读；
 *   居中大窗会盖住整句、还要关掉才能继续，打断阅读。
 *
 * ⚠ 挂载点是 `document.body`（`position: fixed` 放进页面容器会被祖先的
 *   `transform` / `overflow` 裁掉）—— 词库那个弹窗踩过同一个坑。
 * ⚠ 位置由 JS 用 `getBoundingClientRect` 算（`positionMarkCard`），
 *   这里只给尺寸与外观。
 */
.emm-mark-card {
  position: fixed; z-index: 2100; width: min(320px, calc(100vw - 24px));
  box-sizing: border-box; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: 10px;
  /**
   * ⚠⚠⚠ **必须用不透明底色，不能用 `--bg-secondary`**。
   *
   *   `--bg-secondary` 是**玻璃色**（`color-mix(… 94%, transparent)`，实测 alpha=0.94）——
   *   用在面板上没问题（它铺在整页背景上），但**浮层底下是 19px 的白色正文**：
   *   6% 透上来，实测卡片中心透出的字是 `rgb(30,31,33)`，
   *   与卡片底 `rgb(16,17,19)` 的对比度 **1.15:1** —— 数值不大，但
   *   **截图里一眼就能看见句子穿过卡片**，像卡片没画完。
   *
   *   ⚠ 参考同类的 `eng-phrase-card`（阅读器的短语卡）：它用的是
   *     **不透明**的 `--reader-paper`，所以没有这个问题。
   *   ⚠ 这里改用 `--bg-primary`（实色 `#08090a`）打底 + 一层极淡的提亮，
   *     既保住「浮层」的层次感，又完全挡住底下的文字。
   */
  background: var(--bg-primary);
  background-image: linear-gradient(color-mix(in srgb, var(--text-primary) 5%, transparent), color-mix(in srgb, var(--text-primary) 5%, transparent));
  color: var(--text-primary);
  box-shadow: 0 12px 32px rgba(0, 0, 0, .28);
  animation: emmMarkCardIn .13s ease;
}
@keyframes emmMarkCardIn { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }
/* 左边框与标记同色 —— 一眼看出这张卡是「考察词」还是「搭配」。 */
.emm-mark-card[data-kind="word"] { border-left: 3px solid rgba(37, 99, 235, .75); }
.emm-mark-card[data-kind="phrase"] { border-left: 3px solid rgba(217, 119, 6, .75); }
.emm-mark-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.emm-mark-card-kind { display: block; color: var(--text-tertiary); font-size: 10.5px; }
.emm-mark-card-kind.is-phrase { color: #b45309; }
.emm-mark-card-head strong { display: block; margin-top: 1px; font-size: 15px; line-height: 1.4; }
.emm-mark-card-body { margin-top: 7px; }
.emm-mark-card-meaning { margin: 0; color: var(--text-secondary); font-size: 13px; line-height: 1.65; }
.emm-mark-card-in { margin: 5px 0 0; color: var(--text-tertiary); font-size: 11.5px; line-height: 1.6; }
.emm-mark-card-in b { color: var(--text-secondary); font-weight: 600; }
.emm-mark-card-note { margin: 5px 0 0; padding-left: 8px; border-left: 2px solid var(--border); color: var(--text-tertiary); font-size: 11.5px; line-height: 1.6; }
.emm-mark-card-stats { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 7px 0 0; }
.emm-mark-card-stats > div { display: flex; align-items: baseline; gap: 5px; }
.emm-mark-card-stats dt { color: var(--text-tertiary); font-size: 11px; }
.emm-mark-card-stats dd { margin: 0; color: var(--text-secondary); font-size: 11.5px; }

/* ---------- 逐句解析（①②③ 与打印件同一套序号） ---------- */
.emm-sent-segments { display: flex; flex-direction: column; gap: 5px; margin: 8px 0 0; padding: 0; list-style: none; }
.emm-sent-segments > li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; font-size: 12.5px; line-height: 1.75; }
.emm-sent-seg-no { flex: none; color: var(--text-tertiary); font-size: 12px; }
.emm-sent-seg-text { color: var(--text-primary); }
.emm-sent-seg-role { padding: 0 5px; border-radius: 4px; background: var(--bg-secondary); color: var(--text-secondary); font-size: 11px; }
.emm-sent-seg-explain { color: var(--text-secondary); }

/* ---------- 固定搭配解释（用户要求「对句子中出现的固定搭配短语进行翻译解释」） ---------- */
.emm-sent-colloc { margin: 10px 0 0; padding: 9px 11px; border: 1px solid var(--border); border-left: 3px solid #d97706; border-radius: 8px; background: var(--bg-secondary); }
.emm-sent-colloc h4 { display: flex; align-items: baseline; gap: 6px; margin: 0 0 6px; color: var(--text-secondary); font-size: 12px; font-weight: 600; }
.emm-sent-colloc h4 span { color: var(--text-tertiary); font-weight: 400; }
.emm-sent-colloc ul { display: flex; flex-direction: column; gap: 5px; margin: 0; padding: 0; list-style: none; }
.emm-sent-colloc li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; font-size: 12px; line-height: 1.7; }
.emm-sent-colloc b { color: var(--text-primary); font-weight: 600; }
.emm-colloc-in { color: var(--text-tertiary); font-size: 11px; }
.emm-colloc-meaning { color: var(--text-secondary); }
.emm-colloc-note { color: var(--text-tertiary); font-size: 11px; }
/* ⚠ 窄屏：搭配条目的三段（短语/句中出现/释义）改成整行堆叠，否则会被挤成竖条。 */
@media (max-width: 760px) {
  .emm-sent-colloc li { display: block; }
  .emm-colloc-in, .emm-colloc-meaning, .emm-colloc-note { display: block; margin-top: 2px; }
}

/* 实时进度 */
.emm-gen-run { display: flex; flex-direction: column; gap: 8px; padding: 10px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-primary); }
.emm-gen-run.is-running { border-color: var(--rd-blue-strong, var(--eng-color)); }
.emm-gen-run-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.emm-gen-run-head strong { color: var(--text-primary); font-size: 13px; }
.emm-gen-run-head span { color: var(--text-tertiary); font-size: 11.5px; }
.emm-gen-bar { height: 6px; border-radius: 999px; background: var(--bg-secondary); overflow: hidden; }
.emm-gen-bar span { display: block; height: 100%; border-radius: 999px; background: var(--rd-blue-strong, var(--eng-color)); transition: width .3s ease; }
.emm-gen-run-words { display: flex; flex-direction: column; gap: 3px; margin: 0; padding: 0; list-style: none; max-height: 220px; overflow-y: auto; }
.emm-gen-run-words li { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; font-size: 11.5px; }
.emm-gen-run-name { color: var(--text-primary); }
.emm-gen-run-stage { color: var(--text-tertiary); }
.emm-gen-run-words li.is-ready .emm-gen-run-stage { color: #16a34a; }
.emm-gen-run-words li.is-failed .emm-gen-run-stage { color: #dc2626; }

/* 质量检查结果 */
.emm-gen-issues { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; list-style: none; max-height: 420px; overflow-y: auto; }
.emm-gen-issues > li { padding: 9px 10px; border: 1px solid var(--border); border-left-width: 3px; border-radius: 8px; background: var(--bg-primary); }
.emm-gen-issues > li.is-error { border-left-color: #dc2626; }
.emm-gen-issues > li.is-warning { border-left-color: #d97706; }
.emm-gen-issues > li.is-clean { border-left-color: #16a34a; }
.emm-gen-issue-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.emm-gen-issue-head strong { color: var(--text-primary); font-size: 13px; }
.emm-gen-issue-head span { color: var(--text-tertiary); font-size: 11.5px; }
.emm-gen-issue-summary { margin: 5px 0 0; color: var(--text-secondary); font-size: 12px; }
.emm-gen-issue-list { display: flex; flex-direction: column; gap: 4px; margin: 7px 0 0; padding: 0; list-style: none; }
.emm-gen-issue-list li { display: flex; gap: 6px; color: var(--text-secondary); font-size: 11.5px; line-height: 1.55; }
.emm-gen-sev { flex: 0 0 auto; padding: 1px 5px; border-radius: 4px; font-size: 10.5px; background: var(--bg-secondary); color: var(--text-tertiary); }
.emm-gen-issue-list li.is-error .emm-gen-sev { background: color-mix(in srgb, #dc2626 18%, var(--bg-secondary)); color: #dc2626; }
.emm-gen-issue-list li.is-warning .emm-gen-sev { background: color-mix(in srgb, #d97706 18%, var(--bg-secondary)); color: #d97706; }

/* ---------- 长列表窗口 ----------
   把「长瀑布」长栏收进一个可放大的窗口里看（见 js/.../listWindow.js）。
   ⚠ 这里刻意**不发明新的视觉语言**：外壳复用 .emm-dialog 那一套 token
   （--border / --bg-secondary / 12px 圆角 / 同一条阴影），遮罩直接复用
   .emm-dialog-overlay。加进类里只是为了能改宽高和滚动方式。 */
.emm-window-overlay { --emm-window-w: min(940px, 100%); }
.emm-window { display: flex; flex-direction: column; width: var(--emm-window-w); max-height: min(86vh, 100%); box-sizing: border-box; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-secondary); box-shadow: 0 20px 60px rgba(0, 0, 0, .24); overflow: hidden; }
.emm-window-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex: 0 0 auto; padding: 18px 20px 14px; border-bottom: 1px solid var(--border); }
.emm-window-title h2 { margin: 0; color: var(--text-primary); font-size: 17px; }
.emm-window-title p { margin: 5px 0 0; color: var(--text-tertiary); font-size: 12px; line-height: 1.6; }
.emm-window-tools { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.emm-window-size { padding: 2px 8px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg-primary); color: var(--text-tertiary); font-size: 11px; white-space: nowrap; }
.emm-window-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 16px 20px 20px; }

/* 三档尺寸。'full' 是真·满屏：连四边留白都收掉，只留一点呼吸空间。 */
.emm-window-overlay[data-size="md"] { --emm-window-w: min(760px, 100%); }
.emm-window-overlay[data-size="md"] .emm-window { max-height: min(78vh, 100%); }
.emm-window-overlay[data-size="lg"] { --emm-window-w: min(1100px, 100%); }
.emm-window-overlay[data-size="lg"] .emm-window { max-height: min(90vh, 100%); }
.emm-window-overlay[data-size="full"] { padding: 0; }
.emm-window-overlay[data-size="full"] .emm-window { width: 100%; height: 100vh; max-height: 100vh; border: 0; border-radius: 0; }

/* 窗口里的列表不再自带滚动条 —— 滚动交给 .emm-window-body，
   否则会出现内外两层滚动条（鼠标滚到内层边缘就卡住）。 */
.emm-window .emm-gen-words, .emm-window .emm-gen-issues, .emm-window .emm-gen-run-words,
.emm-window .emm-wrong-list, .emm-window .emm-word-list, .emm-window .emm-sent-list { max-height: none; overflow: visible; }
/* 窗口里空间宽裕，用双列瀑布减少空荡与来回滚动。
   ⚠ 只对窗口内的列表生效：页面那一栏比窗口窄得多，双列会把词挤到断行。

   ⚠⚠ **必须先把 display 从 flex 改回 block**：`.emm-gen-words` 等列表原本是
     `display: flex; flex-direction: column`，而 **CSS 多列布局对 flex 容器无效** ——
     实测写 `columns: 2` 之后 `column-count` 算出来是 2（看起来生效了），
     但每条仍然是整行宽、老老实实上下堆叠（第一个 li 1058px 宽、
     第二个的 y 比第一个大 106px），界面和预期完全不符。这类「属性算出来对、
     实际没生效」的坑只能靠量真实 DOM 发现，肉眼看截图也容易当成"还没加载完"。 */
.emm-window .emm-sent-list,
.emm-window .emm-gen-words.is-wide,
.emm-window .emm-wrong-list {
  display: block;
  columns: 2;
  column-gap: 14px;
}
.emm-window .emm-sent-list > li,
.emm-window .emm-gen-words.is-wide > li,
.emm-window .emm-wrong-list > li { break-inside: avoid; margin-bottom: 10px; }
/* 错词本的列表容器自带"1px 间隙 + 边框"的表格感，放进窗口会和窗口外框
   叠成双层线，所以窗内剥掉一层。
   ⚠ `.emm-word-list` 现在只剩错词本在用（词库已改成卡片网格 `.emm-word-grid`，
     不再走窗口）—— 保留它是为了错词本那条线不受影响。 */
.emm-window .emm-word-list, .emm-window .emm-wrong-list { border: 0; border-radius: 0; background: none; gap: 0; }
@media (max-width: 900px) {
  .emm-window .emm-sent-list,
  .emm-window .emm-gen-words.is-wide,
  .emm-window .emm-wrong-list { columns: 1; }
}

/* 内联触发器：对齐 .emm-gen-tab 那类小控件，跟页面其余按钮是一套语言。 */
.emm-window-open { display: inline-flex; align-items: center; gap: 5px; padding: 5px 11px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg-primary); color: var(--text-secondary); font: inherit; font-size: 12px; cursor: pointer; transition: border-color .15s ease, color .15s ease; }
.emm-window-open:hover { border-color: var(--eng-ink, var(--eng-color)); color: var(--eng-ink, var(--eng-color)); }
.emm-window-open svg { width: 13px; height: 13px; }
.emm-window-more { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 9px 0 0; color: var(--text-tertiary); font-size: 12px; }

body.emm-window-open { overflow: hidden; }

@media (max-width: 760px) {
  /* 手机上窗口就是全屏抽屉：留白给不出信息，只会挤掉内容。 */
  .emm-window-overlay { padding: 0; }
  .emm-window { width: 100%; height: 100vh; max-height: 100vh; border: 0; border-radius: 0; }
  .emm-window-body { padding: 14px 14px 20px; }
}

/* ⚠ 折成一列后，两栏的包装层会把顺序钉成「左栏整块 → 右栏整块」，
   也就是「题库/进行中/质量检查」跑到「选词」前面 —— 而选词是生成的前置步骤，
   先看到「生成待生成的 N 个词」却还没挑词是说不通的。
   所以这里用 `display: contents` 把两个包装层「拆掉」，让 5 个面板
   成为同一个 flex 容器的直接子元素，再用 `order` 单独排序。
   （`display: contents` 只影响布局盒子，不动 DOM 结构与事件绑定。）

   ⚠⚠ 必须显式写回 `align-items: stretch`：宽屏那条规则里的 `align-items: start`
     是给 grid 用的（防子项被拉伸到同高），但折成一列后它会让每个面板
     **按内容宽度收缩**——实测 5 个面板宽度成了 772/812/644/198/812 各不相同，
     「进行中」被压成 198px 一条。改 `display` 时一定要把影响另一套布局的属性一起改回来。 */
/* ============================ 审查面板：两条线各一块 ============================ */

/**
 * 审查面板与生成台**同构**：语境填空审查 / 长难句审查各是一块独立面板，
 * 内容完全不同（审什么、范围、计数单位、记录存放都不一样）。
 * 这里给两块加上各自的视觉标识，让用户一眼看出当前审的是哪条线。
 */
.emm-gen-panel--review-sentence { border-left: 3px solid var(--rd-green-strong, #16a34a); }
/* ⚠ 短句记词这块是「还没做」的说明，用中性灰而不是蓝/绿：
   它不参与审查，给一个跟另外两块同样「能审」的颜色会误导。
   （灰色用的是既有 token，不是新颜色。） */
.emm-gen-panel--review-micro { border-left: 3px solid var(--text-tertiary); }

/* 范围行：把「审的是全库还是某一批」摆在按钮正上方，点之前就能看清。 */
.emm-gen-review-scope {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
}

@media (max-width: 1100px) {
  /* ⚠ 折成单列时必须把 `align-items` 写回 `stretch`：宽屏那条 `align-items: start`
     是给 grid 防拉伸用的，折成 flex 单列后会让每个面板**按内容宽度收缩**。 */
  .emm-gen-layout { display: flex; flex-direction: column; align-items: stretch; }
  .emm-gen-main { display: flex; flex-direction: column; gap: 14px; }
  /* 进度栏回到主内容**下面**，并且不再 sticky（单列下 sticky 会盖住内容）。 */
  .emm-gen-rail { position: static; order: 9; }
  /* 单列顺序：三个大卡片（无 order）→ 当前面板 → 审查 → 模型设置。
     ⚠ 模型设置必须**最后**：它是配置项，不是每次都要看的操作。
     ⚠⚠ `.emm-gen-panel--micro` 必须并进这一条：漏了它，短句记词面板在窄屏下
        会掉到「审查」「模型设置」**后面**（没有 order 的元素排在所有有 order 的后面），
        用户要先滚过审查台才看得到自己要操作的面板。 */
  .emm-gen-panel--sentence, .emm-gen-panel--micro { order: 2; }
  .emm-gen-panel--review { order: 3; }
  .emm-gen-panel--model { order: 4; }
}
/* ==== pages/eng-exam.css ==== */
/**
 * 英语真题刷题 —— 组题工作台 + 刷题界面样式。
 *
 * ## 与现有 UI 是一套（不是另起炉灶）
 *
 * 全部复用项目既有 CSS 变量（`--bg-secondary` / `--border` / `--text-*` /
 * `--accent` / `--danger`）与页头组件（`eng-header` / `eng-page-title` /
 * `emm-tabs`）。这里只加 `eex-` 前缀的布局类，不重定义颜色体系。
 *
 * ## ⚠ 壁纸模式要一起适配
 *
 * 本项目支持壁纸背景（`html.has-wallpaper`）。直接铺在页面上的浅色文字
 * 在壁纸亮部会读不清 —— 见 `css/pages/wallpaper.css` 的「文字背衬」名单。
 * 这个页面的卡片都用了 `background: var(--bg-secondary)` 实体底，
 * 所以不需要额外进背衬名单；但 `.eex-hint` 这类裸文字需要。
 */

/* ============================ 工作台 ============================ */

.eex-page {
  width: min(1120px, calc(100% - 28px));
  margin: 0 auto 60px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.eex-loading {
  padding: 60px 0;
  text-align: center;
  color: var(--text-tertiary);
}

/* 概览统计条 */
.eex-statbar {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
}

.eex-stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 12px;
}

.eex-stat b {
  font-size: 24px;
  font-weight: 650;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.eex-stat span {
  font-size: 12px;
  color: var(--text-tertiary);
}

/* 面板 */
.eex-panel {
  padding: 20px 22px 22px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 14px;
}

.eex-panel-title {
  margin: 0 0 4px;
  font-size: 15px;
  font-weight: 650;
  color: var(--text-primary);
  display: flex;
  align-items: center;
  gap: 8px;
}

.eex-count-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 10px;
  background: var(--bg-hover);
  color: var(--text-secondary);
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.eex-panel-hint {
  margin: 0 0 14px;
  font-size: 12px;
  color: var(--text-tertiary);
  line-height: 1.6;
}

/* 字段行 */
.eex-field {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 12px 0;
  border-top: 1px solid var(--border);
}

.eex-field:first-of-type { border-top: none; }

.eex-field-label {
  flex: 0 0 44px;
  padding-top: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
}

.eex-inline {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* 勾选项 */
.eex-checkrow {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  flex: 1;
}

.eex-check {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--bg-primary, transparent);
  border: 1px solid var(--border);
  border-radius: 9px;
  cursor: pointer;
  font-size: 13px;
  color: var(--text-secondary);
  transition: border-color .12s, background .12s;
  user-select: none;
}

.eex-check input {
  /**
   * ⚠ 不能写 `width:0; height:0; opacity:0`：那样 input 变成**零尺寸、不可聚焦**，
   *   键盘 Tab 跳不到、读屏念不出、自动化也点不中（Playwright 报
   *   "Element is outside of the viewport"）。
   *   用「铺满整个 label + 全透明」的写法：视觉上看不见，但它有真实尺寸、
   *   能接收点击与焦点，点在 label 任何位置都等于点在 input 上。
   */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

/**
 * 键盘聚焦时给 label 一个可见的聚焦环。
 * ⚠ 没有这个，纯键盘用户按 Tab 在题型之间跳时**看不出焦点在哪**
 *   （input 本身透明，浏览器默认的 outline 也是画在 input 上、被 label 盖住）。
 */
.eex-check:focus-within {
  outline: 2px solid var(--accent, #2563eb);
  outline-offset: 2px;
}

.eex-check:hover { border-color: var(--text-tertiary); }

.eex-check.is-on {
  border-color: var(--accent, #2563eb);
  background: rgba(37, 99, 235, .08);
  color: var(--text-primary);
}

/* 一遍都抽不出来的档位：压暗，但仍可点（用户可能想删题组腾位置） */
.eex-check.is-empty {
  opacity: .5;
}

.eex-check-name { font-weight: 500; }

.eex-check-meta {
  font-size: 11px;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}

.eex-check--sm { padding: 6px 10px; font-size: 12.5px; }

/* 输入框 */
.eex-input {
  width: 84px;
  padding: 8px 10px;
  background: var(--bg-primary, transparent);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text-primary);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.eex-input:focus {
  outline: none;
  border-color: var(--accent, #2563eb);
}

.eex-input--answer {
  width: 200px;
}

.eex-hint {
  font-size: 12px;
  color: var(--text-tertiary);
  line-height: 1.6;
}

/* 按钮 */
.eex-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-top: 14px;
  margin-top: 4px;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}

.eex-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 16px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--bg-primary, transparent);
  color: var(--text-primary);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background .12s, border-color .12s, opacity .12s;
  white-space: nowrap;
}

.eex-btn:hover:not(:disabled) { background: var(--bg-hover); }

.eex-btn:disabled { opacity: .5; cursor: default; }

.eex-btn--primary {
  background: var(--accent, #2563eb);
  border-color: var(--accent, #2563eb);
  color: #fff;
}

.eex-btn--primary:hover:not(:disabled) {
  background: var(--accent-strong, #1d4ed8);
  border-color: var(--accent-strong, #1d4ed8);
}

.eex-btn--danger {
  color: var(--danger, #dc2626);
  border-color: color-mix(in srgb, var(--danger, #dc2626) 34%, transparent);
}

.eex-btn--danger:hover:not(:disabled) {
  background: color-mix(in srgb, var(--danger, #dc2626) 10%, transparent);
}

.eex-btn--lg {
  padding: 10px 22px;
  font-size: 14px;
}

/* ============================ 题组列表 ============================ */

.eex-set-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.eex-set {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--bg-primary, transparent);
  flex-wrap: wrap;
}

.eex-set.is-done { border-left: 3px solid var(--accent, #2563eb); }
.eex-set.is-doing { border-left: 3px solid var(--warning, #d97706); }

.eex-set-main { flex: 1; min-width: 0; }

.eex-set-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.eex-set-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 6px;
  font-size: 11.5px;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}

.eex-set-side {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.eex-set-status {
  font-size: 12px;
  color: var(--text-tertiary);
}

.eex-set-score {
  font-size: 13px;
  font-weight: 650;
  color: var(--accent, #2563eb);
  font-variant-numeric: tabular-nums;
}

/* ============================ 刷题界面 ============================ */

/**
 * ⚠ 宽度不在这里定：刷题界面用 `#page-container.ov-fullwidth` 铺满整窗
 *   （左右双屏必须吃满宽度，见下方「刷题界面 · 左右双屏」）。
 */
.eex-page--session {
  width: 100%;
}

/**
 * 工具栏不再 `sticky`：整页已经不滚了（滚动都在两栏内部），
 * 没有需要「粘住」的场景；`sticky` 在 `overflow: hidden` 的父级里也不生效。
 */
.eex-toolbar {
  position: relative;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 18px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  flex-wrap: wrap;
}

.eex-timer {
  font-size: 22px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
  letter-spacing: .5px;
}

.eex-timer.is-urgent {
  color: var(--danger, #dc2626);
  animation: eex-pulse 1s ease-in-out infinite;
}

.eex-timer.is-done { color: var(--text-tertiary); font-size: 16px; }

@keyframes eex-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .45; }
}

.eex-toolbar-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.eex-progress {
  font-size: 12.5px;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}

.eex-result {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 22px 24px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 14px;
  flex-wrap: wrap;
}

.eex-result-score {
  font-size: 38px;
  font-weight: 700;
  color: var(--accent, #2563eb);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.eex-result-score span {
  font-size: 17px;
  color: var(--text-tertiary);
  font-weight: 500;
}

.eex-result-meta {
  display: flex;
  gap: 20px;
  font-size: 13px;
  color: var(--text-secondary);
  flex-wrap: wrap;
}

/**
 * `.eex-passage-block` 已废弃：左右双屏后原文与题目分居两栏，
 * 不再需要「一篇一块」的卡片外壳（那一块由 `.eex-pane--passage` 承担）。
 */

.eex-passage-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}

.eex-passage-title {
  font-size: 14px;
  font-weight: 650;
  color: var(--text-primary);
}

.eex-passage-meta {
  font-size: 11.5px;
  color: var(--text-tertiary);
}

.eex-passage-body {
  /* ⚠ 与英语阅读页同一套字体：Times New Roman 在前（用户明确要求「正常高考上的字体」）。 */
  font-family: 'Times New Roman', 'SimSun', 'Microsoft YaHei', serif;
  font-size: 16.5px;
  line-height: 2;
  color: var(--text-primary);
}

.eex-passage-body p {
  margin: 0 0 14px;
}

.eex-passage-body p:last-child { margin-bottom: 0; }

/* 七选五的 A–G 选项池 */
.eex-optionbank {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px dashed var(--border);
}

.eex-optionbank-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  margin-bottom: 8px;
}

.eex-optionbank-item {
  font-family: 'Times New Roman', 'SimSun', 'Microsoft YaHei', serif;
  font-size: 15px;
  line-height: 1.8;
  color: var(--text-primary);
}

.eex-optionbank-item b {
  color: var(--text-secondary);
  margin-right: 4px;
}

/* 题目 */
/**
 * `.eex-questions` 仍是题目列表的容器（右屏内层），
 * 但不再需要 `margin-top`：分栏后它紧贴 `.eex-pane--questions` 顶部。
 */
.eex-questions {
  margin-top: 0;
}

.eex-question {
  padding: 16px 0;
  border-top: 1px solid var(--border);
}

.eex-question:first-child { border-top: none; }

.eex-q-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.eex-q-no {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--bg-hover);
  color: var(--text-secondary);
  font-size: 11.5px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

.eex-q-type {
  font-size: 11px;
  color: var(--text-tertiary);
}

.eex-q-stem {
  font-family: 'Times New Roman', 'SimSun', 'Microsoft YaHei', serif;
  font-size: 15.5px;
  line-height: 1.8;
  color: var(--text-primary);
  margin-bottom: 10px;
}

.eex-q-hint {
  font-size: 12.5px;
  color: var(--text-tertiary);
  margin-right: 8px;
}

/* 选项按钮 */
.eex-options {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.eex-option {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  width: 100%;
  padding: 9px 13px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--bg-primary, transparent);
  color: var(--text-primary);
  font-family: 'Times New Roman', 'SimSun', 'Microsoft YaHei', serif;
  font-size: 15px;
  line-height: 1.6;
  text-align: left;
  cursor: pointer;
  transition: border-color .12s, background .12s;
}

.eex-option:hover:not(:disabled) { background: var(--bg-hover); }

.eex-option b { color: var(--text-secondary); flex: 0 0 auto; }

.eex-option.is-chosen {
  border-color: var(--accent, #2563eb);
  background: rgba(37, 99, 235, .08);
}

/* 交卷后：正确项绿、选错的红 */
.eex-option.is-answer {
  border-color: var(--success, #16a34a);
  background: color-mix(in srgb, var(--success, #16a34a) 10%, transparent);
}

.eex-option.is-chosen-wrong {
  border-color: var(--danger, #dc2626);
  background: color-mix(in srgb, var(--danger, #dc2626) 10%, transparent);
}

.eex-option:disabled { cursor: default; }

.eex-blank {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.eex-input--answer.is-correct { border-color: var(--success, #16a34a); }
.eex-input--answer.is-wrong { border-color: var(--danger, #dc2626); }

.eex-question.is-correct .eex-q-no { background: color-mix(in srgb, var(--success, #16a34a) 22%, transparent); }
.eex-question.is-wrong .eex-q-no { background: color-mix(in srgb, var(--danger, #dc2626) 22%, transparent); }

/* 解析 */
.eex-analysis {
  margin-top: 12px;
  padding: 12px 14px;
  background: var(--bg-hover);
  border-radius: 9px;
  font-size: 13px;
  line-height: 1.8;
  color: var(--text-secondary);
}

.eex-analysis-title {
  font-weight: 650;
  color: var(--text-primary);
  margin-bottom: 6px;
  font-size: 12px;
}

.eex-analysis-answer {
  margin-top: 8px;
  color: var(--text-primary);
}

/* ============================ 刷题界面 · 左右双屏 ============================ */

/**
 * 布局：左屏原文、右屏题目，**两屏各自独立滚动，页面本身不滚**。
 *
 * ## 高度怎么定：不用拍数字，用 flex 自己撑
 *
 * ⚠⚠ 这里**踩过一次坑**：最初写 `height: calc(100dvh - 232px)`，
 *   232 是估的 → 实测页头被顶部导航压住并裁掉半截（截图可见
 *   「【布局探针】」只剩上半边）。原因是 `#page-container` 自己还有
 *   `padding-top: calc(var(--nav-height) + 20px)`，而页头还在它下面排。
 *
 * 正确做法（README 同类踩坑记录也这么写）：**不要在页面里减视口高度**，
 * 让外层 `.ov-fullwidth` 把 `#page-container` 的内边距吃掉、高度锁成视口，
 * 页面自己 `flex: 1` 从父级拿剩余高度。这样页头、工具栏、翻页栏
 * 无论怎么换行，两栏都会自动缩到刚好剩下的空间。
 *
 * 依赖：`renderEngExamSession` 会给 `#page-container` 加 `ov-fullwidth`
 * 并内联清掉它的 padding（见 JS 里的说明）。
 */
.eex-page--session {
  display: flex;
  flex-direction: column;
  gap: 12px;
  /**
   * `flex: 1` + `min-height: 0` 是这套布局的关键：
   * 不加 `min-height: 0`，flex 子项的最小高度等于内容高度，
   * 两栏内的长文会把整个页面顶高 —— 页面就又能滚了（用户明确不要）。
   */
  flex: 1;
  min-height: 0;
  /* 页面本身不滚：滚动条只出现在两栏内部 */
  overflow: hidden;
}

.eex-split {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  /* 两屏要贴满整窗，只留一点呼吸空间（否则英文行宽过窄） */
  padding: 0 2px;
}

/**
 * 每一屏都是一个独立滚动容器。
 * `min-width: 0` 必须有：grid 子项默认 `min-width: auto`，
 * 英文长单词/长例句会把列撑破，两栏就不再是 1:1 了。
 */
.eex-pane {
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 18px 20px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 14px;
  /* 滚动时内容不要贴边（现代浏览器支持，旧浏览器忽略即可） */
  scrollbar-width: thin;
}

.eex-pane:focus-visible {
  outline: 2px solid var(--accent, #2563eb);
  outline-offset: 2px;
}

/* 两栏各自的滚动条加粗一点，方便看清「这一屏还有多少」 */
.eex-pane::-webkit-scrollbar { width: 10px; }
.eex-pane::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--text-tertiary) 45%, transparent);
  border-radius: 6px;
  border: 3px solid transparent;
  background-clip: content-box;
}
.eex-pane::-webkit-scrollbar-thumb:hover {
  background: color-mix(in srgb, var(--text-tertiary) 70%, transparent);
  background-clip: content-box;
}

/* 右屏的题目不需要再套一层卡片（它自己就是屏） */
.eex-pane--questions .eex-question:first-child { border-top: none; padding-top: 0; }
.eex-pane--questions .eex-question:last-child { padding-bottom: 0; }

.eex-pane-empty {
  padding: 40px 0;
  text-align: center;
  color: var(--text-tertiary);
  font-size: 13px;
}

/* ---------------- 翻页栏 ---------------- */

.eex-pager {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  margin-right: auto;
}

.eex-pager-arrow {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-primary);
  color: var(--text-primary);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease;
}

.eex-pager-arrow:hover:not(:disabled) {
  background: var(--bg-tertiary, var(--bg-primary));
  border-color: var(--accent, #2563eb);
}

.eex-pager-arrow:disabled {
  opacity: .38;
  cursor: not-allowed;
}

.eex-pager-text {
  font-size: 12.5px;
  color: var(--text-secondary);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.eex-pager-text b {
  color: var(--text-primary);
  font-size: 14px;
}

.eex-dots {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-left: 4px;
}

.eex-dot {
  width: 9px;
  height: 9px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  transition: background 140ms ease, transform 140ms ease;
}

.eex-dot:hover { transform: scale(1.25); }

/* 已答完的篇实心填充（方便一眼看出还剩哪几篇） */
.eex-dot.is-full {
  background: color-mix(in srgb, var(--success, #16a34a) 70%, transparent);
  border-color: transparent;
}

.eex-dot.is-active {
  background: var(--accent, #2563eb);
  border-color: var(--accent, #2563eb);
  transform: scale(1.15);
}

/* ============================ 响应式 ============================ */

/**
 * 窄屏（手机/竖屏平板）：左右双屏挤不下，退化成**上下两屏**，仍然各自滚动。
 *
 * ⚠ 不退化成单页长滚动：那样用户看题时找不到原文。
 *   上下两屏虽然也能滚，但至少「原文在上、题在下」的结构还在，
 *   且 `50/50` 的分割让两边都够看。
 */
@media (max-width: 900px) {
  .eex-split {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr 1fr;
    gap: 10px;
  }
  .eex-pane { padding: 14px 16px; }
  .eex-pager-text { font-size: 12px; }
}

@media (max-width: 720px) {
  .eex-page { width: calc(100% - 20px); }
  /* 刷题界面铺满整窗，不吃这条窄边距（否则两屏又被挤窄一圈） */
  .eex-page--session { width: 100%; }
  .eex-field { flex-direction: column; gap: 8px; }
  .eex-field-label { padding-top: 0; flex: none; }
  .eex-set { flex-direction: column; align-items: stretch; }
  .eex-set-side { justify-content: flex-start; }
  .eex-timer { font-size: 18px; }
  .eex-result-score { font-size: 30px; }
  .eex-split { gap: 8px; }
  .eex-pane { padding: 12px 13px; border-radius: 12px; }
}

/* 壁纸模式：裸说明文字要背衬，否则亮部读不清 */
html.has-wallpaper .eex-hint,
html.has-wallpaper .eex-panel-hint,
html.has-wallpaper .eex-set-meta,
html.has-wallpaper .eex-passage-meta,
html.has-wallpaper .eex-q-type,
html.has-wallpaper .eex-progress {
  background: var(--bg-secondary);
  padding: 1px 6px;
  border-radius: 5px;
  display: inline-block;
}
/* ==== pages/eng-exam-report.css ==== */
/**
 * 英语真题刷题 —— 练习报告页样式（`/eng/exam/report`）。
 *
 * ⚠ 从 `eng-exam.css` 拆出来是**分开维护**，不是重复：
 *   组题工作台与刷题界面是一套（`eex-`），报告页是另一套阅读型版式（`eex-report-`），
 *   两者没有共用规则。放一个文件里会让那个文件越来越难定位。
 *
 * 复用同一套 CSS 变量与字体栈（`Times New Roman` 在前，与打印出口一致）。
 */

.eex-page--report {
  width: min(1020px, calc(100% - 28px));
}

.eex-report-summary {
  display: flex;
  align-items: center;
  gap: 26px;
  padding: 22px 24px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 14px;
  flex-wrap: wrap;
}

.eex-report-score {
  font-size: 40px;
  font-weight: 700;
  color: var(--accent, #2563eb);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.eex-report-score span {
  font-size: 17px;
  color: var(--text-tertiary);
  font-weight: 500;
}

.eex-report-summary-meta {
  display: flex;
  gap: 18px;
  font-size: 13px;
  color: var(--text-secondary);
  flex-wrap: wrap;
}

.eex-report-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.eex-report-progress {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.eex-report-progress-bar {
  height: 5px;
  border-radius: 3px;
  background: var(--bg-hover);
  overflow: hidden;
}

.eex-report-progress-bar span {
  display: block;
  height: 100%;
  background: var(--accent, #2563eb);
  transition: width .25s ease;
}

.eex-report-progress-text {
  font-size: 12px;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}

.eex-report-body {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.eex-report-passage {
  padding: 20px 22px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 14px;
}

.eex-report-passage-head {
  padding-bottom: 10px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--border);
}

.eex-report-passage-head h2 {
  margin: 0;
  font-size: 14px;
  font-weight: 650;
  color: var(--text-primary);
}

.eex-report-family {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 7px;
  border-radius: 5px;
  background: var(--bg-hover);
  color: var(--text-tertiary);
  font-size: 11px;
  font-weight: 500;
  vertical-align: middle;
}

.eex-report-passage-meta {
  margin-top: 5px;
  font-size: 11.5px;
  color: var(--text-tertiary);
}

.eex-report-passage-body {
  font-family: 'Times New Roman', 'SimSun', 'Microsoft YaHei', serif;
  font-size: 16px;
  line-height: 2;
  color: var(--text-primary);
}

.eex-report-passage-body p { margin: 0 0 13px; }
.eex-report-passage-body p:last-child { margin-bottom: 0; }

.eex-report-optionbank {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed var(--border);
}

.eex-report-optionbank-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  margin-bottom: 7px;
}

.eex-report-optionbank-item {
  font-family: 'Times New Roman', 'SimSun', 'Microsoft YaHei', serif;
  font-size: 15px;
  line-height: 1.8;
}

.eex-report-optionbank-item b { color: var(--text-secondary); margin-right: 4px; }

.eex-report-questions { margin-top: 6px; }

.eex-report-q {
  padding: 14px 0;
  border-top: 1px solid var(--border);
}

.eex-report-q:first-child { border-top: none; }

.eex-report-q-stem {
  font-family: 'Times New Roman', 'SimSun', 'Microsoft YaHei', serif;
  font-size: 15.5px;
  line-height: 1.8;
  color: var(--text-primary);
  margin-bottom: 8px;
}

.eex-report-q-no {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  margin-right: 8px;
  border-radius: 50%;
  background: var(--bg-hover);
  color: var(--text-secondary);
  font-size: 11.5px;
  font-weight: 650;
  font-family: system-ui, sans-serif;
  vertical-align: middle;
}

.eex-report-q.is-correct .eex-report-q-no { background: color-mix(in srgb, var(--success, #16a34a) 22%, transparent); }
.eex-report-q.is-wrong .eex-report-q-no { background: color-mix(in srgb, var(--danger, #dc2626) 22%, transparent); }

.eex-report-options { display: flex; flex-direction: column; gap: 5px; margin-bottom: 7px; }

.eex-report-option {
  padding: 7px 11px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: 'Times New Roman', 'SimSun', 'Microsoft YaHei', serif;
  font-size: 15px;
  line-height: 1.65;
  color: var(--text-primary);
}

.eex-report-option b { color: var(--text-secondary); }

.eex-report-option.is-answer {
  border-color: var(--success, #16a34a);
  background: color-mix(in srgb, var(--success, #16a34a) 9%, transparent);
}

.eex-report-option.is-wrong {
  border-color: var(--danger, #dc2626);
  background: color-mix(in srgb, var(--danger, #dc2626) 9%, transparent);
}

.eex-report-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 0 5px;
  border: 1px solid currentColor;
  border-radius: 3px;
  font-size: 10px;
  font-family: system-ui, sans-serif;
  opacity: .8;
}

.eex-report-fill { margin-bottom: 7px; font-size: 14.5px; }

.eex-report-hint { color: var(--text-tertiary); font-size: 12.5px; }

.eex-report-q-result {
  font-size: 13px;
  color: var(--text-secondary);
}

.eex-report-q.is-correct .eex-report-q-result { color: var(--success, #16a34a); }
.eex-report-q.is-wrong .eex-report-q-result { color: var(--danger, #dc2626); }

.eex-report-analysis {
  margin-top: 10px;
  padding: 11px 13px;
  background: var(--bg-hover);
  border-radius: 9px;
  font-size: 13px;
  line-height: 1.8;
  color: var(--text-secondary);
}

.eex-report-analysis-title {
  font-weight: 650;
  color: var(--text-primary);
  margin-right: 6px;
  font-size: 12px;
}

/* 生僻词表 */
.eex-report-vocab {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px dashed var(--border);
}

.eex-report-vocab-title {
  font-size: 13px;
  font-weight: 650;
  color: var(--text-primary);
  margin-bottom: 9px;
}

.eex-report-vocab-count {
  font-weight: 400;
  color: var(--text-tertiary);
  font-size: 11.5px;
  margin-left: 6px;
}

.eex-report-vocab-error {
  font-size: 12.5px;
  color: var(--danger, #dc2626);
  margin: 0;
}

.eex-report-vocab-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}

.eex-report-vocab-table th,
.eex-report-vocab-table td {
  border: 1px solid var(--border);
  padding: 6px 9px;
  text-align: left;
  vertical-align: top;
  line-height: 1.6;
}

.eex-report-vocab-table th {
  background: var(--bg-hover);
  font-weight: 600;
  color: var(--text-secondary);
  font-size: 11.5px;
  white-space: nowrap;
}

.eex-vocab-word { font-weight: 650; color: var(--text-primary); white-space: nowrap; }
.eex-vocab-phonetic { color: var(--text-tertiary); white-space: nowrap; font-size: 12px; }
.eex-vocab-pos { color: var(--text-tertiary); white-space: nowrap; }
.eex-vocab-sentence { color: var(--text-secondary); font-size: 12px; }

@media (max-width: 720px) {
  .eex-page--report { width: calc(100% - 20px); }
  .eex-report-score { font-size: 32px; }
  .eex-report-vocab-table { font-size: 11.5px; }
  .eex-report-vocab-table th, .eex-report-vocab-table td { padding: 4px 6px; }
}

/* 壁纸模式下裸说明文字要背衬 */
html.has-wallpaper .eex-report-passage-meta,
html.has-wallpaper .eex-report-progress-text {
  background: var(--bg-secondary);
  padding: 1px 6px;
  border-radius: 5px;
  display: inline-block;
}
/* ==== pages/study-checkin.css ==== */
/*
 * 学习打卡清单（.ck-*）
 *
 * 独立模块：不属于任何科目，从侧栏「打卡清单」进入。
 *
 * ⚠ 所有颜色走项目既有 token（--bg-secondary / --border / --text-* / --accent*），
 *   深色主题与壁纸模式才会自动跟上。写死 #fff/#000 在壁纸下会像贴上去的色块。
 * ⚠ 裸文字类（.ck-eyebrow / .ck-sub / .ck-panel-note / .ck-td-num 等）
 *   必须同时登记进 wallpaper.css 的背衬名单，否则壁纸亮部读不清。
 */

.ck-page {
  --ck-accent: #15803d;
  --ck-accent-soft: color-mix(in srgb, var(--ck-accent) 9%, var(--bg-secondary));
  --ck-accent-line: color-mix(in srgb, var(--ck-accent) 28%, var(--border));
  margin: 0 auto;
  padding: 20px 0 56px;
  width: min(1080px, calc(100% - 32px));
}

/* ---------- 页头 ---------- */
.ck-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px;
  align-items: end;
  margin-bottom: 18px;
}
.ck-eyebrow {
  display: block;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ck-accent);
}
.ck-title {
  margin: 4px 0 6px;
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--text-primary);
  letter-spacing: -.01em;
}
.ck-sub {
  margin: 0;
  font-size: .78rem;
  color: var(--text-tertiary);
}
.ck-header-tools {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* ---------- 按钮 ---------- */
.ck-btn {
  padding: 7px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 8px);
  background: var(--bg-secondary);
  color: var(--text-secondary);
  font: inherit;
  font-size: .78rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color .15s, color .15s, background .15s;
}
.ck-btn:hover { border-color: var(--ck-accent-line); color: var(--text-primary); }
.ck-btn--primary {
  background: var(--ck-accent);
  border-color: var(--ck-accent);
  color: #fff;
}
.ck-btn--primary:hover { background: color-mix(in srgb, var(--ck-accent) 88%, #000); color: #fff; }
.ck-btn--xs { padding: 3px 9px; font-size: .7rem; }

/* ---------- 今日卡 ---------- */
.ck-today {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  gap: 18px;
  align-items: center;
  padding: 18px 20px;
  margin-bottom: 14px;
  border: 1px solid var(--border);
  border-left: 4px solid var(--text-tertiary);
  border-radius: var(--radius-lg, 12px);
  background: var(--bg-secondary);
}
.ck-today.is-hit {
  border-left-color: var(--ck-accent);
  background: var(--ck-accent-soft);
}
.ck-today-value {
  display: block;
  margin: 4px 0 4px;
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.ck-today-hint {
  font-size: .76rem;
  color: var(--text-tertiary);
}
.ck-today-parts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
}
.ck-today-part {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-primary);
  font-size: .74rem;
  color: var(--text-secondary);
}
.ck-today-part em {
  font-style: normal;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text-tertiary);
}
.ck-today-part.is-hit {
  border-color: var(--ck-accent-line);
  background: var(--ck-accent-soft);
}
.ck-today-part.is-hit em { color: var(--ck-accent); }

/* ---------- 统计 ---------- */
.ck-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
  margin-bottom: 18px;
}
.ck-stat {
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 8px);
  background: var(--bg-secondary);
}
.ck-stat span {
  display: block;
  font-size: .7rem;
  color: var(--text-tertiary);
}
.ck-stat strong {
  font-size: 1.35rem;
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.ck-stat em {
  margin-left: 3px;
  font-style: normal;
  font-size: .7rem;
  color: var(--text-tertiary);
}

/* ---------- 面板 ---------- */
.ck-panel {
  margin-bottom: 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 12px);
  background: var(--bg-secondary);
  overflow: hidden;
}
.ck-panel-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
.ck-panel-head strong {
  font-size: .86rem;
  color: var(--text-primary);
}
.ck-panel-note {
  font-size: .7rem;
  color: var(--text-tertiary);
}

/* ---------- 表格 ---------- */
.ck-table-wrap { overflow-x: auto; }
.ck-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .78rem;
}
.ck-table th,
.ck-table td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
  text-align: left;
  white-space: nowrap;
}
.ck-table th {
  font-size: .7rem;
  font-weight: 600;
  color: var(--text-tertiary);
  background: color-mix(in srgb, var(--bg-primary) 60%, var(--bg-secondary));
}
.ck-table tbody tr:last-child td { border-bottom: 0; }
.ck-table tbody tr:hover { background: color-mix(in srgb, var(--ck-accent) 4%, transparent); }
.ck-table tbody tr.is-hit { background: color-mix(in srgb, var(--ck-accent) 6%, transparent); }
.ck-table tbody tr.is-partial { background: color-mix(in srgb, #f59e0b 7%, transparent); }

.ck-td-name { font-weight: 600; color: var(--text-primary); }
.ck-td-num { text-align: right; font-variant-numeric: tabular-nums; color: var(--text-secondary); }
.ck-td-mid { text-align: center; color: var(--text-secondary); }
.ck-td-parts { color: var(--text-tertiary); font-size: .74rem; white-space: normal; min-width: 200px; }
.ck-td-empty { text-align: center; color: var(--text-tertiary); padding: 20px; }
.ck-unit { margin-left: 3px; font-size: .68rem; color: var(--text-tertiary); }

.ck-tag {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 5px;
  font-size: .68rem;
  font-weight: 600;
}
.ck-tag--ok {
  background: color-mix(in srgb, var(--ck-accent) 14%, transparent);
  color: var(--ck-accent);
}
.ck-tag--warn {
  background: color-mix(in srgb, #f59e0b 16%, transparent);
  color: #b45309;
}

/* ---------- 日历 ---------- */
.ck-cal {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  padding: 14px 16px 16px;
}
.ck-cal-wd {
  text-align: center;
  font-size: .68rem;
  color: var(--text-tertiary);
  padding: 2px 0;
}
.ck-cal-cell {
  position: relative;
  min-height: 44px;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-primary);
}
/*
 * 日历格现在要放「新学 N 条 · 复习 N 条 · 刷题 N 题」几行文字，
 * 比原来只放一个 ✓ 高得多。给足高度并允许换行，否则文字会溢出格子。
 */
.ck-cal-cell.has-detail { min-height: 62px; }
.ck-cal-cell.is-blank { border: 0; background: transparent; }
.ck-cal-cell.is-hit {
  border-color: var(--ck-accent-line);
  background: var(--ck-accent-soft);
}
.ck-cal-cell.is-partial {
  border-color: color-mix(in srgb, #f59e0b 40%, var(--border));
  background: color-mix(in srgb, #f59e0b 8%, var(--bg-primary));
}
.ck-cal-cell.is-today { outline: 2px solid var(--ck-accent); outline-offset: -2px; }
.ck-cal-day { font-size: .68rem; color: var(--text-tertiary); }
.ck-cal-detail {
  display: block;
  margin-top: 2px;
  font-size: .62rem;
  line-height: 1.35;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  word-break: break-word;
}
.ck-cal-mark {
  position: absolute;
  top: 2px;
  right: 5px;
  font-size: .72rem;
  font-weight: 800;
  color: var(--ck-accent);
}

/* ---------- 空态 / 骨架 ---------- */
.ck-empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--text-tertiary);
}
.ck-empty h3 { margin: 0 0 8px; color: var(--text-secondary); font-size: .95rem; }
.ck-empty p { margin: 0 0 14px; font-size: .8rem; }
.ck-skeleton {
  padding: 60px 20px;
  text-align: center;
  color: var(--text-tertiary);
  font-size: .84rem;
}

/* ---------- 窄屏 ---------- */
@media (max-width: 760px) {
  .ck-page { width: calc(100% - 20px); }
  .ck-header { grid-template-columns: 1fr; align-items: start; }
  .ck-header-tools { justify-content: flex-start; }
  .ck-today { grid-template-columns: 1fr; }
  .ck-today-parts { justify-content: flex-start; }
  .ck-stats { grid-template-columns: repeat(2, 1fr); }
  .ck-cal-cell { min-height: 36px; }
  .ck-cal-cell.has-detail { min-height: 54px; }
  .ck-cal-detail { font-size: .58rem; line-height: 1.3; }
}
/* ==== english.css ==== */
/**
 * 英语模块样式 (精简版)
 * 蓝色主题：#3b82f6 / #2563eb
  * 保留 English 特有样式，通用样式由 main.css 提供
 */

/* ===== 变量 ===== */
:root {
  --eng-color: #3b82f6;
  --eng-color-dark: #2563eb;
  --eng-light: rgba(59, 130, 246, 0.08);
  --eng-light-2: rgba(59, 130, 246, 0.15);
  /* Text-safe English blue. #3b82f6 on a white surface is only 3.0:1, so small
     labels use a darker blue in light mode; dark mode restores the lighter one. */
  --eng-ink: #1d4ed8;
}
[data-theme="dark"] { --eng-ink: #7aa8f8; }

/* ===== 通用页头 ===== */
.eng-header { display: flex; align-items: center; gap: 16px; padding: 24px 32px 16px; max-width: 1200px; margin: 0 auto; }
.eng-back-btn { width: 40px; height: 40px; border-radius: 12px; border: 1px solid var(--border); background: var(--bg-secondary); color: var(--text-primary); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.15s ease; }
.eng-back-btn:hover { background: var(--eng-light); color: var(--eng-color); }
.eng-back-btn svg { width: 18px; height: 18px; }
.eng-title-block { flex: 1; min-width: 0; }
.eng-subject-badge { display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px; border-radius: 999px; background: var(--eng-light); border: 1px solid var(--eng-light-2); margin-bottom: 8px; }
.eng-badge-icon { font-size: 18px; }
.eng-badge-text { font-size: 14px; font-weight: 600; color: var(--eng-color); }
.eng-page-title { margin: 0; font-size: 24px; font-weight: 700; color: var(--text-primary); }
.eng-subtitle { margin: 4px 0 0; font-size: 13px; color: var(--text-tertiary); }

/* ===== 涓婚〉锛氫功鏋?===== */
.eng-home { min-height: calc(100vh - 60px); position: relative; padding-bottom: 60px; }
.eng-home-bg { position: absolute; inset: 0; pointer-events: none; background: radial-gradient(circle at 20% 20%, rgba(59,130,246,0.06), transparent 40%), radial-gradient(circle at 80% 80%, rgba(37,99,235,0.04), transparent 40%); z-index: 0; }
.eng-home > * { position: relative; z-index: 1; }
.eng-action-row { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; max-width: 1200px; margin: 0 auto 32px; padding: 0 32px; }
.eng-action-card { display: flex; align-items: center; gap: 16px; padding: 20px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 16px; cursor: pointer; transition: all 0.15s ease; }
.eng-action-card:hover { border-color: var(--eng-color); transform: translateY(-2px); box-shadow: 0 4px 20px var(--eng-light-2); }
.eng-more-tools { max-width: 1200px; margin: 0 auto; padding: 0 32px; }
.eng-more-tools > summary { cursor: pointer; color: var(--text-tertiary); font-size: 13px; padding: 10px 0; }
.eng-more-tools-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px; padding: 4px 0 20px; }
.eng-more-tool { display: grid; grid-template-columns: auto 1fr auto; grid-template-rows: auto auto; align-items: center; gap: 2px 10px; padding: 12px 14px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-secondary); color: var(--text-primary); text-align: left; cursor: pointer; font: inherit; }
.eng-more-tool > svg:first-child { grid-row: 1 / span 2; color: var(--eng-color); width: 18px; height: 18px; }
.eng-more-tool > span { font-size: 13px; font-weight: 650; }
.eng-more-tool > small { color: var(--text-tertiary); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.eng-more-tool > svg:last-child { grid-column: 3; grid-row: 1 / span 2; width: 15px; height: 15px; color: var(--text-tertiary); }
.eng-more-tool:hover { border-color: var(--eng-color); }
@media (max-width: 700px) { .eng-more-tools { padding: 0 16px; } .eng-more-tools-list { grid-template-columns: 1fr; } }
.eng-action-icon { flex-shrink: 0; width: 48px; height: 48px; border-radius: 12px; display: flex; align-items: center; justify-content: center; }
.eng-action-icon--blue { background: rgba(59,130,246,0.1); color: #3b82f6; }
.eng-action-icon--purple { background: rgba(139,92,246,0.1); color: #8b5cf6; }
.eng-action-icon--green { background: rgba(16,185,129,0.1); color: #10b981; }
.eng-action-icon--indigo { background: rgba(99,102,241,0.1); color: #6366f1; }
.eng-action-icon--amber { background: rgba(217,119,6,0.1); color: #d97706; }
.eng-action-icon--rose { background: rgba(225,29,72,0.1); color: #e11d48; }
.eng-action-icon svg { width: 22px; height: 22px; }
.eng-action-info { flex: 1; min-width: 0; }
.eng-action-info h3 { margin: 0 0 4px; font-size: 16px; font-weight: 600; color: var(--text-primary); }
.eng-action-info p { margin: 0; font-size: 13px; color: var(--text-tertiary); }
.eng-action-arrow { width: 18px; height: 18px; color: var(--text-tertiary); flex-shrink: 0; }

.eng-shelf-page { min-height: calc(100vh - 60px); padding-bottom: 60px; }
.eng-shelf-content { max-width: 1200px; margin: 0 auto; padding: 0 24px; }
.eng-shelf-wrap { display: flex; flex-direction: column; gap: 32px; }
.eng-shelf-series { display: flex; flex-direction: column; gap: 14px; }
.eng-shelf-series-header { display: flex; align-items: baseline; gap: 12px; }
.eng-shelf-series-label { margin: 0; font-size: 16px; font-weight: 700; color: var(--text-primary); position: relative; padding-left: 12px; line-height: 1.4; }
.eng-shelf-series-label::before { content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: 4px; height: 16px; border-radius: 2px; background: var(--eng-color); }
.eng-shelf-series-count { font-size: 12px; color: var(--text-tertiary); }
.eng-shelf-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 18px; }

/* 封面卡片 */
.eng-cover-card { display: flex; flex-direction: column; cursor: pointer; border-radius: 10px; outline: none; transition: transform 0.2s ease; }
.eng-cover-card:hover, .eng-cover-card:focus-visible { transform: translateY(-2px); }
.eng-cover-card:focus-visible .eng-cover-img-wrap { box-shadow: 0 0 0 3px var(--eng-color); }

.eng-cover-img-wrap { position: relative; width: 100%; aspect-ratio: 2 / 3; border-radius: 10px; overflow: hidden; background: var(--bg-secondary); box-shadow: 0 4px 12px rgba(0,0,0,0.08); transition: box-shadow 0.2s ease; }
.eng-cover-card:hover .eng-cover-img-wrap, .eng-cover-card:focus-visible .eng-cover-img-wrap { box-shadow: 0 8px 22px rgba(59,130,246,0.28); }

.eng-cover-img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.3s ease; }
.eng-cover-card:hover .eng-cover-img { transform: scale(1.04); }

.eng-cover-img-wrap.img-error { background: linear-gradient(135deg, var(--eng-light), var(--bg-secondary)); }

.eng-cover-fallback { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; background: linear-gradient(135deg, var(--eng-color), var(--eng-color-dark)); color: white; }
.eng-cover-fallback-no { font-size: 24px; font-weight: 700; font-family: 'Georgia', serif; letter-spacing: 0.02em; }
.eng-cover-fallback-sub { font-size: 10px; opacity: 0.75; letter-spacing: 0.12em; }

.eng-cover-vol-badge, .eng-cover-chapters-badge { position: absolute; padding: 3px 8px; font-size: 11px; font-weight: 600; border-radius: 6px; background: rgba(255,255,255,0.92); color: #1e293b; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); box-shadow: 0 1px 4px rgba(0,0,0,0.15); }
.eng-cover-vol-badge { top: 8px; left: 8px; }
.eng-cover-chapters-badge { bottom: 8px; right: 8px; background: rgba(59,130,246,0.92); color: white; }

.eng-cover-meta { padding: 10px 2px 0; }
.eng-cover-title { margin: 0 0 2px; font-size: 13px; font-weight: 600; color: var(--text-primary); line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; word-break: break-word; }
.eng-cover-sub { margin: 0; font-size: 11px; color: var(--text-tertiary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 骨架屏 */
.eng-cover-card.is-skeleton { pointer-events: none; }
.eng-cover-skeleton-img { width: 100%; height: 100%; background: linear-gradient(90deg, var(--bg-secondary) 25%, var(--bg-tertiary) 50%, var(--bg-secondary) 75%); background-size: 200% 100%; animation: engSkeleton 1.5s infinite; }
.eng-cover-skeleton-title { height: 12px; width: 80%; margin-top: 10px; border-radius: 4px; background: linear-gradient(90deg, var(--bg-secondary) 25%, var(--bg-tertiary) 50%, var(--bg-secondary) 75%); background-size: 200% 100%; animation: engSkeleton 1.5s infinite; }
.eng-cover-skeleton-sub { height: 10px; width: 50%; margin-top: 6px; border-radius: 4px; background: linear-gradient(90deg, var(--bg-secondary) 25%, var(--bg-tertiary) 50%, var(--bg-secondary) 75%); background-size: 200% 100%; animation: engSkeleton 1.5s infinite; }
.eng-list-skeleton { height: 64px; border-radius: 8px; background: linear-gradient(90deg, var(--bg-secondary) 25%, var(--bg-tertiary) 50%, var(--bg-secondary) 75%); background-size: 200% 100%; animation: engSkeleton 1.5s infinite; }
@keyframes engSkeleton { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

/* 空状态 */
.eng-shelf-empty { padding: 60px 20px; text-align: center; color: var(--text-tertiary); }
.eng-shelf-empty-icon { font-size: 48px; margin-bottom: 12px; opacity: 0.55; }
.eng-shelf-empty p { margin: 4px 0; font-size: 14px; }
.eng-shelf-empty-hint { font-size: 12px; opacity: 0.7; }

/* ===== 听力训练 ===== */
.eng-study-page {
  width: min(1080px, 100%);
  min-height: calc(100vh - 60px);
  margin: 0 auto;
  padding: 28px 32px 64px;
  box-sizing: border-box;
  color: var(--text-primary);
}

.eng-study-page [hidden] { display: none !important; }

.eng-tool-header {
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 52px;
  margin-bottom: 24px;
}

.eng-tool-header > div { min-width: 0; }
.eng-tool-header h1 { margin: 0; font-size: 24px; line-height: 1.25; letter-spacing: 0; }
.eng-tool-header p { margin: 5px 0 0; color: var(--text-tertiary); font-size: 13px; }

.eng-segmented {
  display: inline-grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(92px, 1fr);
  gap: 3px;
  padding: 3px;
  margin-bottom: 24px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-tertiary);
}

.eng-segmented button {
  min-height: 36px;
  padding: 7px 16px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.eng-segmented button:hover { color: var(--text-primary); }
.eng-segmented button.is-active { background: var(--bg-secondary); color: var(--eng-ink); box-shadow: 0 1px 3px rgba(0,0,0,0.12); }

.eng-study-loading,
.eng-study-empty {
  min-height: 180px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  color: var(--text-tertiary);
  text-align: center;
}

.eng-study-loading svg { width: 24px; height: 24px; animation: engSpin 1s linear infinite; }
.eng-study-empty h2, .eng-study-empty p { margin: 0; }
.eng-study-empty h2 { color: var(--text-primary); font-size: 18px; }
@keyframes engSpin { to { transform: rotate(360deg); } }

.eng-study-section {
  padding: 24px 0;
  border-top: 1px solid var(--border);
}

.eng-study-section:first-child { border-top: 0; padding-top: 0; }
.eng-section-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
.eng-section-heading > div { min-width: 0; }
.eng-section-heading h2 { margin: 0; font-size: 17px; letter-spacing: 0; }
.eng-section-heading p { margin: 4px 0 0; color: var(--text-tertiary); font-size: 12px; }
.eng-section-heading .btn svg, .eng-primary-action .btn svg, .eng-resume-band .btn svg, .eng-generate-row .btn svg { width: 17px; height: 17px; }

.eng-stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 18px; }
.eng-stat { min-height: 92px; padding: 16px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-secondary); box-sizing: border-box; }
.eng-stat span { display: block; color: var(--text-tertiary); font-size: 12px; }
.eng-stat strong { display: block; margin-top: 9px; font-size: 25px; line-height: 1; font-variant-numeric: tabular-nums; }
.eng-stat small { font-size: 12px; color: var(--text-secondary); }

.eng-resume-band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin: 0 0 18px;
  padding: 14px 16px;
  border-left: 3px solid #d97706;
  background: color-mix(in srgb, #d97706 8%, var(--bg-secondary));
}

.eng-resume-band > div { display: flex; flex-direction: column; gap: 3px; }
.eng-resume-band span { color: var(--text-secondary); font-size: 12px; }
.eng-resume-band strong { font-size: 16px; }

.eng-primary-action { display: flex; justify-content: flex-end; margin-top: 18px; }

.eng-listening-options input,
.eng-listening-options select,
.eng-answer-panel textarea {
  min-width: 0;
  min-height: 40px;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--bg-secondary);
  color: var(--text-primary);
  font: inherit;
  font-size: 13px;
  box-sizing: border-box;
}

.eng-listening-options input:focus,
.eng-answer-panel textarea:focus { outline: 2px solid var(--eng-light-2); border-color: var(--eng-color); }
.eng-listening-layout { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(300px, .7fr); gap: 36px; align-items: start; }
.eng-listening-builder { min-width: 0; }
.eng-listening-history { position: sticky; top: 76px; min-width: 0; }
.eng-listening-history .eng-section-heading { margin-bottom: 10px; }
.eng-listening-options { display: grid; grid-template-columns: minmax(0, 1fr) 180px; gap: 14px; padding-top: 4px; }
.eng-listening-options label { display: grid; gap: 7px; color: var(--text-secondary); font-size: 12px; font-weight: 600; }
.eng-generate-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border-light); }
.eng-provider-status { color: #b45309; font-size: 11px; }
.eng-provider-status.is-ready { color: #15803d; }
.eng-listening-progress { margin-top: 18px; padding: 14px; border: 1px solid color-mix(in srgb, var(--eng-color) 18%, var(--border)); border-radius: 8px; background: color-mix(in srgb, var(--eng-color) 4%, var(--bg-secondary)); }
.eng-listening-progress-top { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; align-items: center; gap: 10px; }
.eng-listening-progress-icon { width: 28px; height: 28px; display: grid; place-items: center; border-radius: 6px; background: var(--eng-light); color: var(--eng-color); }
.eng-listening-progress-icon svg { width: 16px; height: 16px; }
.eng-listening-progress.is-working .eng-listening-progress-icon svg { animation: engSpin 1s linear infinite; }
.eng-listening-progress.is-error { border-color: rgba(220, 38, 38, .35); }
.eng-listening-progress.is-error .eng-listening-progress-icon { background: rgba(220, 38, 38, .1); color: #b91c1c; }
.eng-listening-progress-top div { min-width: 0; display: grid; gap: 3px; }
.eng-listening-progress-top strong { font-size: 13px; }
.eng-listening-progress-top small { overflow-wrap: anywhere; color: var(--text-tertiary); font-size: 11px; line-height: 1.45; }
.eng-listening-progress-top b { color: var(--eng-color); font-size: 13px; font-variant-numeric: tabular-nums; }
.eng-listening-progress-track { height: 5px; margin-top: 13px; overflow: hidden; border-radius: 999px; background: var(--bg-tertiary); }
.eng-listening-progress-track i { display: block; height: 100%; border-radius: inherit; background: var(--eng-color); transition: width .35s ease; }
.eng-listening-progress-meta { display: flex; justify-content: space-between; gap: 10px; margin-top: 9px; color: var(--text-tertiary); font-size: 11px; font-variant-numeric: tabular-nums; }
.eng-history-list { display: grid; border-top: 1px solid var(--border-light); }
.eng-history-row { display: grid; grid-template-columns: 54px minmax(0, 1fr) 44px; align-items: center; gap: 12px; min-height: 72px; padding: 9px 8px; border: 0; border-bottom: 1px solid var(--border-light); background: transparent; color: var(--text-primary); text-align: left; cursor: pointer; transition: background .15s ease, padding .15s ease; }
.eng-history-row:hover { padding-left: 12px; background: color-mix(in srgb, var(--eng-color) 5%, var(--bg-hover)); }
.eng-history-row > span:nth-child(2) { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.eng-history-row strong, .eng-history-row small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.eng-history-row strong { font-size: 14px; }
.eng-history-row small { color: var(--text-tertiary); font-size: 11px; }
.eng-history-mode { width: 44px; padding: 4px 5px; border-radius: 5px; background: var(--bg-tertiary); color: var(--text-secondary); font-size: 10px; text-align: center; }
.eng-history-row > b { color: var(--eng-color); font-size: 18px; text-align: center; }
.eng-history-row > i { width: 24px; height: 24px; color: var(--text-tertiary); justify-self: center; }
.eng-history-row > i svg { width: 100%; height: 100%; }

.eng-listening-session { width: min(820px, 100%); }
.eng-listening-session-main { display: grid; gap: 0; }
.eng-audio-panel { padding: 20px; border: 1px solid color-mix(in srgb, var(--eng-color) 20%, var(--border)); border-radius: 8px; background: color-mix(in srgb, var(--eng-color) 4%, var(--bg-secondary)); }
.eng-audio-panel.eng-study-section:first-child { padding-top: 20px; }
.eng-audio-title { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.eng-audio-title > span:first-child { width: 38px; height: 38px; display: grid; place-items: center; border-radius: 7px; background: rgba(225,29,72,.1); color: #e11d48; }
.eng-audio-title svg { width: 18px; height: 18px; }
.eng-audio-title > div { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.eng-audio-title strong { overflow-wrap: anywhere; font-size: 15px; }
.eng-audio-title small { color: var(--text-tertiary); font-size: 11px; }
.eng-listening-badge { margin-left: auto; padding: 4px 7px; border: 1px solid var(--border); border-radius: 5px; color: var(--text-tertiary); font-size: 10px; white-space: nowrap; }
.eng-audio-panel audio { width: 100%; height: 46px; }
.eng-playback-rate { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 14px; }
.eng-playback-rate > span { color: var(--text-tertiary); font-size: 11px; font-weight: 700; }
.eng-playback-rate-options { display: inline-grid; grid-template-columns: repeat(4, minmax(48px, 1fr)); gap: 3px; padding: 3px; border: 1px solid var(--border); border-radius: 7px; background: var(--bg-tertiary); }
.eng-playback-rate-options button { min-width: 48px; min-height: 28px; padding: 4px 7px; border: 0; border-radius: 5px; background: transparent; color: var(--text-secondary); font: inherit; font-size: 11px; font-weight: 700; cursor: pointer; font-variant-numeric: tabular-nums; }
.eng-playback-rate-options button:hover { color: var(--text-primary); background: var(--bg-hover); }
.eng-playback-rate-options button.is-active { background: var(--bg-secondary); color: var(--eng-color); box-shadow: 0 1px 3px rgba(0,0,0,.12); }
.eng-audio-status { min-height: 48px; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 12px; border: 1px dashed var(--border-hover); border-radius: 7px; color: var(--text-secondary); font-size: 12px; box-sizing: border-box; }
.eng-audio-status.is-error { color: #b91c1c; }
.eng-target-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }
.eng-target-tags span { padding: 4px 7px; border-radius: 5px; background: var(--eng-light); color: var(--eng-color); font-size: 11px; }
.eng-audio-actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 16px; padding-top: 14px; border-top: 1px solid color-mix(in srgb, var(--eng-color) 14%, var(--border)); }
.eng-audio-actions .btn { gap: 6px; }
.eng-audio-actions .btn svg { width: 15px; height: 15px; }
.eng-audio-actions > span { color: var(--text-tertiary); font-size: 11px; }
.eng-answer-panel { padding-top: 30px; }
.eng-answer-panel textarea { width: 100%; min-height: 170px; resize: vertical; line-height: 1.7; background: var(--bg-secondary); }
.eng-listening-result { display: grid; grid-template-columns: 90px minmax(0, 1fr); align-items: center; gap: 20px; }
.eng-score-ring { width: 82px; aspect-ratio: 1; display: grid; place-content: center; justify-items: center; border: 6px solid #dc2626; border-radius: 50%; box-sizing: border-box; }
.eng-score-ring.is-mid { border-color: #d97706; }
.eng-score-ring.is-high { border-color: #16a34a; }
.eng-score-ring strong { font-size: 25px; line-height: 1; }
.eng-score-ring span { margin-top: 3px; color: var(--text-tertiary); font-size: 10px; }
.eng-result-copy h2 { margin: 0 0 7px; font-size: 17px; }
.eng-result-copy p { margin: 0; color: var(--text-secondary); font-size: 13px; line-height: 1.7; }
.eng-dimension-grid { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.eng-dimension-grid > div { padding: 10px; border: 1px solid var(--border); border-radius: 7px; }
.eng-dimension-grid span { display: block; color: var(--text-tertiary); font-size: 10px; }
.eng-dimension-grid strong { display: block; margin-top: 5px; font-size: 17px; }
.eng-feedback-list { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.eng-feedback-list strong { margin-right: 4px; font-size: 12px; }
.eng-feedback-list span { padding: 5px 7px; border-radius: 5px; background: rgba(217,119,6,.1); color: #b45309; font-size: 11px; }
.eng-feedback-list.is-good span { background: rgba(22,163,74,.1); color: #15803d; }
.eng-transcript-panel { padding: 20px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-secondary); }
.eng-transcript-panel.eng-study-section { margin-top: 24px; }
.eng-transcript-copy { margin: 0; padding: 18px 20px; border-left: 3px solid var(--eng-color); background: color-mix(in srgb, var(--eng-color) 5%, var(--bg-tertiary)); color: var(--text-secondary); font-family: Georgia, 'Times New Roman', serif; font-size: 15px; line-height: 1.95; white-space: pre-wrap; }
.eng-reference-summary { margin-top: 16px; padding: 14px 16px; border: 1px solid color-mix(in srgb, #15803d 20%, var(--border)); border-radius: 7px; background: color-mix(in srgb, #16a34a 5%, var(--bg-secondary)); }
.eng-reference-summary span { color: #15803d; font-size: 11px; font-weight: 700; }
.eng-reference-summary p { margin: 6px 0 0; color: var(--text-secondary); font-size: 13px; line-height: 1.7; }
.eng-word-notes { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-top: 18px; }
.eng-word-notes span { display: flex; gap: 8px; padding: 8px 10px; border-left: 2px solid var(--eng-color); background: var(--bg-tertiary); color: var(--text-secondary); font-size: 12px; }
.eng-word-notes strong { color: var(--text-primary); }

@media (max-width: 720px) {
  .eng-study-page { padding: 18px 16px 44px; }
  .eng-tool-header { margin-bottom: 18px; }
  .eng-tool-header h1 { font-size: 20px; }
  .eng-segmented { display: grid; grid-auto-columns: minmax(0, 1fr); width: 100%; box-sizing: border-box; }
  .eng-stat-grid { grid-template-columns: repeat(2, 1fr); }
  .eng-stat { min-height: 82px; }
  .eng-resume-band { align-items: flex-start; flex-direction: column; }
  .eng-resume-band .btn { width: 100%; justify-content: center; }
  .eng-section-heading { align-items: flex-start; }
  .eng-listening-layout { grid-template-columns: 1fr; gap: 0; }
  .eng-listening-history { position: static; }
  .eng-listening-options { grid-template-columns: 1fr; }
  .eng-generate-row { align-items: stretch; flex-direction: column; }
  .eng-generate-row .btn { width: 100%; justify-content: center; }
  .eng-listening-result { grid-template-columns: 72px minmax(0, 1fr); gap: 14px; }
  .eng-score-ring { width: 68px; border-width: 5px; }
  .eng-dimension-grid { grid-template-columns: repeat(2, 1fr); }
  .eng-word-notes { grid-template-columns: 1fr; }
  .eng-audio-panel { padding: 16px; }
  .eng-audio-actions { align-items: flex-start; flex-direction: column; }
  .eng-playback-rate { align-items: flex-start; flex-direction: column; }
  .eng-playback-rate-options { width: 100%; }
  .eng-playback-rate-options button { min-width: 0; }
  .eng-transcript-panel { padding: 16px; }
  .eng-transcript-copy { padding: 15px; font-size: 14px; }
  .eng-action-row { grid-template-columns: 1fr; padding: 0 16px; }
}

@media (max-width: 420px) {
  .eng-study-page { padding-left: 12px; padding-right: 12px; }
  .eng-stat-grid { gap: 7px; }
  .eng-stat { padding: 13px; }
  .eng-history-row { grid-template-columns: 44px minmax(0, 1fr) 36px; gap: 8px; }
}

/* ===== Reader Page ===== */

/* Reading progress bar */
.eng-reading-progress{position:fixed;top:var(--nav-height);left:0;right:0;height:3px;z-index:102;background:transparent;pointer-events:none}
.eng-reading-progress-fill{height:100%;width:0;background:linear-gradient(90deg,var(--eng-color),var(--eng-color-dark));transition:width 0.12s ease;border-radius:0 2px 2px 0;box-shadow:0 0 6px rgba(59,130,246,0.4)}

/* Main reader container */
.eng-reader{min-height:calc(100vh - var(--nav-height));display:flex;flex-direction:column;background:var(--bg-primary);transition:background 0.3s ease}
.eng-reader.night{background:#1a1814;color:#ccc5b9}

/* Bottom bar — glass morphism */
.eng-reader-bottombar{position:fixed;bottom:0;left:0;right:0;z-index:101;background:var(--surface-strong);border-top:1px solid var(--border);display:flex;flex-direction:column;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);box-shadow:0 -6px 20px rgba(0,0,0,0.06)}
.eng-reader.night .eng-reader-bottombar{background:rgba(30,28,25,0.93);border-color:rgba(255,255,255,0.09)}

/* Topbar */
.eng-reader-topbar{display:flex;align-items:center;gap:10px;padding:10px 20px;max-width:720px;margin:0 auto;width:100%;box-sizing:border-box}
.eng-reader-btn{display:flex;align-items:center;gap:5px;padding:7px 13px;border:1px solid var(--border);border-radius:var(--radius-full,999px);background:transparent;color:var(--text-secondary);cursor:pointer;font-size:12px;font-weight:500;transition:all 0.15s;white-space:nowrap;min-height:44px;min-width:44px}
.eng-reader-btn:hover{background:var(--eng-light);color:var(--eng-color);border-color:var(--eng-color)}
.eng-reader-btn svg{width:14px;height:14px}
.eng-reader.night .eng-reader-btn{border-color:rgba(255,255,255,0.14);color:#9a9184}
.eng-reader.night .eng-reader-btn:hover{background:rgba(59,130,246,0.15);color:#93c5fd;border-color:rgba(59,130,246,0.3)}
.eng-reader-title{flex:1;text-align:center;font-size:13px;font-weight:600;color:var(--text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:0.01em}
.eng-reader.night .eng-reader-title{color:#7a7468}

/* Chapter navigation row */
.eng-reader-nav{display:flex;gap:8px;padding:8px 20px 0;border-bottom:1px solid var(--border);max-width:720px;width:100%;margin:0 auto;box-sizing:border-box}
.eng-reader.night .eng-reader-nav{border-color:rgba(255,255,255,0.08)}
.eng-nav-btn{flex:1;display:flex;align-items:center;justify-content:center;gap:5px;padding:9px 12px;border:1px solid var(--border);border-radius:var(--radius-lg,16px);background:var(--bg-secondary);color:var(--text-secondary);cursor:pointer;font-size:13px;font-weight:500;transition:all 0.15s}
.eng-nav-btn:hover{background:var(--eng-light);color:var(--eng-color);border-color:var(--eng-color);transform:translateY(-1px)}
.eng-nav-btn svg{width:15px;height:15px}
.eng-reader.night .eng-nav-btn{background:rgba(255,255,255,0.04);border-color:rgba(255,255,255,0.1);color:#9a9184}
.eng-reader.night .eng-nav-btn:hover{background:rgba(59,130,246,0.12);color:#93c5fd;border-color:rgba(59,130,246,0.25)}

/* Reading body */
.eng-reader-body{flex:1;max-width:680px;width:100%;margin:0 auto;padding:28px 24px 172px;font-size:var(--rs-fs,18px);line-height:var(--rs-lh,1.85)}
.eng-reader.night .eng-reader-body{color:#ccc5b9}
.eng-reader-loading,.eng-reader-error{text-align:center;padding:80px 0;color:var(--text-tertiary);font-size:14px}
.eng-reader-error{color:#ef4444}

/* Chapter heading */
.eng-chapter-heading{font-size:1.5em;font-weight:700;margin:0 0 40px;color:var(--text-primary);text-align:center;line-height:1.3;position:relative;padding-bottom:28px}
.eng-chapter-heading::after{content:'';position:absolute;bottom:0;left:50%;transform:translateX(-50%);width:48px;height:2px;background:linear-gradient(90deg,transparent,var(--eng-color),transparent);border-radius:2px}
.eng-reader.night .eng-chapter-heading{color:#e8e0d5}

/* Content typography */
.eng-chapter-content{font-family:'Georgia','Times New Roman',serif;color:var(--text-primary)}
.eng-reader.night .eng-chapter-content{color:#ccc5b9}
.eng-paragraph{margin:0 0 1.4em;text-indent:2em;text-align:justify;letter-spacing:0.005em}
.eng-chapter-content>.eng-paragraph:first-child::first-letter{font-size:2.8em;font-weight:700;float:left;line-height:0.82;margin:0.1em 0.08em -0.1em 0;color:var(--eng-color);font-family:'Georgia',serif}
.eng-reader.night .eng-chapter-content>.eng-paragraph:first-child::first-letter{color:#93c5fd}

/* ===== 章节插图 ===== */
.eng-illustration{margin:1.6em 0;text-align:center;page-break-inside:avoid;break-inside:avoid}
.eng-illustration.eng-illus-leading{margin-top:0;margin-bottom:1.6em}
.eng-illus-img{max-width:100%;max-height:60vh;border-radius:8px;box-shadow:0 2px 12px rgba(0,0,0,0.1)}
.eng-reader.night .eng-illus-img{box-shadow:0 2px 12px rgba(0,0,0,0.3)}

/* 章节导航条（在底部工具栏内） */
.eng-reader-nav { display: flex; gap: 12px; padding: 8px 24px; border-bottom: 1px solid var(--border); max-width: 720px; width: 100%; margin: 0 auto; box-sizing: border-box; }
.eng-reader.night .eng-reader-nav { border-color: #3a3a3a; }
.eng-nav-btn { flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px; padding: 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-primary); color: var(--text-secondary); cursor: pointer; font-size: 13px; transition: all 0.15s ease; min-height: 44px; min-width: 44px; }
.eng-nav-btn:hover { background: var(--eng-light); color: var(--eng-color); border-color: var(--eng-color); }
.eng-nav-btn svg { width: 16px; height: 16px; }

/* ===== 阅读设置弹层 ===== */
.eng-settings-overlay { position: fixed; inset: 0; z-index: 9999; background: rgba(0,0,0,0.5); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; padding: 20px; animation: engFadeIn 0.2s ease; }
@keyframes engFadeIn { from { opacity: 0; } to { opacity: 1; } }
.eng-settings-dialog { width: 100%; max-width: 420px; max-height: 90vh; overflow-y: auto; background: var(--bg-secondary); border-radius: 16px; border: 1px solid var(--border); box-shadow: 0 20px 60px rgba(0,0,0,0.3); }
.eng-settings-header { display: flex; align-items: center; justify-content: space-between; padding: 20px 24px; border-bottom: 1px solid var(--border); }
.eng-settings-header h3 { margin: 0; font-size: 17px; font-weight: 600; color: var(--text-primary); }
.eng-settings-close { width: 32px; height: 32px; border: none; background: transparent; color: var(--text-tertiary); cursor: pointer; display: flex; align-items: center; justify-content: center; border-radius: 8px; }
.eng-settings-close:hover { background: var(--bg-tertiary); }
.eng-settings-body { padding: 20px 24px; }
.eng-settings-row { display: flex; align-items: center; justify-content: space-between; padding: 12px 0; }
.eng-settings-row > label { font-size: 14px; font-weight: 500; color: var(--text-primary); }
.eng-settings-controls { display: flex; align-items: center; gap: 12px; }
.eng-step-btn { width: 32px; height: 32px; border: 1px solid var(--border); background: var(--bg-primary); color: var(--text-primary); border-radius: 8px; cursor: pointer; font-size: 16px; font-weight: 600; transition: all 0.15s ease; }
.eng-step-btn:hover { background: var(--eng-color); color: white; border-color: var(--eng-color); }
.eng-step-value { min-width: 50px; text-align: center; font-size: 13px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.eng-switch { position: relative; display: inline-block; width: 44px; height: 24px; cursor: pointer; }
.eng-switch input { opacity: 0; width: 0; height: 0; }
.eng-switch-slider { position: absolute; inset: 0; background: var(--bg-tertiary); border-radius: 999px; transition: 0.2s; }
.eng-switch-slider::before { content: ''; position: absolute; width: 18px; height: 18px; left: 3px; top: 3px; background: white; border-radius: 50%; transition: 0.2s; box-shadow: 0 1px 3px rgba(0,0,0,0.2); }
.eng-switch input:checked + .eng-switch-slider { background: var(--eng-color); }
.eng-switch input:checked + .eng-switch-slider::before { transform: translateX(20px); }
.eng-settings-divider { height: 1px; background: var(--border); margin: 16px 0; }
.eng-settings-section-title { font-size: 13px; font-weight: 600; color: var(--text-secondary); margin-bottom: 12px; }
.eng-cat-list { display: flex; flex-direction: column; gap: 8px; }
.eng-cat-item { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; cursor: pointer; transition: all 0.15s ease; }
.eng-cat-item:hover { background: var(--eng-light); }
.eng-cat-item input[type="checkbox"] { margin-top: 2px; accent-color: var(--eng-color); }
.eng-cat-info { flex: 1; }
.eng-cat-name { font-size: 13px; font-weight: 500; color: var(--text-primary); }
.eng-cat-desc { font-size: 11px; color: var(--text-tertiary); margin-top: 2px; }
.eng-cat-hint { font-size: 11px; color: var(--text-tertiary); margin: 12px 0 0; line-height: 1.5; }
.eng-settings-reload { width: 100%; margin-top: 16px; padding: 12px; border: none; border-radius: 10px; background: var(--eng-color); color: white; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.15s ease; }
.eng-settings-reload:hover { background: var(--eng-color-dark); }

/* ===== 鍒掕瘝缈昏瘧 ===== */
.eng-translate-fab { position: fixed; z-index: 1100; bottom: 124px; right: 16px; width: 48px; height: 48px; border-radius: 50%; border: none; background: linear-gradient(135deg, var(--eng-color), var(--eng-color-dark)); color: white; font-size: 17px; font-weight: 700; cursor: pointer; display: none; align-items: center; justify-content: center; box-shadow: 0 4px 16px rgba(59,130,246,0.4), 0 2px 6px rgba(0,0,0,0.15); -webkit-tap-highlight-color: transparent; user-select: none; transition: transform 0.12s ease, opacity 0.15s ease; }
.eng-translate-fab:active { transform: scale(0.92); }
.eng-translate-fab span { pointer-events: none; line-height: 1; text-shadow: 0 1px 2px rgba(0,0,0,0.2); }
.eng-note-fab { position: fixed; z-index: 1100; bottom: 124px; left: 16px; width: 48px; height: 48px; border-radius: 50%; border: none; background: linear-gradient(135deg, #10b981, #059669); color: white; font-size: 17px; font-weight: 700; cursor: pointer; display: none; align-items: center; justify-content: center; box-shadow: 0 4px 16px rgba(16,185,129,0.35); transition: all 0.15s ease; }
.eng-note-fab:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(16,185,129,0.45); }
.eng-note-fab:active { transform: scale(0.92); }
.eng-note-fab span { pointer-events: none; line-height: 1; text-shadow: 0 1px 2px rgba(0,0,0,0.2); }
.eng-translate-overlay { position: fixed; inset: 0; z-index: 1200; background: rgba(0,0,0,0.35); display: flex; align-items: flex-end; justify-content: center; opacity: 0; transition: opacity 0.25s ease; }
.eng-translate-overlay.show { opacity: 1; }
.eng-translate-sheet { width: 100%; max-width: 720px; max-height: 70vh; background: var(--bg-secondary); border-radius: 20px 20px 0 0; box-shadow: 0 -8px 40px rgba(0,0,0,0.25); display: flex; flex-direction: column; transform: translateY(100%); transition: transform 0.28s cubic-bezier(0.22,1,0.36,1); overflow: hidden; }
.eng-translate-overlay.show .eng-translate-sheet { transform: translateY(0); }
.eng-translate-handle { flex-shrink: 0; width: 36px; height: 4px; background: var(--border); border-radius: 2px; margin: 10px auto 4px; }
.eng-translate-header { flex-shrink: 0; display: flex; align-items: flex-start; gap: 12px; padding: 8px 20px 14px; border-bottom: 1px solid var(--border); }
.eng-translate-source { flex: 1; min-width: 0; font-size: 14px; font-family: 'Georgia', serif; color: var(--text-secondary); line-height: 1.5; word-break: break-word; white-space: pre-wrap; max-height: 5em; overflow-y: auto; }
.eng-translate-close { flex-shrink: 0; width: 32px; height: 32px; border: none; background: transparent; color: var(--text-tertiary); font-size: 24px; line-height: 1; cursor: pointer; border-radius: 8px; display: flex; align-items: center; justify-content: center; -webkit-tap-highlight-color: transparent; }
.eng-translate-close:hover { background: var(--bg-tertiary); color: var(--text-primary); }
.eng-translate-body { flex: 1; overflow-y: auto; padding: 16px 20px 24px; -webkit-overflow-scrolling: touch; }
.eng-translate-loading { text-align: center; padding: 32px 0; color: var(--text-tertiary); font-size: 14px; }
.eng-translate-loading::before { content: ''; display: inline-block; width: 16px; height: 16px; margin-right: 8px; border: 2px solid var(--eng-light-2); border-top-color: var(--eng-color); border-radius: 50%; vertical-align: middle; animation: engSpin 0.8s linear infinite; }
@keyframes engSpin { to { transform: rotate(360deg); } }
.eng-translate-footer { flex-shrink: 0; padding: 10px 16px; border-top: 1px solid var(--border); background: var(--bg-secondary); border-radius: 0 0 16px 16px; }
.eng-translate-add-note { width: 100%; min-height: 42px; padding: 10px; border: 0; border-radius: 10px; background: var(--eng-color); color: white; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.15s ease; display: flex; align-items: center; justify-content: center; gap: 7px; }
.eng-translate-add-note svg { width: 16px; height: 16px; }
.eng-translate-add-note:hover:not(:disabled) { background: var(--eng-color-dark); }
.eng-translate-add-note:disabled { background: var(--bg-tertiary); color: var(--text-tertiary); cursor: not-allowed; }
.eng-translate-error { padding: 16px; border-radius: 10px; background: rgba(239,68,68,0.08); color: #ef4444; font-size: 13px; line-height: 1.6; word-break: break-word; }

/* 词典结果 */
.eng-tr-dict { display: flex; flex-direction: column; gap: 8px; }
.eng-tr-word { font-size: 20px; font-weight: 700; color: var(--text-primary); font-family: 'Georgia', serif; }
.eng-tr-pos { font-size: 13px; font-weight: 500; color: var(--eng-color); font-family: inherit; }
.eng-tr-phonetic { font-size: 14px; color: var(--text-tertiary); font-family: 'Georgia', serif; }
.eng-tr-def { font-size: 15px; color: var(--text-primary); line-height: 1.7; }
.eng-tr-freq { font-size: 12px; color: var(--text-tertiary); padding: 2px 8px; background: var(--bg-tertiary); border-radius: 6px; align-self: flex-start; }
.eng-tr-phrases { margin: 12px 0 0; padding: 10px 12px; background: rgba(59,130,246,0.05); border-radius: 8px; border: 1px solid rgba(59,130,246,0.12); }
.eng-tr-phrases-title { font-size: 13px; font-weight: 600; color: var(--eng-color); margin-bottom: 8px; }
.eng-tr-phrases-list { display: flex; flex-direction: column; gap: 4px; padding-left: 0; list-style: none; }
.eng-tr-phrases-list li { display: flex; flex-wrap: wrap; gap: 8px; font-size: 13px; line-height: 1.5; }
.eng-tr-phrase { font-weight: 500; color: #1e293b; }
.eng-tr-phrase-meaning { color: #64748b; }
.eng-tr-cats { display: flex; flex-wrap: wrap; gap: 6px; }
.eng-tr-cat { font-size: 11px; padding: 2px 8px; border-radius: 999px; background: var(--eng-light); color: var(--eng-color); border: 1px solid var(--eng-light-2); }
.eng-tr-examples { margin: 8px 0 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }
.eng-tr-examples li { font-size: 13px; line-height: 1.6; color: var(--text-secondary); font-family: 'Georgia', serif; }
.eng-tr-source { font-size: 11px; color: var(--text-tertiary); margin-top: 4px; }
.eng-tr-contextual { margin-bottom: 14px; padding: 12px 14px; border: 1px solid color-mix(in srgb, var(--eng-color) 20%, var(--border)); border-left: 3px solid var(--eng-color); border-radius: 0 10px 10px 0; background: color-mix(in srgb, var(--eng-color) 6%, transparent); }
.eng-tr-section-label, .eng-gr-label { margin-bottom: 7px; color: var(--eng-color); font-size: 11px; font-weight: 700; letter-spacing: .04em; }
.eng-tr-translation { color: var(--text-primary); font-size: 17px; font-weight: 650; line-height: 1.65; }
.eng-tr-sense-meta { margin-top: 5px; color: var(--eng-color); font-size: 12px; }
.eng-tr-sense, .eng-tr-note, .eng-tr-alternatives { margin-top: 7px; color: var(--text-secondary); font-size: 13px; line-height: 1.6; }
.eng-tr-note { padding: 6px 8px; border-radius: 6px; background: color-mix(in srgb, #d28a24 10%, transparent); }
.eng-tr-alternatives { color: var(--text-tertiary); }
.eng-tr-dict { padding-top: 2px; }
.eng-tr-llm { font-size: 15px; line-height: 1.75; color: var(--text-primary); white-space: pre-wrap; word-break: break-word; }
.eng-grammar-section { margin-top: 20px; padding-top: 16px; border-top: 0.5px dashed var(--border); }
.eng-grammar-title { font-size: 13px; font-weight: 600; color: var(--eng-color); margin-bottom: 12px; display: flex; align-items: center; gap: 6px; letter-spacing: 0.02em; }
.eng-grammar-title::before { content: ''; width: 3px; height: 14px; background: var(--eng-color); border-radius: 2px; }
.eng-grammar-content { font-size: 14px; line-height: 1.8; color: var(--text-primary); white-space: pre-wrap; word-break: break-word; }
.eng-gr-summary { margin: 0 0 12px; color: var(--text-primary); line-height: 1.7; }
.eng-gr-block { margin-top: 12px; }
.eng-gr-block p { margin: 0; color: var(--text-secondary); line-height: 1.7; }
.eng-gr-list, .eng-gr-bullets { margin: 0; padding-left: 18px; color: var(--text-secondary); }
.eng-gr-list { list-style: none; padding-left: 0; }
.eng-gr-list li { display: flex; flex-wrap: wrap; gap: 7px; margin: 5px 0; line-height: 1.6; }
.eng-gr-list li strong { color: var(--text-primary); font-family: Georgia, serif; }
.eng-gr-list li span { color: var(--text-secondary); }
.eng-gr-bullets li { margin: 4px 0; }
.eng-gr-legacy { white-space: pre-wrap; }

/* ===== 绌虹姸鎬?===== */
.eng-empty { grid-column: 1 / -1; text-align: center; padding: 60px 20px; color: var(--text-tertiary); }
.eng-empty-icon { font-size: 48px; margin-bottom: 12px; opacity: 0.5; }
.eng-empty p { margin: 4px 0; font-size: 14px; }
.eng-empty-hint { font-size: 12px !important; opacity: 0.7; }

/* ===== 绗旇鏈〉闈?===== */
/* ========== 笔记本（Linear v6.0） ========== */
.nb-page { min-height: calc(100vh - 60px); padding-bottom: 60px; --nb: #0e9f6e; --nb-light: rgba(14,159,110,0.1); }
[data-theme="dark"] .nb-page, [data-theme="dark"] .nb-cat-overlay, [data-theme="dark"] .nb-reanalyze-overlay, [data-theme="dark"] .nb-annotation-overlay { --nb: #3ecf8e; --nb-light: rgba(62,207,142,0.12); }
.nb-header { display: flex; align-items: center; gap: 14px; padding: 24px 32px 14px; max-width: 980px; margin: 0 auto; }
.nb-back-btn { width: 36px; height: 36px; border-radius: var(--radius-md); border: 1px solid var(--border); background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all var(--transition-fast); flex-shrink: 0; }
.nb-back-btn:hover { background: var(--bg-hover); color: var(--text-primary); border-color: var(--border-hover); }
.nb-back-btn svg { width: 18px; height: 18px; }
.nb-title-block { flex: 1; min-width: 0; }
.nb-badge { display: inline-flex; align-items: center; gap: 8px; }
.nb-badge-icon { font-size: 17px; }
.nb-badge-text { font-size: 17px; font-weight: 700; color: var(--text-primary); letter-spacing: -0.02em; }
.nb-subtitle { margin: 2px 0 0; font-size: 12.5px; color: var(--text-tertiary); font-variant-numeric: tabular-nums; }
.nb-quiz-entry { display: inline-flex; align-items: center; gap: 7px; height: 36px; padding: 0 14px; border: 1px solid color-mix(in srgb, var(--nb) 35%, transparent); border-radius: var(--radius-md); background: var(--nb-light); color: var(--nb); cursor: pointer; font-size: 13px; font-weight: 600; transition: all var(--transition-fast); flex-shrink: 0; }
.nb-quiz-entry:hover { background: var(--nb); color: #fff; border-color: var(--nb); }
.nb-quiz-entry-icon { font-size: 15px; line-height: 1; }
@media (max-width: 560px) { .nb-quiz-entry-label { display: none; } .nb-quiz-entry { width: 36px; padding: 0; justify-content: center; } }

/* 工具栏 */
.nb-toolbar { max-width: 980px; margin: 0 auto 14px; padding: 0 32px; display: flex; flex-direction: column; gap: 10px; }
.nb-search-row { display: flex; gap: 8px; }
.nb-search-wrap { position: relative; flex: 1; display: flex; align-items: center; }
.nb-search-icon { position: absolute; left: 12px; display: flex; align-items: center; pointer-events: none; color: var(--text-tertiary); }
.nb-search-icon svg { width: 15px; height: 15px; }
.nb-search-input { width: 100%; padding: 9px 34px 9px 36px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-secondary); color: var(--text-primary); font-size: 14px; outline: none; transition: border-color var(--transition-fast), box-shadow var(--transition-fast); }
.nb-search-input:focus { border-color: var(--nb); box-shadow: 0 0 0 3px color-mix(in srgb, var(--nb) 18%, transparent); }
.nb-search-input::placeholder { color: var(--text-tertiary); }
.nb-search-clear { position: absolute; right: 8px; width: 22px; height: 22px; border: 0; border-radius: var(--radius-sm); background: var(--bg-tertiary); color: var(--text-tertiary); font-size: 11px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all var(--transition-fast); }
.nb-search-clear:hover { background: var(--bg-active); color: var(--text-primary); }
.nb-search-clear.hidden { display: none; }
.nb-search-btn { padding: 0 18px; border: 0; border-radius: var(--radius-md); background: var(--nb); color: white; font-size: 13.5px; font-weight: 600; cursor: pointer; transition: all var(--transition-fast); box-shadow: inset 0 1px 0 rgba(255,255,255,0.1); }
.nb-search-btn:hover { background: color-mix(in srgb, var(--nb) 85%, #000); }
[data-theme="dark"] .nb-search-btn { color: #08090a; }
[data-theme="dark"] .nb-search-btn:hover { background: color-mix(in srgb, var(--nb) 85%, #fff); }

/* 大分类（句子/短语）— 分段控件风格 */
.nb-filter-row { display: flex; align-items: center; gap: 10px; }
.nb-major-row { display: inline-flex; gap: 2px; padding: 3px; background: var(--bg-tertiary); border: 1px solid var(--border-light); border-radius: var(--radius-md); width: fit-content; }
.nb-major-btn { padding: 5px 14px; border: 1px solid transparent; border-radius: var(--radius-sm); background: transparent; color: var(--text-secondary); font-size: 12.5px; font-weight: 600; cursor: pointer; transition: all var(--transition-fast); white-space: nowrap; font-variant-numeric: tabular-nums; }
.nb-major-btn:hover { color: var(--text-primary); }
.nb-major-btn.active { background: var(--bg-secondary); color: var(--accent); border-color: var(--border); box-shadow: var(--shadow-sm); }

/* 子分类 chips */
.nb-category-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.nb-cat-btn { padding: 4px 12px; border: 1px solid var(--border); border-radius: var(--radius-full); background: transparent; color: var(--text-secondary); font-size: 12px; cursor: pointer; transition: all var(--transition-fast); font-variant-numeric: tabular-nums; }
.nb-cat-btn:hover { border-color: color-mix(in srgb, var(--nb) 40%, transparent); color: var(--nb); background: var(--nb-light); }
.nb-cat-btn.active { background: var(--nb); color: white; border-color: var(--nb); font-weight: 600; }
[data-theme="dark"] .nb-cat-btn.active { color: #08090a; }
.nb-cat-manage { width: 26px; height: 26px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--border); border-radius: var(--radius-full); background: transparent; color: var(--text-tertiary); font-size: 13px; cursor: pointer; transition: all var(--transition-fast); margin-left: auto; }
.nb-cat-manage:hover { border-color: var(--border-hover); color: var(--text-primary); background: var(--bg-hover); }

/* 列表 */
.nb-list-container { max-width: 980px; margin: 0 auto; padding: 0 32px; }
.nb-list { display: flex; flex-direction: column; gap: 8px; }
.nb-loading { text-align: center; padding: 60px 0; color: var(--text-tertiary); font-size: 14px; }
.nb-empty { text-align: center; padding: 64px 0; color: var(--text-tertiary); }
.nb-empty-icon { font-size: 44px; margin-bottom: 12px; opacity: 0.85; }
.nb-empty-hint { font-size: 12px; margin-top: 4px; opacity: 0.8; }

/* 笔记卡片 */
.nb-item { position: relative; display: flex; gap: 10px; padding: 14px 16px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-lg); transition: border-color var(--transition-base), box-shadow var(--transition-base); align-items: flex-start; content-visibility: auto; contain-intrinsic-size: auto 120px; }
.nb-item:hover { border-color: color-mix(in srgb, var(--nb) 35%, var(--border)); box-shadow: var(--shadow-card-hover); }
.nb-item:has(.nb-cb:checked) { border-color: color-mix(in srgb, var(--nb) 55%, transparent); background: color-mix(in srgb, var(--nb) 4%, var(--bg-secondary)); }
.nb-item-check { flex-shrink: 0; display: flex; align-items: center; padding-top: 3px; }
.nb-item-check input { width: 15px; height: 15px; cursor: pointer; accent-color: var(--nb); }
.nb-item-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.nb-item-text { font-size: 14.5px; font-weight: 600; color: var(--text-primary); overflow-wrap: break-word; line-height: 1.5; letter-spacing: -0.01em; }
.nb-item-trans { font-size: 13px; color: var(--text-secondary); line-height: 1.55; overflow-wrap: break-word; }
.nb-item-context { font-size: 12px; color: var(--text-tertiary); font-style: italic; line-height: 1.5; padding: 5px 10px; background: var(--bg-tertiary); border-left: 2px solid var(--border-hover); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; overflow-wrap: break-word; }
.nb-item-analysis { font-size: 12.5px; color: var(--text-secondary); line-height: 1.6; padding: 8px 10px; background: var(--bg-tertiary); border: 1px solid var(--border-light); border-radius: var(--radius-md); overflow-wrap: break-word; margin-top: 2px; }
.nb-item-analysis.nb-analyzing { display: flex; align-items: center; gap: 7px; color: var(--nb); font-weight: 500; border-color: color-mix(in srgb, var(--nb) 25%, transparent); background: var(--nb-light); }
.nb-pulse { width: 7px; height: 7px; border-radius: 50%; background: var(--nb); animation: nbPulse 1.2s infinite; flex-shrink: 0; }
@keyframes nbPulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.4; transform: scale(1.3); } }
.nb-item.is-analyzing { border-color: color-mix(in srgb, var(--nb) 40%, transparent); }
.nb-item-usernote { display: flex; gap: 8px; align-items: flex-start; padding: 8px 10px; margin-top: 2px; background: color-mix(in srgb, #0891b2 6%, transparent); border: 1px solid color-mix(in srgb, #0891b2 15%, transparent); border-left: 2px solid #0891b2; border-radius: 0 var(--radius-md) var(--radius-md) 0; overflow-wrap: break-word; }
[data-theme="dark"] .nb-item-usernote { border-left-color: #22d3ee; }
.nb-usernote-label { flex-shrink: 0; font-size: 10.5px; font-weight: 600; color: #0891b2; padding: 1px 6px; background: color-mix(in srgb, #0891b2 14%, transparent); border-radius: var(--radius-sm); line-height: 1.6; }
[data-theme="dark"] .nb-usernote-label { color: #67e8f9; }
.nb-usernote-text { flex: 1; font-size: 12.5px; color: var(--text-primary); line-height: 1.6; white-space: pre-wrap; min-width: 0; }
.nb-item-keywords { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
.nb-keyword { font-size: 11px; padding: 1px 8px; border-radius: var(--radius-sm); background: var(--accent-light); color: var(--accent); font-weight: 500; border: 1px solid color-mix(in srgb, var(--accent) 15%, transparent); }
.nb-detail-label { display: block; margin-bottom: 4px; color: var(--text-tertiary); font-size: 10px; font-weight: 700; letter-spacing: .04em; }
.nb-item-language, .nb-item-writing { padding: 9px 11px; border-radius: var(--radius-md); line-height: 1.6; overflow-wrap: anywhere; }
.nb-item-language { border-left: 2px solid var(--accent); background: var(--accent-light); color: var(--text-secondary); }
.nb-item-language ul { margin: 0; padding-left: 18px; }
.nb-item-language li { margin: 3px 0; }
.nb-item-writing { border-left: 2px solid #16845a; background: color-mix(in srgb, #16845a 7%, transparent); color: var(--text-secondary); }

/* 折叠/展开：详情（上下文/解析/附笔/关键词）默认收起 */
.nb-item.nb-collapsible { cursor: pointer; }
.nb-item.nb-collapsible .nb-item-actions button { cursor: pointer; }
.nb-item-detail { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--transition-normal); }
.nb-item.expanded .nb-item-detail { grid-template-rows: 1fr; }
.nb-item-detail-inner { overflow: hidden; display: flex; flex-direction: column; gap: 5px; min-height: 0; }
.nb-item.expanded .nb-item-detail-inner { padding-top: 2px; }
/* 折叠态翻译最多两行，展开后完整显示 */
.nb-item.nb-collapsible:not(.expanded) .nb-item-trans { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* 展开指示箭头 */
.nb-item-expand { flex-shrink: 0; width: 28px; height: 28px; border: 0; border-radius: var(--radius-md); background: transparent; color: var(--text-tertiary); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all var(--transition-fast); }
.nb-item-expand:hover { background: var(--bg-hover); color: var(--text-primary); }
.nb-item-expand svg { width: 14px; height: 14px; transition: transform var(--transition-normal); transform: rotate(90deg); }
.nb-item.expanded .nb-item-expand svg { transform: rotate(-90deg); }

/* 元信息行 */
.nb-item-meta { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 3px; align-items: center; }
.nb-item-major { font-size: 10.5px; padding: 1px 8px; border-radius: var(--radius-sm); background: var(--accent-light); color: var(--accent); font-weight: 600; border: 1px solid color-mix(in srgb, var(--accent) 20%, transparent); }
.nb-item-theme { font-size: 10.5px; padding: 1px 8px; border-radius: var(--radius-sm); background: var(--nb-light); color: var(--nb); font-weight: 600; border: 1px solid color-mix(in srgb, var(--nb) 20%, transparent); }
.nb-item-usage { font-size: 10.5px; padding: 1px 8px; border-radius: var(--radius-sm); background: rgba(139,92,246,0.1); color: #8b5cf6; font-weight: 500; border: 1px solid rgba(139,92,246,0.18); }
[data-theme="dark"] .nb-item-usage { color: #a78bfa; }
.nb-item-depth { font-size: 10.5px; color: var(--warning); letter-spacing: 1px; }
.nb-item-cat { font-size: 10.5px; padding: 1px 8px; border-radius: var(--radius-sm); background: var(--nb-light); color: var(--nb); font-weight: 500; }
.nb-item-src { font-size: 10.5px; color: var(--text-tertiary); padding: 1px 6px; background: var(--bg-tertiary); border-radius: var(--radius-sm); max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nb-item-time { font-size: 10.5px; color: var(--text-tertiary); margin-left: auto; font-variant-numeric: tabular-nums; }

/* 操作按钮列：桌面 hover 显现，触屏恒显 */
.nb-item-actions { flex-shrink: 0; display: flex; flex-direction: column; gap: 3px; align-items: flex-end; }
.nb-item-del, .nb-item-jump, .nb-item-reanalyze, .nb-item-annotation { flex-shrink: 0; width: 28px; height: 28px; border: 0; border-radius: var(--radius-md); background: transparent; color: var(--text-tertiary); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all var(--transition-fast); }
@media (hover: hover) {
  .nb-item .nb-item-actions { opacity: 0.3; transition: opacity var(--transition-base); }
  .nb-item:hover .nb-item-actions, .nb-item:focus-within .nb-item-actions { opacity: 1; }
}
.nb-item-del:hover { background: var(--danger-light); color: var(--danger); }
.nb-item-jump:hover { background: var(--accent-light); color: var(--accent); }
.nb-item-reanalyze:hover { background: rgba(139,92,246,0.12); color: #8b5cf6; }
.nb-item-annotation:hover { background: rgba(8,145,178,0.12); color: #0891b2; }
[data-theme="dark"] .nb-item-reanalyze:hover { color: #c4b5fd; }
[data-theme="dark"] .nb-item-annotation:hover { color: #67e8f9; }
.nb-item-del svg, .nb-item-jump svg, .nb-item-reanalyze svg, .nb-item-annotation svg { width: 14px; height: 14px; }

/* 批量操作栏：sticky 悬浮 */
.nb-actions-bar { position: sticky; bottom: 12px; z-index: 5; display: flex; align-items: center; gap: 12px; padding: 10px 16px; margin-top: 12px; background: var(--surface-strong); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }
.nb-select-all { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-secondary); cursor: pointer; user-select: none; }
.nb-select-all input { width: 15px; height: 15px; cursor: pointer; accent-color: var(--nb); }
.nb-selected-count { font-size: 12.5px; color: var(--text-tertiary); flex: 1; font-variant-numeric: tabular-nums; }
.nb-delete-btn { padding: 6px 16px; border: 0; border-radius: var(--radius-md); background: var(--danger); color: white; font-size: 13px; font-weight: 600; cursor: pointer; transition: all var(--transition-fast); box-shadow: inset 0 1px 0 rgba(255,255,255,0.1); }
.nb-delete-btn:hover:not(:disabled) { background: color-mix(in srgb, var(--danger) 85%, #000); }
.nb-delete-btn:disabled { opacity: 0.35; cursor: not-allowed; }

/* 重新分析 / 附笔弹窗 */
.nb-reanalyze-overlay, .nb-annotation-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.45); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); z-index: 10000; display: flex; align-items: center; justify-content: center; padding: 16px; animation: nbFadeIn 0.15s ease; }
[data-theme="dark"] .nb-reanalyze-overlay, [data-theme="dark"] .nb-annotation-overlay { background: rgba(0,0,0,0.6); }
@keyframes nbFadeIn { from { opacity: 0; } to { opacity: 1; } }
.nb-reanalyze-dialog, .nb-annotation-dialog { width: 100%; max-width: 480px; background: var(--surface-strong); border: 1px solid var(--border); border-radius: var(--radius-2xl); box-shadow: var(--shadow-xl); overflow: hidden; animation: nbDialogIn 0.15s cubic-bezier(0.25,0.46,0.45,0.94); }
@keyframes nbDialogIn { from { opacity: 0; transform: translateY(4px) scale(0.99); } to { opacity: 1; transform: translateY(0) scale(1); } }
.nb-reanalyze-header, .nb-annotation-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--border); }
.nb-reanalyze-title, .nb-annotation-title { font-size: 15px; font-weight: 600; color: var(--text-primary); letter-spacing: -0.01em; }
.nb-reanalyze-close, .nb-annotation-close { width: 28px; height: 28px; border: 0; border-radius: var(--radius-md); background: var(--bg-tertiary); color: var(--text-tertiary); font-size: 18px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all var(--transition-fast); }
.nb-reanalyze-close:hover, .nb-annotation-close:hover { background: var(--bg-active); color: var(--text-primary); }
.nb-reanalyze-body, .nb-annotation-body { padding: 16px 18px; }
.nb-reanalyze-hint, .nb-annotation-hint { margin: 0 0 10px; font-size: 12px; line-height: 1.55; color: var(--text-tertiary); }
.nb-reanalyze-textarea, .nb-annotation-textarea { width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-primary); color: var(--text-primary); font-size: 13px; line-height: 1.55; font-family: inherit; resize: vertical; min-height: 80px; outline: none; transition: border-color var(--transition-fast), box-shadow var(--transition-fast); box-sizing: border-box; }
.nb-reanalyze-textarea:focus { border-color: #8b5cf6; box-shadow: 0 0 0 3px rgba(139,92,246,0.15); }
.nb-annotation-textarea { min-height: 120px; line-height: 1.6; }
.nb-annotation-textarea:focus { border-color: #0891b2; box-shadow: 0 0 0 3px rgba(8,145,178,0.15); }
.nb-reanalyze-footer, .nb-annotation-footer { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 18px; border-top: 1px solid var(--border); }
.nb-reanalyze-cancel, .nb-annotation-cancel { padding: 7px 16px; border-radius: var(--radius-md); font-size: 13px; font-weight: 500; cursor: pointer; transition: all var(--transition-fast); background: transparent; color: var(--text-secondary); border: 1px solid var(--border); }
.nb-reanalyze-cancel:hover, .nb-annotation-cancel:hover { background: var(--bg-hover); color: var(--text-primary); }
.nb-reanalyze-submit { padding: 7px 16px; border: 0; border-radius: var(--radius-md); font-size: 13px; font-weight: 600; cursor: pointer; transition: all var(--transition-fast); background: #8b5cf6; color: #fff; box-shadow: inset 0 1px 0 rgba(255,255,255,0.1); }
.nb-reanalyze-submit:hover { background: #7c3aed; }
.nb-reanalyze-submit:disabled { opacity: 0.5; cursor: not-allowed; }
.nb-annotation-submit { padding: 7px 16px; border: 0; border-radius: var(--radius-md); font-size: 13px; font-weight: 600; cursor: pointer; transition: all var(--transition-fast); background: #0891b2; color: #fff; box-shadow: inset 0 1px 0 rgba(255,255,255,0.1); }
.nb-annotation-submit:hover { background: #0e7490; }
.nb-annotation-submit:disabled { opacity: 0.5; cursor: not-allowed; }

/* 分类管理弹窗 */
.nb-cat-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.45); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); z-index: 10000; display: flex; align-items: center; justify-content: center; padding: 16px; animation: nbFadeIn 0.15s ease; }
[data-theme="dark"] .nb-cat-overlay { background: rgba(0,0,0,0.6); }
.nb-cat-dialog { width: 100%; max-width: 420px; max-height: 80vh; background: var(--surface-strong); border: 1px solid var(--border); border-radius: var(--radius-2xl); box-shadow: var(--shadow-xl); overflow: hidden; display: flex; flex-direction: column; animation: nbDialogIn 0.15s cubic-bezier(0.25,0.46,0.45,0.94); }
.nb-cat-dialog-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.nb-cat-dialog-title { font-size: 15px; font-weight: 600; color: var(--text-primary); letter-spacing: -0.01em; }
.nb-cat-dialog-close { width: 28px; height: 28px; border: 0; border-radius: var(--radius-md); background: var(--bg-tertiary); color: var(--text-tertiary); font-size: 18px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all var(--transition-fast); }
.nb-cat-dialog-close:hover { background: var(--bg-active); color: var(--text-primary); }
.nb-cat-dialog-body { padding: 14px 18px; overflow-y: auto; flex: 1; }
.nb-cat-list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 14px; }
.nb-cat-loading, .nb-cat-empty { text-align: center; padding: 24px 0; color: var(--text-tertiary); font-size: 13px; }
.nb-cat-item { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-secondary); transition: border-color var(--transition-fast); }
.nb-cat-item:hover { border-color: var(--border-hover); }
.nb-cat-item.editing { border-color: var(--accent); background: var(--accent-light); }
.nb-cat-item-name { flex: 1; font-size: 13.5px; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nb-cat-rename-input { flex: 1; padding: 5px 8px; border: 1px solid var(--accent); border-radius: var(--radius-sm); background: var(--bg-primary); color: var(--text-primary); font-size: 13.5px; outline: none; box-sizing: border-box; box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent); }
.nb-cat-item-actions { display: flex; gap: 4px; flex-shrink: 0; }
.nb-cat-item-edit, .nb-cat-item-del, .nb-cat-item-confirm, .nb-cat-item-cancel { width: 26px; height: 26px; border: 0; border-radius: var(--radius-sm); background: transparent; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all var(--transition-fast); font-size: 13px; }
.nb-cat-item-edit { color: var(--text-tertiary); }
.nb-cat-item-edit:hover { background: rgba(139,92,246,0.12); color: #8b5cf6; }
.nb-cat-item-del { color: var(--text-tertiary); }
.nb-cat-item-del:hover { background: var(--danger-light); color: var(--danger); }
.nb-cat-item-del:disabled { opacity: 0.3; cursor: not-allowed; }
.nb-cat-item-confirm { color: var(--nb); }
.nb-cat-item-confirm:hover { background: var(--nb-light); }
.nb-cat-item-confirm:disabled { opacity: 0.5; cursor: not-allowed; }
.nb-cat-item-cancel { color: var(--text-tertiary); }
.nb-cat-item-cancel:hover { background: var(--bg-hover); }
.nb-cat-add-row { display: flex; gap: 8px; padding-top: 10px; border-top: 1px solid var(--border); }
.nb-cat-add-input { flex: 1; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-primary); color: var(--text-primary); font-size: 13px; outline: none; transition: border-color var(--transition-fast), box-shadow var(--transition-fast); box-sizing: border-box; }
.nb-cat-add-input:focus { border-color: var(--accent); box-shadow: var(--focus-ring); }
.nb-cat-add-btn { padding: 8px 16px; border: 0; border-radius: var(--radius-md); background: var(--accent); color: white; font-size: 13px; font-weight: 600; cursor: pointer; transition: background var(--transition-fast); flex-shrink: 0; box-shadow: inset 0 1px 0 rgba(255,255,255,0.1); }
.nb-cat-add-btn:hover { background: var(--accent-hover); }
.nb-cat-add-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.nb-cat-dialog-footer { display: flex; justify-content: flex-end; padding: 12px 18px; border-top: 1px solid var(--border); flex-shrink: 0; }
.nb-cat-dialog-close-btn { padding: 7px 16px; border: 1px solid var(--border); border-radius: var(--radius-md); font-size: 13px; font-weight: 500; cursor: pointer; transition: all var(--transition-fast); background: transparent; color: var(--text-secondary); }
.nb-cat-dialog-close-btn:hover { background: var(--bg-hover); color: var(--text-primary); }
[data-theme="dark"] .nb-cat-item-edit:hover { color: #c4b5fd; }

/* ===== 响应式 ===== */
@media (max-width: 900px) { .eng-action-row { grid-template-columns: 1fr; } }
@media (max-width: 900px) {
  .eng-shelf-content { padding: 0 16px; }
  .eng-shelf-grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 14px; }
  .eng-cover-title { font-size: 12px; }
}
@media (max-width: 640px) {
  .eng-header { padding: 16px 20px 12px; }
  .eng-action-row { padding: 0 20px; }
  .eng-shelf-content { padding: 0 12px; }
  .eng-shelf-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
  .eng-cover-vol-badge, .eng-cover-chapters-badge { font-size: 10px; padding: 2px 6px; }
  .eng-cover-vol-badge { top: 6px; left: 6px; }
  .eng-cover-chapters-badge { bottom: 6px; right: 6px; }
  .eng-cover-title { font-size: 12px; -webkit-line-clamp: 2; line-clamp: 2; }
  .eng-reader-body { padding: 24px 16px 120px; }
  .eng-reader-nav { padding: 10px 16px; }
  .nb-toolbar { padding: 0 20px; }
  .nb-list-container { padding: 0 20px; }
  .nb-search-input { padding: 12px 34px 12px 36px; font-size: 16px; }
  .nb-search-btn { min-height: 44px; padding: 0 16px; }
  .nb-cat-btn { min-height: 34px; padding: 7px 14px; }
}

/* ========== 汉译英练习闪卡（Linear v6.0） ========== */
.nbq-page{max-width:720px;margin:0 auto;padding:0 20px;min-height:calc(100vh - var(--nav-height));display:flex;flex-direction:column;--nb:#0e9f6e;--nb-light:rgba(14,159,110,0.1)}
[data-theme="dark"] .nbq-page{--nb:#3ecf8e;--nb-light:rgba(62,207,142,0.12)}
.nbq-header{display:flex;align-items:center;gap:12px;padding:16px 0 12px}
.nbq-back-btn{width:36px;height:36px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--bg-secondary);color:var(--text-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all var(--transition-fast)}
.nbq-back-btn:hover{background:var(--bg-hover);color:var(--text-primary);border-color:var(--border-hover)}
.nbq-back-btn svg{width:18px;height:18px}
.nbq-title-block{flex:1;min-width:0}
.nbq-badge{display:flex;align-items:center;gap:8px}
.nbq-badge-icon{font-size:18px}
.nbq-badge-text{font-size:17px;font-weight:700;color:var(--text-primary);letter-spacing:-0.02em}
.nbq-subtitle{margin:2px 0 0;font-size:12.5px;color:var(--text-tertiary);font-variant-numeric:tabular-nums}
.nbq-major-row{display:inline-flex;gap:2px;padding:3px;background:var(--bg-tertiary);border:1px solid var(--border-light);border-radius:var(--radius-md);width:fit-content;margin-bottom:16px}
.nbq-major-btn{padding:5px 16px;border:1px solid transparent;border-radius:var(--radius-sm);background:transparent;color:var(--text-secondary);cursor:pointer;font-size:12.5px;font-weight:600;transition:all var(--transition-fast)}
.nbq-major-btn.active{background:var(--bg-secondary);color:var(--nb);border-color:var(--border);box-shadow:var(--shadow-sm)}
.nbq-major-btn:not(.active):hover{color:var(--text-primary)}
.nbq-card-area{flex:1;display:flex;align-items:center;justify-content:center;perspective:1200px;min-height:300px;padding-bottom:8px}
.nbq-card{position:relative;width:100%;max-width:500px;min-height:280px;transform-style:preserve-3d;transition:transform 0.4s cubic-bezier(0.25,0.46,0.45,0.94);cursor:pointer}
.nbq-card.flipped{transform:rotateY(180deg)}
.nbq-card-face{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;padding:32px 24px;border-radius:var(--radius-2xl);background:var(--bg-secondary);border:1px solid var(--border);box-shadow:var(--shadow-lg)}
.nbq-card-front{border-top:2px solid var(--nb)}
.nbq-card-back{transform:rotateY(180deg);border-top:2px solid var(--accent)}
.nbq-card-label{font-size:11px;color:var(--text-tertiary);letter-spacing:0.1em;text-transform:uppercase;font-weight:600}
.nbq-card-text{font-size:20px;font-weight:600;color:var(--text-primary);text-align:center;line-height:1.5;word-break:break-word;letter-spacing:-0.01em}
.nbq-card-en{font-family:'Georgia','Times New Roman',serif}
.nbq-card-context{font-size:13px;color:var(--text-tertiary);text-align:center;max-width:400px;line-height:1.6;font-style:italic}
.nbq-card-tags{display:flex;gap:6px;flex-wrap:wrap;justify-content:center}
.nbq-tag{font-size:11px;padding:2px 10px;border-radius:var(--radius-full);background:var(--nb-light);color:var(--nb);font-weight:500;border:1px solid color-mix(in srgb,var(--nb) 20%,transparent)}
.nbq-card-hint{font-size:12px;color:var(--text-tertiary);opacity:0.6}
.nbq-controls{display:flex;gap:10px;padding:12px 0 24px}
.nbq-ctrl-btn{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:12px;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--bg-secondary);color:var(--text-secondary);cursor:pointer;font-size:14px;font-weight:500;transition:all var(--transition-fast);min-height:44px}
.nbq-ctrl-btn:hover{background:var(--bg-hover);color:var(--text-primary);border-color:var(--border-hover)}
.nbq-ctrl-btn:active{background:var(--bg-active)}
.nbq-ctrl-btn svg{width:16px;height:16px}
.nbq-ctrl-flip{flex:0.6;background:var(--nb);color:#fff;border-color:transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);font-weight:600}
.nbq-ctrl-flip:hover{background:color-mix(in srgb,var(--nb) 85%,#000);color:#fff;border-color:transparent}
[data-theme="dark"] .nbq-ctrl-flip{color:#08090a}
[data-theme="dark"] .nbq-ctrl-flip:hover{background:color-mix(in srgb,var(--nb) 85%,#fff);color:#08090a}
.nbq-card-skeleton{width:100%;max-width:500px;height:280px;border-radius:var(--radius-2xl);background:linear-gradient(90deg,var(--bg-secondary) 25%,var(--bg-tertiary) 50%,var(--bg-secondary) 75%);background-size:200% 100%;animation:engSkeleton 1.5s infinite;border:1px solid var(--border)}
.nbq-empty{text-align:center;padding:60px 0;color:var(--text-tertiary)}
.nbq-empty-icon{font-size:44px;margin-bottom:12px;opacity:0.85}
.nbq-empty-hint{font-size:13px;margin-top:4px;opacity:0.7}
.nbq-slide-in-right{animation:nbqSlideRight 0.2s cubic-bezier(0.25,0.46,0.45,0.94)}
.nbq-slide-in-left{animation:nbqSlideLeft 0.2s cubic-bezier(0.25,0.46,0.45,0.94)}
@keyframes nbqSlideRight{from{opacity:0;transform:translateX(16px)}to{opacity:1;transform:translateX(0)}}
@keyframes nbqSlideLeft{from{opacity:0;transform:translateX(-16px)}to{opacity:1;transform:translateX(0)}}
@media (max-width:640px){
  .nbq-page{padding:0 16px}
  .nbq-card{min-height:240px}
  .nbq-card-text{font-size:18px}
  .nbq-card-face{padding:24px 20px}
  .nbq-ctrl-btn span{display:none}
  .nbq-ctrl-flip span{display:inline}
  .nbq-card-skeleton{height:240px}
}

/* =====================================================================
   回顾笔记本新版工作区
   这组规则覆盖旧版笔记本 UI，保留同一批 class 与 data-action。
   ===================================================================== */
.nb-page {
  --nb: #0c9f72;
  --nb-strong: #087f5b;
  --nb-light: rgba(12, 159, 114, 0.1);
  min-height: calc(100vh - var(--nav-height, 52px));
  padding: 0 24px 64px;
  background: var(--bg-primary);
}
[data-theme="dark"] .nb-page {
  --nb: #3fd49a;
  --nb-strong: #65e4ad;
  --nb-light: rgba(63, 212, 154, 0.12);
}
.nb-shell { max-width: 1180px; margin: 0 auto; }
.nb-header {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 112px;
  padding: 22px 0 18px;
  border-bottom: 1px solid var(--border-light);
}
.nb-back-btn {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-secondary);
  color: var(--text-secondary);
  cursor: pointer;
  transition: color var(--transition-fast), background var(--transition-fast), border-color var(--transition-fast);
}
.nb-back-btn:hover { color: var(--text-primary); background: var(--bg-hover); border-color: var(--border-hover); }
.nb-back-btn svg { width: 18px; height: 18px; }
.nb-title-icon {
  width: 42px;
  height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border: 1px solid color-mix(in srgb, var(--nb) 24%, var(--border));
  border-radius: 10px;
  background: var(--nb-light);
  color: var(--nb);
}
.nb-title-icon svg { width: 21px; height: 21px; }
.nb-title-block { min-width: 0; flex: 1; }
.nb-eyebrow, .nbq-eyebrow {
  color: var(--nb);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  line-height: 1.2;
}
.nb-title {
  margin: 4px 0 2px;
  color: var(--text-primary);
  font-size: 22px;
  font-weight: 700;
  line-height: 1.2;
}
.nb-subtitle { margin: 0; color: var(--text-tertiary); font-size: 12px; font-variant-numeric: tabular-nums; }
.nb-quiz-entry {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 12px;
  flex-shrink: 0;
  border: 1px solid color-mix(in srgb, var(--nb) 32%, var(--border));
  border-radius: var(--radius-md);
  background: var(--nb-light);
  color: var(--nb);
  cursor: pointer;
  font-size: 13px;
  font-weight: 650;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.nb-quiz-entry:hover { border-color: var(--nb); background: var(--nb); color: #fff; }
.nb-quiz-entry-icon svg, .nb-quiz-entry-arrow svg { width: 16px; height: 16px; }
.nb-quiz-entry-arrow { display: inline-flex; transition: transform var(--transition-fast); }
.nb-quiz-entry:hover .nb-quiz-entry-arrow { transform: translateX(2px); }
.nb-workspace { display: grid; grid-template-columns: 230px minmax(0, 1fr); gap: 36px; padding-top: 26px; }
.nb-sidebar { min-width: 0; padding-right: 26px; border-right: 1px solid var(--border-light); }
.nb-search-row { display: flex; gap: 7px; }
.nb-search-wrap { min-width: 0; position: relative; flex: 1; display: flex; align-items: center; }
.nb-search-icon { position: absolute; left: 10px; display: inline-flex; color: var(--text-tertiary); pointer-events: none; }
.nb-search-icon svg { width: 15px; height: 15px; }
.nb-search-input {
  width: 100%;
  height: 38px;
  padding: 0 30px 0 32px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  outline: 0;
  background: var(--bg-secondary);
  color: var(--text-primary);
  font-size: 13px;
  box-sizing: border-box;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.nb-search-input:focus { border-color: var(--nb); box-shadow: 0 0 0 3px color-mix(in srgb, var(--nb) 16%, transparent); }
.nb-search-input::placeholder { color: var(--text-tertiary); }
.nb-search-clear {
  position: absolute;
  right: 6px;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: var(--bg-tertiary);
  color: var(--text-tertiary);
  cursor: pointer;
}
.nb-search-clear svg { width: 12px; height: 12px; }
.nb-search-clear:hover { color: var(--text-primary); background: var(--bg-active); }
.nb-search-clear.hidden { display: none; }
.nb-search-btn {
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  padding: 0;
  border: 1px solid var(--nb);
  border-radius: var(--radius-md);
  background: var(--nb);
  color: #fff;
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast);
}
.nb-search-btn:hover { background: var(--nb-strong); border-color: var(--nb-strong); }
.nb-search-btn svg { width: 16px; height: 16px; }
.nb-filter-section { margin-top: 30px; }
.nb-filter-section--categories { margin-top: 32px; }
.nb-filter-label { color: var(--text-tertiary); font-size: 11px; font-weight: 650; letter-spacing: 0.08em; text-transform: uppercase; }
.nb-filter-heading { display: flex; align-items: center; justify-content: space-between; }
.nb-major-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px; width: 100%; margin-top: 10px; padding: 3px; border: 1px solid var(--border-light); border-radius: var(--radius-md); background: var(--bg-tertiary); box-sizing: border-box; }
.nb-major-btn {
  min-width: 0;
  min-height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 0 4px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.nb-major-btn:hover { color: var(--text-primary); }
.nb-major-btn.active { border-color: var(--border); background: var(--bg-secondary); color: var(--nb); box-shadow: var(--shadow-sm); }
.nb-major-count { color: var(--text-tertiary); font-size: 10px; font-variant-numeric: tabular-nums; }
.nb-major-btn.active .nb-major-count { color: var(--nb); }
.nb-category-row { display: flex; flex-direction: column; gap: 3px; margin-top: 10px; }
.nb-cat-btn {
  min-height: 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 0 10px;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 12px;
  text-align: left;
}
.nb-cat-btn:hover { background: var(--bg-hover); color: var(--text-primary); }
.nb-cat-btn.active { border-color: color-mix(in srgb, var(--nb) 24%, transparent); background: var(--nb-light); color: var(--nb); font-weight: 650; }
.nb-cat-count { color: var(--text-tertiary); font-size: 10px; font-variant-numeric: tabular-nums; }
.nb-cat-btn.active .nb-cat-count { color: var(--nb); }
.nb-cat-manage { width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 1px solid var(--border); border-radius: var(--radius-md); background: transparent; color: var(--text-tertiary); cursor: pointer; }
.nb-cat-manage:hover { color: var(--text-primary); background: var(--bg-hover); border-color: var(--border-hover); }
.nb-cat-manage svg { width: 14px; height: 14px; }
.nb-content { min-width: 0; }
.nb-list-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin: 2px 0 18px; }
.nb-list-title { margin: 0; color: var(--text-primary); font-size: 16px; font-weight: 700; line-height: 1.3; }
.nb-list-summary { margin: 5px 0 0; color: var(--text-tertiary); font-size: 12px; }
.nb-total-count { min-width: 34px; padding: 4px 8px; border: 1px solid var(--border); border-radius: var(--radius-full); color: var(--text-secondary); font-size: 11px; text-align: center; font-variant-numeric: tabular-nums; }
.nb-list { display: flex; flex-direction: column; gap: 10px; }
.nb-list-skeleton { height: 126px; border: 1px solid var(--border-light); border-radius: var(--radius-lg); background: var(--bg-secondary); position: relative; overflow: hidden; }
.nb-list-skeleton::after { content: ''; position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--text-primary) 4%, transparent), transparent); animation: nbShimmer 1.3s infinite; }
@keyframes nbShimmer { to { transform: translateX(100%); } }
.nb-item { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 12px; padding: 16px 18px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--bg-secondary); box-shadow: var(--shadow-card); transition: border-color var(--transition-base), box-shadow var(--transition-base), background var(--transition-base); }
.nb-item:hover { border-color: color-mix(in srgb, var(--nb) 42%, var(--border)); box-shadow: var(--shadow-card-hover); }
.nb-item:has(.nb-cb:checked) { border-color: color-mix(in srgb, var(--nb) 55%, var(--border)); background: color-mix(in srgb, var(--nb) 4%, var(--bg-secondary)); }
.nb-item-check { display: flex; align-items: flex-start; padding-top: 3px; }
.nb-item-check input, .nb-select-all input { width: 15px; height: 15px; margin: 0; accent-color: var(--nb); cursor: pointer; }
.nb-item-body { min-width: 0; display: flex; flex-direction: column; gap: 7px; }
.nb-item-head { display: flex; align-items: flex-start; gap: 12px; }
.nb-item-text { flex: 1; min-width: 0; color: var(--text-primary); font-family: Georgia, 'Times New Roman', serif; font-size: 16px; font-weight: 700; line-height: 1.42; overflow-wrap: anywhere; }
.nb-item-trans { color: var(--text-secondary); font-size: 13px; line-height: 1.55; overflow-wrap: anywhere; }
.nb-item-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 5px; margin-top: 1px; }
.nb-item-major, .nb-item-theme, .nb-item-usage, .nb-item-src { padding: 3px 7px; border-radius: var(--radius-sm); font-size: 10px; line-height: 1.2; }
.nb-item-major { border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent); background: var(--accent-light); color: var(--accent); font-weight: 650; }
.nb-item-theme { border: 1px solid color-mix(in srgb, var(--nb) 22%, transparent); background: var(--nb-light); color: var(--nb); font-weight: 650; }
.nb-item-usage { border: 1px solid rgba(139, 92, 246, 0.18); background: rgba(139, 92, 246, 0.1); color: #8b5cf6; }
.nb-item-src { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; background: var(--bg-tertiary); color: var(--text-tertiary); }
.nb-item-depth { color: var(--warning); font-size: 11px; letter-spacing: 1px; }
.nb-item-time { margin-left: auto; color: var(--text-tertiary); font-size: 10px; font-variant-numeric: tabular-nums; }
.nb-item-actions { display: inline-flex; flex-direction: row; align-items: center; gap: 2px; flex-shrink: 0; opacity: 0.35; transition: opacity var(--transition-base); }
.nb-item:hover .nb-item-actions, .nb-item:focus-within .nb-item-actions { opacity: 1; }
.nb-item-actions button { width: 27px; height: 27px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--text-tertiary); cursor: pointer; }
.nb-item-actions button:hover { background: var(--bg-hover); color: var(--text-primary); }
.nb-item-actions button svg { width: 14px; height: 14px; }
.nb-item-actions .nb-item-expand svg { transform: none; transition: transform var(--transition-normal); }
.nb-item.expanded .nb-item-expand svg { transform: rotate(180deg); }
.nb-item-actions .nb-item-jump:hover { color: var(--accent); background: var(--accent-light); }
.nb-item-actions .nb-item-annotation:hover { color: #0891b2; background: rgba(8, 145, 178, 0.11); }
.nb-item-actions .nb-item-reanalyze:hover { color: #8b5cf6; background: rgba(139, 92, 246, 0.11); }
.nb-item-actions .nb-item-del:hover { color: var(--danger); background: var(--danger-light); }
.nb-item-detail { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--transition-normal); }
.nb-item.expanded .nb-item-detail { grid-template-rows: 1fr; }
.nb-item-detail-inner { min-height: 0; display: flex; flex-direction: column; gap: 7px; overflow: hidden; }
.nb-item.expanded .nb-item-detail-inner { padding-top: 4px; }
.nb-item.nb-collapsible:not(.expanded) .nb-item-trans { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.nb-item-context, .nb-item-analysis { padding: 9px 11px; border-radius: var(--radius-md); color: var(--text-secondary); font-size: 12px; line-height: 1.65; overflow-wrap: anywhere; }
.nb-item-context { border-left: 2px solid var(--border-hover); background: var(--bg-tertiary); font-style: italic; }
.nb-item-analysis { border: 1px solid var(--border-light); background: var(--bg-tertiary); }
.nb-item-analysis.nb-analyzing { display: flex; align-items: center; gap: 8px; border-color: color-mix(in srgb, var(--nb) 26%, transparent); background: var(--nb-light); color: var(--nb); font-weight: 600; }
.nb-item-usernote { display: flex; gap: 8px; align-items: flex-start; padding: 9px 11px; border-left: 2px solid #0891b2; border-radius: 0 var(--radius-md) var(--radius-md) 0; background: rgba(8, 145, 178, 0.07); }
.nb-usernote-label { flex-shrink: 0; padding: 2px 6px; border-radius: var(--radius-sm); background: rgba(8, 145, 178, 0.13); color: #0891b2; font-size: 10px; font-weight: 700; }
.nb-usernote-text { min-width: 0; color: var(--text-primary); font-size: 12px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
.nb-item-keywords { display: flex; flex-wrap: wrap; gap: 5px; }
.nb-keyword { padding: 2px 7px; border: 1px solid color-mix(in srgb, var(--accent) 15%, transparent); border-radius: var(--radius-sm); background: var(--accent-light); color: var(--accent); font-size: 10px; }
.nb-pulse { width: 7px; height: 7px; border-radius: 50%; background: var(--nb); animation: nbPulse 1.2s infinite; }
.nb-empty { min-height: 280px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; border: 1px dashed var(--border); border-radius: var(--radius-lg); color: var(--text-tertiary); text-align: center; }
.nb-empty-icon { width: 38px; height: 38px; display: inline-flex; align-items: center; justify-content: center; border-radius: 10px; background: var(--bg-tertiary); color: var(--text-tertiary); }
.nb-empty-icon svg { width: 20px; height: 20px; }
.nb-empty p { margin: 0; font-size: 13px; }
.nb-actions-bar { position: sticky; bottom: 16px; z-index: 5; display: flex; align-items: center; gap: 12px; min-height: 44px; margin: 0 0 12px; padding: 0 12px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: color-mix(in srgb, var(--surface-strong) 93%, transparent); box-shadow: var(--shadow-lg); backdrop-filter: blur(10px); }
.nb-select-all { display: inline-flex; align-items: center; gap: 7px; color: var(--text-secondary); cursor: pointer; font-size: 12px; user-select: none; }
.nb-selected-count { flex: 1; color: var(--text-tertiary); font-size: 11px; font-variant-numeric: tabular-nums; }
.nb-delete-btn { display: inline-flex; align-items: center; gap: 6px; min-height: 30px; padding: 0 10px; border: 0; border-radius: var(--radius-md); background: var(--danger); color: #fff; cursor: pointer; font-size: 11px; font-weight: 650; }
.nb-delete-btn:hover:not(:disabled) { filter: brightness(0.9); }
.nb-delete-btn:disabled { cursor: not-allowed; opacity: 0.35; }
.nb-delete-btn svg { width: 13px; height: 13px; }

/* 汉译英练习新版工作台 */
.nbq-page { --nb: #0c9f72; --nb-light: rgba(12, 159, 114, 0.1); min-height: calc(100vh - var(--nav-height, 52px)); max-width: 980px; margin: 0 auto; padding: 0 24px 42px; }
[data-theme="dark"] .nbq-page { --nb: #3fd49a; --nb-light: rgba(63, 212, 154, 0.12); }
.nbq-header { display: flex; align-items: center; gap: 14px; min-height: 112px; padding: 22px 0 18px; border-bottom: 1px solid var(--border-light); }
.nbq-back-btn { width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; }
.nbq-back-btn:hover { color: var(--text-primary); background: var(--bg-hover); border-color: var(--border-hover); }
.nbq-back-btn svg { width: 18px; height: 18px; }
.nbq-title-icon { width: 42px; height: 42px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; border: 1px solid color-mix(in srgb, var(--nb) 24%, var(--border)); border-radius: 10px; background: var(--nb-light); color: var(--nb); }
.nbq-title-icon svg { width: 21px; height: 21px; }
.nbq-title-block { flex: 1; min-width: 0; }
.nbq-title { margin: 4px 0 2px; color: var(--text-primary); font-size: 22px; line-height: 1.2; }
.nbq-subtitle { margin: 0; color: var(--text-tertiary); font-size: 12px; font-variant-numeric: tabular-nums; }
.nbq-position { color: var(--text-tertiary); font-size: 12px; font-variant-numeric: tabular-nums; }
.nbq-workspace { display: flex; flex-direction: column; min-height: calc(100vh - 220px); }
.nbq-toolbar { display: flex; align-items: center; gap: 20px; padding: 24px 0 18px; }
.nbq-major-row { display: inline-flex; gap: 3px; padding: 3px; border: 1px solid var(--border-light); border-radius: var(--radius-md); background: var(--bg-tertiary); }
.nbq-major-btn { min-height: 30px; padding: 0 14px; border: 1px solid transparent; border-radius: var(--radius-sm); background: transparent; color: var(--text-secondary); cursor: pointer; font-size: 12px; font-weight: 650; }
.nbq-major-btn.active { border-color: var(--border); background: var(--bg-secondary); color: var(--nb); box-shadow: var(--shadow-sm); }
.nbq-progress { flex: 1; height: 4px; overflow: hidden; border-radius: var(--radius-full); background: var(--bg-tertiary); }
.nbq-progress-fill { display: block; width: 0; height: 100%; border-radius: inherit; background: var(--nb); transition: width var(--transition-normal); }
.nbq-card-area { flex: 1; display: flex; align-items: center; justify-content: center; min-height: 300px; padding: 4px 0 12px; perspective: 1200px; }
.nbq-card { position: relative; width: min(100%, 680px); aspect-ratio: 16 / 9; min-height: 300px; transform-style: preserve-3d; cursor: pointer; transition: transform 0.42s cubic-bezier(0.25, 0.46, 0.45, 0.94); }
.nbq-card.flipped { transform: rotateY(180deg); }
.nbq-card-face { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px; padding: 36px 52px; overflow-y: auto; backface-visibility: hidden; -webkit-backface-visibility: hidden; border: 1px solid var(--border); border-radius: var(--radius-xl); background: var(--bg-secondary); box-shadow: var(--shadow-xl); box-sizing: border-box; }
.nbq-card-front { border-top: 3px solid var(--nb); }
.nbq-card-back { transform: rotateY(180deg); border-top: 3px solid var(--accent); }
.nbq-card-label { color: var(--text-tertiary); font-size: 10px; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; }
.nbq-card-text { max-width: 560px; color: var(--text-primary); font-size: clamp(18px, 2.2vw, 26px); font-weight: 650; line-height: 1.55; text-align: center; overflow-wrap: anywhere; }
.nbq-card-en { font-family: Georgia, 'Times New Roman', serif; }
.nbq-card-context { max-width: 560px; color: var(--text-tertiary); font-family: Georgia, 'Times New Roman', serif; font-size: 13px; line-height: 1.65; text-align: center; font-style: italic; }
.nbq-card-tags { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; }
.nbq-tag { padding: 4px 8px; border: 1px solid color-mix(in srgb, var(--nb) 22%, transparent); border-radius: var(--radius-sm); background: var(--nb-light); color: var(--nb); font-size: 10px; }
.nbq-controls { display: grid; grid-template-columns: 1fr 1.2fr 1fr; gap: 10px; width: min(100%, 500px); margin: 0 auto; padding: 4px 0 0; }
.nbq-ctrl-btn { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; gap: 7px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; font-size: 12px; font-weight: 600; }
.nbq-ctrl-btn:hover:not(:disabled) { border-color: var(--border-hover); background: var(--bg-hover); color: var(--text-primary); }
.nbq-ctrl-btn:disabled { cursor: not-allowed; opacity: 0.3; }
.nbq-ctrl-btn svg { width: 15px; height: 15px; }
.nbq-ctrl-flip { border-color: var(--nb); background: var(--nb); color: #fff; }
.nbq-ctrl-flip:hover:not(:disabled) { border-color: var(--nb); background: color-mix(in srgb, var(--nb) 85%, #000); color: #fff; }
.nbq-card-skeleton { width: min(100%, 680px); aspect-ratio: 16 / 9; min-height: 300px; border: 1px solid var(--border-light); border-radius: var(--radius-xl); background: var(--bg-secondary); position: relative; overflow: hidden; }
.nbq-card-skeleton::after { content: ''; position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--text-primary) 4%, transparent), transparent); animation: nbShimmer 1.3s infinite; }
.nbq-empty { min-height: 280px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; color: var(--text-tertiary); }
.nbq-empty-icon { width: 42px; height: 42px; display: inline-flex; align-items: center; justify-content: center; border-radius: 12px; background: var(--bg-tertiary); }
.nbq-empty-icon svg { width: 22px; height: 22px; }
.nbq-empty p { margin: 0; font-size: 13px; }

/* 笔记本弹窗与移动端 */
.nb-reanalyze-close svg, .nb-annotation-close svg, .nb-cat-dialog-close svg { width: 15px; height: 15px; }
.nb-reanalyze-close, .nb-annotation-close, .nb-cat-dialog-close { display: inline-flex; align-items: center; justify-content: center; }
.nb-cat-item-edit svg, .nb-cat-item-del svg, .nb-cat-item-confirm svg, .nb-cat-item-cancel svg { width: 13px; height: 13px; }
@media (max-width: 840px) {
  .nb-page, .nbq-page { padding-left: 18px; padding-right: 18px; }
  .nb-workspace { grid-template-columns: 1fr; gap: 22px; }
  .nb-sidebar { padding: 0 0 20px; border-right: 0; border-bottom: 1px solid var(--border-light); }
  .nb-filter-section, .nb-filter-section--categories { margin-top: 18px; }
  .nb-category-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .nbq-card-area { min-height: 320px; }
}
@media (max-width: 560px) {
  .nb-header, .nbq-header { min-height: 92px; padding: 16px 0 14px; }
  .nb-title-icon, .nbq-title-icon { width: 36px; height: 36px; }
  .nb-title-icon svg, .nbq-title-icon svg { width: 18px; height: 18px; }
  .nb-title, .nbq-title { font-size: 18px; }
  .nb-quiz-entry { width: 40px; min-height: 40px; justify-content: center; padding: 0; }
  .nb-quiz-entry-label, .nb-quiz-entry-arrow { display: none; }
  .nb-search-input { font-size: 16px; }
  .nb-item { padding: 14px 12px; }
  .nb-item-head { gap: 4px; }
  .nb-item-text { font-size: 15px; }
  .nb-item-actions { opacity: 1; }
  .nb-item-actions button { width: 25px; height: 25px; }
  .nb-item-actions .nb-item-reanalyze, .nb-item-actions .nb-item-annotation { display: none; }
  .nb-item-time { width: 100%; margin-left: 0; }
  .nb-actions-bar { gap: 8px; }
  .nb-select-all span { max-width: 88px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .nbq-toolbar { gap: 12px; padding: 18px 0 10px; }
  .nbq-major-btn { padding: 0 10px; }
  .nbq-card-area { min-height: 290px; padding-bottom: 12px; }
  .nbq-card, .nbq-card-skeleton { aspect-ratio: 4 / 3; min-height: 250px; }
  .nbq-card-face { gap: 14px; padding: 26px 20px; }
  .nbq-card-text { font-size: 18px; }
  .nbq-controls { gap: 7px; }
  .nbq-ctrl-btn { min-height: 42px; padding: 0 7px; }
  .nbq-ctrl-btn span { display: none; }
  .nbq-ctrl-flip span { display: inline; }
}

/* ===== 高中语法学习 ===== */
.eng-grammar-actions { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 8px; margin: 0 0 18px; }
.eng-grammar-actions .btn svg { width: 16px; height: 16px; }
.eng-grammar-chapters { display: grid; border-top: 1px solid var(--border); }
.eng-grammar-chapter-row { display: grid; grid-template-columns: 38px minmax(0, 1fr) 36px; align-items: center; gap: 14px; min-height: 96px; padding: 14px 2px; border-bottom: 1px solid var(--border); }
.eng-grammar-chapter-row:hover { background: color-mix(in srgb, var(--eng-light) 50%, transparent); }
.eng-grammar-order { width: 32px; height: 32px; display: grid; place-items: center; border: 1px solid color-mix(in srgb, var(--eng-color) 30%, var(--border)); border-radius: 7px; background: var(--eng-light); color: var(--eng-color); font-size: 13px; font-weight: 700; }
/* Chapter entry button. Kept as a real <button> for keyboard/AT support, but
   styled as an icon affordance — without this rule the UA default renders a
   grey box that ignores the theme. */
.eng-icon-btn { display: inline-grid; place-items: center; width: 36px; height: 36px; padding: 0; border: 1px solid var(--border); border-radius: 7px; background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast); }
.eng-icon-btn svg { width: 17px; height: 17px; }
.eng-icon-btn:hover { border-color: var(--eng-color); background: var(--eng-light); color: var(--eng-color); }
.eng-icon-btn:focus-visible { outline: 2px solid var(--eng-color); outline-offset: 2px; }
.eng-grammar-chapter-main { min-width: 0; }
.eng-grammar-chapter-main > div { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.eng-grammar-chapter-main h3 { margin: 0; font-size: 15px; letter-spacing: 0; }
.eng-grammar-chapter-main > div > span { flex: 0 0 auto; color: var(--text-tertiary); font-size: 11px; }
.eng-grammar-chapter-main p { margin: 5px 0 9px; color: var(--text-secondary); font-size: 12px; line-height: 1.55; }
.eng-grammar-progress { height: 4px; overflow: hidden; border-radius: 99px; background: var(--bg-tertiary); }
.eng-grammar-progress i { display: block; height: 100%; border-radius: inherit; background: #0f9d74; transition: width .2s ease; }
.eng-grammar-chapter-intro { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 18px 0 24px; border-bottom: 1px solid var(--border); }
.eng-grammar-chapter-intro p { max-width: 650px; margin: 0; color: var(--text-secondary); font-size: 14px; line-height: 1.7; }
.eng-grammar-lessons { display: grid; }
.eng-grammar-lesson { padding: 28px 0; border-bottom: 1px solid var(--border); }
.eng-grammar-lesson-title { display: grid; grid-template-columns: 34px minmax(0, 1fr); align-items: center; gap: 12px; margin-bottom: 16px; }
.eng-grammar-lesson-title > span { width: 30px; height: 30px; display: grid; place-items: center; border-radius: 7px; background: var(--eng-light); color: var(--eng-color); font-size: 12px; font-weight: 700; }
.eng-grammar-lesson-title h2 { margin: 0; font-size: 17px; letter-spacing: 0; }
.eng-grammar-lesson-title small { display: block; margin-top: 3px; color: var(--text-tertiary); font-size: 11px; }
.eng-grammar-rule { margin: 0 0 20px; padding: 13px 15px; border-left: 3px solid var(--eng-color); background: color-mix(in srgb, var(--eng-light) 65%, var(--bg-secondary)); color: var(--text-primary); font-size: 13px; line-height: 1.75; }
.eng-grammar-guide-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; margin-bottom: 18px; }
.eng-grammar-guide-grid h3 { margin: 0 0 9px; color: var(--text-secondary); font-size: 12px; }
.eng-grammar-guide-grid ol, .eng-grammar-guide-grid ul { margin: 0; padding-left: 20px; color: var(--text-secondary); font-size: 12px; line-height: 1.8; }
.eng-grammar-example { display: grid; gap: 4px; padding: 12px 14px; border: 1px solid var(--border); border-radius: 7px; background: var(--bg-secondary); }
.eng-grammar-example p { margin: 0; color: var(--text-primary); font-family: Georgia, 'Times New Roman', serif; font-size: 15px; line-height: 1.5; }
.eng-grammar-example span { color: var(--text-secondary); font-size: 12px; }
.eng-grammar-example small { color: var(--text-tertiary); font-size: 11px; line-height: 1.5; }
.eng-grammar-wrong-list { display: grid; border-top: 1px solid var(--border); }
.eng-grammar-wrong-row { padding: 18px 0; border-bottom: 1px solid var(--border); }
.eng-grammar-wrong-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.eng-grammar-wrong-meta span, .eng-grammar-wrong-meta small { color: var(--text-tertiary); font-size: 11px; }
.eng-grammar-wrong-meta strong { color: var(--eng-color); font-size: 11px; }
.eng-grammar-wrong-meta small { margin-left: auto; }
.eng-grammar-wrong-stem { margin: 12px 0; color: var(--text-primary); font-family: Georgia, 'Times New Roman', serif; font-size: 15px; line-height: 1.6; }
.eng-grammar-wrong-answer { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; color: #b91c1c; font-size: 12px; }
.eng-grammar-wrong-answer strong { color: #15803d; }
.eng-grammar-wrong-explanation { margin: 10px 0 0; color: var(--text-secondary); font-size: 12px; line-height: 1.65; }
.eng-grammar-session-page { max-width: 820px; }
.eng-grammar-session-progress { margin-bottom: 20px; }
.eng-grammar-session-progress > div { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; color: var(--text-tertiary); font-size: 12px; }
.eng-grammar-session-progress > div strong { color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.eng-grammar-session-progress > i { display: block; height: 5px; overflow: hidden; border-radius: 99px; background: var(--bg-tertiary); }
.eng-grammar-session-progress > i > b { display: block; height: 100%; border-radius: inherit; background: var(--eng-color); transition: width .25s ease; }
.eng-grammar-question { min-height: 440px; padding: 28px 0; border-top: 1px solid var(--border); }
.eng-grammar-question-meta { display: flex; align-items: center; gap: 8px; color: var(--text-tertiary); font-size: 11px; }
.eng-grammar-question-meta span { padding: 3px 7px; border-radius: 5px; background: var(--eng-light); color: var(--eng-color); }
.eng-grammar-question h2 { margin: 20px 0 24px; color: var(--text-primary); font-family: Georgia, 'Times New Roman', serif; font-size: 21px; font-weight: 600; line-height: 1.7; letter-spacing: 0; overflow-wrap: anywhere; }
.eng-grammar-options { display: grid; gap: 9px; }
.eng-grammar-option { display: grid; grid-template-columns: 20px 32px minmax(0, 1fr); align-items: center; gap: 11px; min-height: 52px; padding: 9px 13px; border: 1px solid var(--border); border-radius: 7px; background: var(--bg-secondary); cursor: pointer; box-sizing: border-box; }
.eng-grammar-option:hover { border-color: var(--border-hover); background: var(--bg-hover); }
.eng-grammar-option:has(input:checked) { border-color: color-mix(in srgb, var(--eng-color) 55%, var(--border)); background: var(--eng-light); }
.eng-grammar-option input { margin: 0; accent-color: var(--eng-color); }
.eng-grammar-option > span { width: 28px; height: 28px; display: grid; place-items: center; border-radius: 6px; background: var(--bg-tertiary); color: var(--text-secondary); font-size: 12px; font-weight: 700; }
.eng-grammar-option > strong { min-width: 0; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; font-weight: 500; overflow-wrap: anywhere; }
.eng-grammar-option.is-correct { border-color: rgba(22, 163, 74, .45); background: rgba(22, 163, 74, .08); }
.eng-grammar-option.is-correct > span { background: rgba(22, 163, 74, .13); color: #15803d; }
.eng-grammar-option.is-wrong { border-color: rgba(220, 38, 38, .42); background: rgba(220, 38, 38, .07); }
.eng-grammar-option.is-wrong > span { background: rgba(220, 38, 38, .12); color: #b91c1c; }
.eng-grammar-fill { display: grid; gap: 8px; }
.eng-grammar-fill span { color: var(--text-secondary); font-size: 12px; }
.eng-grammar-fill input { width: 100%; min-height: 48px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 7px; outline: 0; background: var(--bg-secondary); color: var(--text-primary); font: inherit; font-family: Georgia, 'Times New Roman', serif; font-size: 16px; box-sizing: border-box; }
.eng-grammar-fill input:focus { border-color: var(--eng-color); box-shadow: 0 0 0 3px var(--eng-light); }
.eng-grammar-feedback { margin-top: 24px; padding: 16px; border-left: 3px solid #16a34a; background: rgba(22, 163, 74, .07); }
.eng-grammar-feedback.is-wrong { border-left-color: #dc2626; background: rgba(220, 38, 38, .06); }
.eng-grammar-feedback-title { display: flex; align-items: center; gap: 8px; color: #15803d; }
.eng-grammar-feedback.is-wrong .eng-grammar-feedback-title { color: #b91c1c; }
.eng-grammar-feedback-title svg { width: 18px; height: 18px; }
.eng-grammar-feedback p { margin: 9px 0 0; color: var(--text-secondary); font-size: 13px; line-height: 1.65; }
.eng-grammar-feedback > .btn { margin-top: 14px; }
.eng-grammar-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.eng-grammar-tags span { padding: 4px 7px; border-radius: 5px; background: rgba(220, 38, 38, .1); color: #b91c1c; font-size: 10px; }
.eng-grammar-summary { min-height: 430px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; border-top: 1px solid var(--border); text-align: center; }
.eng-grammar-summary-score { width: 104px; height: 104px; display: grid; place-content: center; border-radius: 50%; background: var(--eng-light); color: var(--eng-color); font-size: 34px; font-weight: 700; font-variant-numeric: tabular-nums; }
.eng-grammar-summary-score small { font-size: 12px; }
.eng-grammar-summary h2 { margin: 8px 0 0; font-size: 20px; }
.eng-grammar-summary p { margin: 0; color: var(--text-secondary); font-size: 13px; }
.eng-grammar-summary > div { display: flex; gap: 8px; margin-top: 16px; }
.eng-study-empty > svg { width: 28px; height: 28px; }

@media (max-width: 720px) {
  .eng-grammar-chapter-intro { align-items: stretch; flex-direction: column; gap: 14px; }
  .eng-grammar-chapter-intro .btn { align-self: flex-start; }
  .eng-grammar-guide-grid { grid-template-columns: 1fr; gap: 18px; }
  .eng-grammar-question { min-height: 380px; }
  .eng-grammar-question h2 { font-size: 18px; }
}
@media (max-width: 640px) {
  .eng-grammar-page .eng-segmented { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .eng-grammar-chapter-row { grid-template-columns: 32px minmax(0, 1fr) 36px; gap: 10px; }
  .eng-grammar-chapter-main > div { align-items: flex-start; flex-direction: column; gap: 4px; }
  .eng-grammar-wrong-answer { align-items: flex-start; flex-direction: column; gap: 5px; }
  .eng-grammar-option { grid-template-columns: 18px 30px minmax(0, 1fr); padding: 9px; }
  .eng-grammar-summary > div { width: 100%; flex-direction: column; }
}

/* ===== 小说预翻译管理 ===== */
.eng-pre-page { max-width: 1160px; min-height: calc(100vh - 60px); margin: 0 auto; padding-bottom: 64px; }
.eng-action-icon--amber { color: #b76b08; background: rgba(217, 119, 6, .11); }
.eng-pre-icon-btn { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px; padding: 0; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; }
.eng-pre-icon-btn:hover { border-color: var(--eng-color); color: var(--eng-color); }
.eng-pre-icon-btn svg { width: 17px; height: 17px; }
.eng-pre-icon-btn.is-loading svg { animation: eng-pre-spin .8s linear infinite; }
@keyframes eng-pre-spin { to { transform: rotate(360deg); } }
.eng-pre-summary { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin: 0 0 18px; border: 1px solid var(--border); background: var(--border); gap: 1px; }
.eng-pre-summary > div { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; min-height: 58px; padding: 14px 16px; box-sizing: border-box; background: var(--bg-secondary); }
.eng-pre-summary span { color: var(--text-tertiary); font-size: 12px; }
.eng-pre-summary strong { color: var(--text-primary); font-size: 20px; font-variant-numeric: tabular-nums; }
.eng-pre-toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.eng-pre-filters { display: inline-flex; align-items: center; gap: 2px; padding: 3px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-tertiary); }
.eng-pre-filter { min-height: 30px; padding: 0 10px; border: 0; border-radius: 4px; background: transparent; color: var(--text-tertiary); cursor: pointer; font-size: 12px; }
.eng-pre-filter:hover { color: var(--text-primary); }
.eng-pre-filter.is-active { background: var(--bg-secondary); color: var(--text-primary); box-shadow: 0 1px 3px rgba(15, 23, 42, .08); }
.eng-pre-search { position: relative; display: flex; align-items: center; min-width: 180px; flex: 1; }
.eng-pre-search svg { position: absolute; left: 10px; width: 15px; height: 15px; color: var(--text-tertiary); pointer-events: none; }
.eng-pre-search input { width: 100%; height: 38px; padding: 0 12px 0 32px; border: 1px solid var(--border); border-radius: 6px; outline: 0; background: var(--bg-secondary); color: var(--text-primary); font-size: 13px; box-sizing: border-box; }
.eng-pre-search input:focus { border-color: var(--eng-color); box-shadow: 0 0 0 3px var(--eng-light); }
.eng-pre-batch { display: flex; gap: 7px; }
.eng-pre-batch button, .eng-pre-row-all { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 38px; padding: 0 12px; border-radius: 6px; cursor: pointer; font-size: 12px; font-weight: 650; white-space: nowrap; }
.eng-pre-batch button svg, .eng-pre-row-all svg { width: 14px; height: 14px; }
.eng-pre-batch-start { border: 1px solid var(--eng-color); background: var(--eng-color); color: #fff; }
.eng-pre-batch-start:hover { border-color: var(--eng-color-dark); background: var(--eng-color-dark); }
.eng-pre-batch-pause { border: 1px solid var(--border); background: var(--bg-secondary); color: var(--text-secondary); }
.eng-pre-batch-pause:hover { border-color: #d97706; color: #b45309; }
.eng-pre-list-head, .eng-pre-row { display: grid; grid-template-columns: minmax(220px, 1.15fr) minmax(220px, 1fr) minmax(220px, 1fr) 108px; gap: 18px; align-items: center; }
.eng-pre-list-head { min-height: 34px; padding: 0 14px; border-bottom: 1px solid var(--border); color: var(--text-tertiary); font-size: 10px; font-weight: 700; }
.eng-pre-list { border: 1px solid var(--border); border-top: 0; background: var(--bg-secondary); }
.eng-pre-row { min-height: 112px; padding: 14px; border-bottom: 1px solid var(--border-light, var(--border)); }
.eng-pre-row:last-child { border-bottom: 0; }
.eng-pre-row:hover { background: var(--eng-light); }
.eng-pre-book { display: flex; align-items: center; gap: 11px; min-width: 0; }
.eng-pre-cover { position: relative; display: flex; align-items: center; justify-content: center; width: 42px; height: 60px; flex: 0 0 auto; overflow: hidden; border: 1px solid var(--border); border-radius: 4px; background: var(--bg-tertiary); color: var(--text-tertiary); font-size: 11px; font-weight: 700; }
.eng-pre-cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.eng-pre-cover svg { width: 19px; height: 19px; }
.eng-pre-book > div:last-child { min-width: 0; }
.eng-pre-book h3 { margin: 0 0 5px; overflow: hidden; color: var(--text-primary); font-size: 13px; font-weight: 650; line-height: 1.35; text-overflow: ellipsis; white-space: nowrap; }
.eng-pre-book p { margin: 0; color: var(--text-tertiary); font-size: 11px; }
.eng-pre-task { min-width: 0; }
.eng-pre-task-head, .eng-pre-task-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.eng-pre-task-head strong { color: var(--text-secondary); font-size: 11px; font-weight: 650; }
.eng-pre-status { display: inline-flex; align-items: center; gap: 5px; color: var(--text-tertiary); font-size: 10px; white-space: nowrap; }
.eng-pre-status::before { content: ''; width: 6px; height: 6px; flex: 0 0 auto; border-radius: 50%; background: #94a3b8; }
.eng-pre-status.is-running, .eng-pre-status.is-queued { color: #2563eb; }
.eng-pre-status.is-running::before { background: #2563eb; box-shadow: 0 0 0 3px rgba(37, 99, 235, .12); }
.eng-pre-status.is-queued::before { background: #7c3aed; }
.eng-pre-status.is-completed { color: #15803d; }
.eng-pre-status.is-completed::before { background: #16a34a; }
.eng-pre-status.is-paused { color: #a16207; }
.eng-pre-status.is-paused::before { background: #d97706; }
.eng-pre-status.is-pausing { color: #a16207; }
.eng-pre-status.is-pausing::before { background: #d97706; animation: nbPulse 1.2s ease-in-out infinite; }
.eng-pre-status.is-failed { color: #b91c1c; }
.eng-pre-status.is-failed::before { background: #dc2626; }
.eng-pre-progress { height: 5px; margin: 9px 0 7px; overflow: hidden; border-radius: 99px; background: var(--bg-tertiary); }
.eng-pre-progress i { display: block; height: 100%; border-radius: inherit; background: var(--eng-color); transition: width .25s ease; }
.eng-pre-task-foot > span { color: var(--text-tertiary); font-size: 10px; font-variant-numeric: tabular-nums; }
.eng-pre-task-btn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; border: 1px solid var(--border); border-radius: 5px; background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; }
.eng-pre-task-btn:hover:not(:disabled) { border-color: var(--eng-color); color: var(--eng-color); }
.eng-pre-task-btn:disabled { color: #16a34a; cursor: default; opacity: .7; }
.eng-pre-task-btn svg { width: 13px; height: 13px; }
.eng-pre-task-btn[data-control-action="none"] svg, .eng-pre-row-all[data-control-action="none"] svg { animation: eng-pre-spin .9s linear infinite; }
.eng-pre-task-error { margin: 6px 0 0; overflow: hidden; color: #b91c1c; font-size: 10px; text-overflow: ellipsis; white-space: nowrap; }
.eng-pre-row-all { width: 100%; padding: 0 8px; border: 1px solid var(--border); background: var(--bg-secondary); color: var(--text-secondary); }
.eng-pre-row-all:hover { border-color: var(--eng-color); color: var(--eng-color); }
.eng-pre-row-all:disabled { cursor: default; opacity: .65; }
.eng-pre-empty { display: flex; min-height: 260px; flex-direction: column; align-items: center; justify-content: center; gap: 10px; color: var(--text-tertiary); }
.eng-pre-empty svg { width: 24px; height: 24px; }
.eng-pre-empty p { margin: 0; font-size: 13px; }

@media (max-width: 900px) {
  .eng-pre-toolbar { align-items: stretch; flex-wrap: wrap; }
  .eng-pre-filters { order: 1; }
  .eng-pre-search { order: 2; min-width: 240px; }
  .eng-pre-batch { order: 3; width: 100%; }
  .eng-pre-batch button { flex: 1; }
  .eng-pre-list-head { display: none; }
  .eng-pre-list { border-top: 1px solid var(--border); }
  .eng-pre-row { grid-template-columns: minmax(0, 1fr) minmax(180px, .8fr); gap: 14px; }
  .eng-pre-book { grid-column: 1 / -1; }
  .eng-pre-row-all { grid-column: 1 / -1; width: auto; justify-self: end; }
}
@media (max-width: 640px) {
  .eng-segmented { grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-flow: initial; grid-auto-columns: initial; }
  .eng-segmented button { min-width: 0; padding: 7px 4px; font-size: 12px; white-space: nowrap; }
  .eng-pre-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .eng-pre-summary > div { min-height: 50px; padding: 11px 12px; }
  .eng-pre-summary strong { font-size: 18px; }
  .eng-pre-filters { width: 100%; overflow-x: auto; }
  .eng-pre-filter { flex: 1 0 auto; }
  .eng-pre-search { min-width: 100%; }
  .eng-pre-batch { display: grid; grid-template-columns: 1fr 1fr; }
  .eng-pre-row { grid-template-columns: 1fr; gap: 16px; padding: 14px 12px; }
  .eng-pre-book, .eng-pre-row-all { grid-column: auto; }
  .eng-pre-book h3 { white-space: normal; }
  .eng-pre-task { padding-top: 12px; border-top: 1px solid var(--border-light, var(--border)); }
  .eng-pre-row-all { width: 100%; }
}
/* ==== pages/responsive.css ==== */
/* ============================================
   Global responsive overrides (§26) - MUST load last
   Extracted from main.css. Load order matters (see index.html).
   ============================================ */

/* ===== 26. Responsive ===== */
@media (max-width: 900px) { .subject-card-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 768px) {
  :root { --space-lg: 16px; --space-xl: 24px; --nav-height: 56px; }
  #page-container { padding: calc(var(--nav-height) + var(--space-md)) var(--space-md) var(--space-xl); }
  .subject-card-grid { grid-template-columns: 1fr; max-width: 320px; margin: 0 auto; }
  .card-content { flex-direction: row; padding: var(--space-xl); min-height: auto; gap: var(--space-lg); }
  .card-icon-wrapper { width: 64px; height: 64px; flex-shrink: 0; }
  .card-icon-wrapper svg { width: 42px; height: 42px; }
  .card-content > *:not(.card-icon-wrapper):not(.card-arrow) { text-align: left; }
  .card-title { font-size: 1.2rem; }
  .card-desc { font-size: 0.82rem; }
  .card-arrow { position: absolute; right: var(--space-lg); top: 50%; transform: translateY(-50%); width: 32px; height: 32px; margin-top: 0; }
  .hero-stats { gap: var(--space-md); padding: var(--space-md) var(--space-lg); }
  .stat-number { font-size: 1.4rem; }
  .home-shortcuts { gap: var(--space-sm); padding: var(--space-md); }
  .shortcut-item { padding: var(--space-sm) var(--space-sm); }
  .shortcut-icon { width: 38px; height: 38px; }
  .shortcut-icon svg { width: 18px; height: 18px; }
  .shortcut-item span { font-size: 0.72rem; }
  .hero-title { letter-spacing: -0.5px; }
  .card-hint-left, .card-hint-right { display: none !important; }
  .mod-stats-row { grid-template-columns: repeat(2, 1fr); gap: var(--space-sm); }
  .mod-stat { padding: var(--space-sm) var(--space-md); min-height: 56px; }
  .mod-stat-icon { width: 32px; height: 32px; }
  .mod-stat-icon svg { width: 16px; height: 16px; }
  .mod-stat-num { font-size: 1.05rem; }
  .mod-stat-lbl { font-size: 0.62rem; }
  .mod-grid { grid-template-columns: 1fr 1fr; gap: var(--space-sm); }
  .mod-card-inner { padding: var(--space-sm) var(--space-md); gap: var(--space-sm); min-height: 80px; }
  .mod-card-icon-wrap { width: 38px; height: 38px; flex-shrink: 0; }
  .mod-card-icon-wrap svg { width: 18px; height: 18px; }
  .mod-card-info h3 { font-size: 0.88rem; }
  .mod-card-info p { font-size: 0.72rem; }
  .bk-grid { grid-template-columns: 1fr; }
  .ch-grid { grid-template-columns: 1fr 1fr; gap: var(--space-sm); }
  .bk-card-inner { padding: var(--space-lg); min-height: 88px; }
  .bk-icon-wrap { width: 44px; height: 44px; }
  .ch-card-inner { padding: var(--space-lg); min-height: 96px; }
  .review-card { border-radius: var(--radius-xl); box-shadow: var(--shadow-md); }
  .review-card-question { padding: var(--space-md) var(--space-sm) var(--space-sm); }
  .review-card-content { font-size: 0.9rem; line-height: 1.65; }
  .review-card-toggle { padding: 12px var(--space-sm); font-size: 0.82rem; }
  .review-card-answer.expanded .review-card-answer-body { padding: var(--space-sm); }
  .review-card-explanation { padding: var(--space-xs) var(--space-sm); border-radius: var(--radius-md); font-size: 0.82rem; }
  .page-header h1 { font-size: 1.1rem; }
  .page-title-row { gap: var(--space-sm); }
  .wrong-stats-row { grid-template-columns: repeat(2, 1fr); gap: var(--space-sm); }
  .wrong-stat-card { padding: var(--space-sm); }
  .wrong-stat-num { font-size: 1rem; }
  .wrong-toolbar { flex-direction: column; align-items: stretch; }
  .wrong-search-wrap { min-width: 100%; }
  .wrong-filters, .wrong-group-tabs { justify-content: center; }
  .sidebar { width: 100%; }
  .wrong-item .wrong-meta { flex-wrap: wrap; }
  .wrong-item-actions { width: 100%; justify-content: flex-end; margin-top: var(--space-xs); }
  .empty-icon { font-size: 2rem; }
  #toast-container { left: var(--space-md); right: var(--space-md); bottom: var(--space-md); align-items: center; }
  .toast { width: 100%; text-align: center; justify-content: center; font-size: 0.85rem; padding: 10px 16px; }
  .modal-dialog { width: 95%; max-height: 80vh; border-radius: var(--radius-xl); }
  .overlay { padding-top: 8vh; }
  .form-group input, .form-group textarea, .form-group select { padding: 13px 16px; font-size: 16px; }
  .form-group textarea { min-height: 120px; }
  .form-actions { flex-direction: column; gap: var(--space-sm); }
  .form-actions .btn { width: 100%; text-align: center; }
  .btn, .nav-btn, .filter-chip, .card, .chapter-card, .module-card { min-height: 44px; -webkit-user-select: none; user-select: none; }
  .btn { padding: 12px 20px; font-size: 0.9rem; border-radius: var(--radius-md); }
  #page-container { padding-bottom: calc(var(--space-2xl) + env(safe-area-inset-bottom, 0px)); }
}
@media (min-width: 769px) { .nav-btn .btn-label { display: inline; } }
/* Bottom-sheet entrance for phones */
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }

@media (max-width: 600px) {
  .bk-grid { grid-template-columns: 1fr; }
  .ch-grid { grid-template-columns: 1fr 1fr; gap: var(--space-sm); }
  .bk-card-inner { padding: var(--space-lg); min-height: 88px; }
  .bk-icon-wrap { width: 44px; height: 44px; }
  .ch-card-inner { padding: var(--space-lg); min-height: 96px; }
  .page-header h1 { font-size: 1.2rem; }

  /* Content modals become bottom sheets (slide up, full width, rounded top, grab handle) */
  #modal-overlay.overlay { align-items: flex-end; padding: 0; }
  #modal-overlay .modal-dialog,
  #modal-overlay .settings-dialog {
    width: 100%; max-width: 100%; max-height: 92vh;
    border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
    animation: sheetUp 0.3s cubic-bezier(0.25,0.1,0.25,1);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  #modal-overlay .modal-dialog::before,
  #modal-overlay .settings-dialog::before {
    content: ''; display: block; flex: none; width: 40px; height: 4px; margin: 8px auto 0;
    border-radius: var(--radius-full); background: var(--border-hover);
  }
}
@media (max-width: 520px) {
  .list-page { padding: 0 var(--space-sm) var(--space-sm); }
  .list-stats { gap: 6px; }
  .list-stat { padding: 10px 4px; }
  .list-stat__num { font-size: 1.15rem; }
  .list-toolbar { gap: 6px; }
  .list-search { min-width: 140px; }
  .list-search input { height: 34px; font-size: 0.82rem; }
  .list-btn { height: 34px; padding: 0 10px; font-size: 0.76rem; }
  .list-group__header { padding: 10px 12px; }
  .list-item { padding: 12px; }
  .list-item__q { font-size: 0.86rem; }
  .list-item__a { font-size: 0.83rem; padding: 8px 10px; }
  .list-item__e { font-size: 0.8rem; padding: 8px 10px; }
  .mod-stats-row { grid-template-columns: repeat(2, 1fr); gap: var(--space-sm); }
  .mod-stat { padding: var(--space-md); }
  .mod-stat-icon { width: 34px; height: 34px; }
  .mod-stat-icon svg { width: 18px; height: 18px; }
  .mod-stat-num { font-size: 1.3rem; }
  .mod-stat-lbl { font-size: 0.68rem; }
  .mod-grid { grid-template-columns: 1fr !important; gap: var(--space-md); }
  .mod-card-inner { padding: var(--space-lg); min-height: 90px; }
  .mod-card-icon-wrap { width: 46px; height: 46px; }
  .mod-card-icon-wrap svg { width: 22px; height: 22px; }
  .mod-card-info h3 { font-size: 1.05rem; }
  .mod-card-info p { font-size: 0.8rem; }
  .mod-header { gap: var(--space-md); }
  .flashcard-actions { gap: var(--space-sm); padding: var(--space-sm) 0; max-width: 100%; }
  .flashcard-nav-main { width: 100%; justify-content: center; }
  .flashcard-nav-actions { width: 100%; display: grid !important; grid-template-columns: 1fr 1fr; gap: var(--space-xs); justify-content: unset; flex-wrap: unset; }
  .flashcard-nav-actions .btn { flex: 1; justify-content: center; font-size: 0.8rem; padding: 10px 10px; border-radius: var(--radius-md); }
  .ch-grid { grid-template-columns: 1fr !important; }
  .ch-card-inner { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--space-sm); padding: var(--space-md) var(--space-lg); min-height: auto; }
  .ch-top-row { flex: 1; min-width: 0; flex-wrap: nowrap; }
  .ch-num { font-size: 1.1rem; }
  .ch-card-download-btn { width: 24px; height: 24px; }
  .ch-card-download-btn svg { width: 12px; height: 12px; }
  .ch-arrow { display: none; }
  .ch-meta-row { flex-shrink: 0; flex-direction: column; align-items: flex-end; gap: 2px; }
  .ch-name { -webkit-line-clamp: 1; font-size: 0.8rem; }
  .ch-folder-header { padding: var(--space-md) var(--space-lg); gap: var(--space-sm); }
  .ch-folder-icon { width: 20px; height: 20px; }
  .ch-folder-name { font-size: 0.92rem; }
  .ch-folder-count { font-size: 0.75rem; }
  .ch-folder-arrow { width: 16px; height: 16px; }
  .ch-folder-children { margin-left: calc(var(--space-md) + 10px); padding-left: calc(var(--tree-indent, 24px) * 0.8); }
  .ch-file-inner { padding: var(--space-sm) var(--space-lg); gap: var(--space-sm); }
  .ch-file-name { font-size: 0.88rem; }
  .ch-file-meta { font-size: 0.72rem; }
  .review-card-content { font-size: 0.98rem; line-height: 1.65; }
  .page-header h1 { font-size: 1.15rem; }
  #flashcard-progress-text { font-size: 0.78rem !important; padding: 3px 10px; }
  .flashcard-first-btn { font-size: 0.72rem !important; padding: 3px 8px !important; }
  .fc-chapter-name { font-size: 0.75rem; padding: 4px 10px; max-width: calc(100vw - 120px); }
  .item-grid { grid-template-columns: 1fr; gap: 10px; padding: 10px 14px; }
  .item-card__inner { min-height: 72px; }
  .item-card__body { padding: 12px 14px 10px; gap: 4px; }
  .item-card__title { font-size: 0.88rem; }
  .item-card__meta { font-size: 0.72rem; }
  .item-card__ring { width: 38px; height: 38px; margin-right: 12px; }
  .ring-text { font-size: 0.62rem; }
}

/* ===== Very small phones (≤380px) ===== */
@media (max-width: 380px) {
  :root { --space-lg: 14px; }
  .hero-title { font-size: 2rem; }
  .mod-badge-text { font-size: 1.15rem; }
  .modal-header h3, .settings-header h3 { font-size: 0.95rem; }
  .btn { padding: 11px 16px; font-size: 0.85rem; }
  .wrong-tab { padding: 8px 14px; }
}

/* ==== redesign.css ==== */
/* Unified interface layer. Loaded after page styles so every module shares one visual language. */

:root {
  /* 表面色分层（透明 UI 的基础）：
     `--x-solid` 是不透明真值，`--x` 默认指向它。
     启用壁纸时只需在 html.has-wallpaper 里把 --x 重定义为半透明，
     不用在两个文件里各维护一套颜色。改色只改 solid。 */
  --rd-bg-solid: #f4f6f8;
  --rd-surface-solid: #ffffff;
  --rd-surface-2-solid: #f8fafc;
  --rd-line-solid: #dfe3e8;

  --rd-bg: var(--rd-bg-solid);
  --rd-surface: var(--rd-surface-solid);
  --rd-surface-2: var(--rd-surface-2-solid);
  --rd-line: var(--rd-line-solid);
  --rd-line-strong: #c7cdd5;
  --rd-ink: #151922;
  --rd-muted: #666f7c;
  /* #9099a5 only reached 3.03:1 on --rd-bg. Darkened so tertiary text clears
     4.5:1 while staying clearly quieter than --rd-muted. */
  --rd-faint: #656d79;
  --rd-blue: #2563eb;
  /* Fill colour for solid primary surfaces. In light mode this matches --rd-blue;
     in dark mode it stays dark enough for white text (see the dark block below). */
  --rd-blue-strong: #2563eb;
  --rd-blue-soft: #eaf1ff;
  --rd-green: #16845a;
  /* Fill green for solid surfaces (white text). Stays dark in both themes. */
  --rd-green-strong: #15803d;
  --rd-green-soft: #e8f6ef;
  --rd-amber: #b86b00;
  --rd-amber-soft: #fff4df;
  --rd-red: #c43b3b;
  --rd-red-soft: #fff0f0;
  /* Ink for "active" chrome sitting on --rd-blue-soft; darker than --rd-blue
     so small nav labels clear 4.5:1 against the tinted background. */
  --nav-active-ink: #1d4ed8;
  --rd-radius: 8px;
  --rd-shadow: 0 1px 2px rgba(15, 23, 42, .05), 0 8px 24px rgba(15, 23, 42, .05);
  --rd-shadow-hover: 0 2px 3px rgba(15, 23, 42, .06), 0 14px 30px rgba(15, 23, 42, .08);
}

/* English novel reader v2 */
body.eng-reader-active {
  overflow-x: hidden;
  background: #f2f0ea;
}
body.eng-reader-active #top-nav,
body.eng-reader-active #back-to-top {
  display: none !important;
}
body.eng-reader-active #page-container,
body.eng-reader-active #page-container.ov-fullwidth {
  max-width: none;
  min-height: 100dvh;
  padding: 0;
  animation: none;
}

.eng-reader {
  --reader-bg: #f2f0ea;
  --reader-paper: #faf9f5;
  --reader-ink: #292b2d;
  --reader-muted: #73716b;
  --reader-line: #d8d4ca;
  --reader-control: rgba(250, 249, 245, .94);
  min-height: 100dvh;
  color: var(--reader-ink);
  background: var(--reader-bg);
  transition: color .18s ease, background .18s ease;
}
[data-theme="dark"] body.eng-reader-active { background: #141615; }
[data-theme="dark"] .eng-reader {
  --reader-bg: #141615;
  --reader-paper: #1b1e1c;
  --reader-ink: #d8d7d0;
  --reader-muted: #92958f;
  --reader-line: #343936;
  --reader-control: rgba(27, 30, 28, .95);
}

.eng-reading-progress {
  position: fixed;
  z-index: 260;
  top: 0;
  right: 0;
  left: 0;
  height: 3px;
  background: transparent;
  pointer-events: none;
}
.eng-reading-progress-fill {
  width: 0;
  height: 100%;
  border-radius: 0;
  background: #3678d4;
  box-shadow: none;
  transition: width .12s linear;
}

.eng-reader-toolbar {
  position: fixed;
  z-index: 250;
  top: 0;
  right: 0;
  left: 0;
  border-bottom: 1px solid var(--reader-line);
  background: var(--reader-control);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.eng-reader-toolbar-inner {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  width: min(100%, 1080px);
  min-height: 70px;
  margin: 0 auto;
  padding: max(3px, env(safe-area-inset-top)) 20px 0;
  box-sizing: border-box;
}
.eng-reader-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--reader-muted);
  background: transparent;
  cursor: pointer;
}
.eng-reader-icon-btn:hover {
  color: var(--reader-ink);
  border-color: var(--reader-line);
  background: var(--reader-paper);
}
.eng-reader-icon-btn svg { width: 18px; height: 18px; }
.eng-reader-heading { min-width: 0; }
.eng-reader-kicker {
  display: block;
  margin-bottom: 2px;
  color: var(--reader-muted);
  font-size: 10px;
  font-weight: 700;
  line-height: 1.2;
  text-transform: uppercase;
}
.eng-reader-title {
  display: block;
  overflow: hidden;
  color: var(--reader-ink);
  font-size: 14px;
  font-weight: 650;
  line-height: 1.35;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.eng-reader-metrics {
  display: flex;
  align-items: center;
  gap: 13px;
  color: var(--reader-muted);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.eng-reader-sync { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.eng-reader-sync i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #d28a24;
}
.eng-reader-sync[data-state="synced"] i { background: #2e9b68; }
.eng-reader-sync[data-state="offline"] i { background: #c4574f; }
.eng-reader-sync[data-state="local"] i { background: #d28a24; }
.eng-reader-percent {
  min-width: 36px;
  color: var(--reader-ink);
  font-weight: 700;
  text-align: right;
}
.eng-reader-translation-status,
.eng-reader-phrase-status {
  max-width: 86px;
  overflow: hidden;
  color: var(--reader-muted);
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.eng-reader-translation-status[data-state="completed"],
.eng-reader-phrase-status[data-state="completed"] { color: #2e9b68; }
.eng-reader-translation-status[data-state="failed"],
.eng-reader-phrase-status[data-state="failed"] { color: #c4574f; }

.eng-reader-body {
  width: min(calc(100% - 40px), var(--rs-width, 700px));
  max-width: var(--rs-width, 700px);
  min-height: 100dvh;
  margin: 0 auto;
  padding: calc(70px + clamp(46px, 8vh, 86px)) 0 calc(104px + env(safe-area-inset-bottom));
  box-sizing: border-box;
  color: var(--reader-ink);
  font-size: var(--rs-fs, 19px);
  line-height: var(--rs-lh, 1.9);
}
.eng-reader[data-reader-font="serif"] .eng-chapter-content {
  font-family: Georgia, 'Times New Roman', serif;
}
.eng-reader[data-reader-font="sans"] .eng-chapter-content {
  font-family: Inter, 'Segoe UI', Arial, sans-serif;
}
.eng-reader-loading,
.eng-reader-error {
  padding: 18vh 0;
  color: var(--reader-muted);
  font-size: 13px;
  text-align: center;
}
.eng-chapter-heading {
  margin: 0 0 clamp(42px, 8vh, 72px);
  padding: 0;
  color: var(--reader-ink);
  font-size: 2rem;
  font-weight: 650;
  line-height: 1.28;
  text-align: left;
}
.eng-chapter-heading::after { display: none; }
.eng-chapter-content { color: var(--reader-ink); }
.eng-paragraph {
  margin: 0 0 1.45em;
  color: var(--reader-ink);
  line-height: var(--rs-lh, 1.9);
  text-align: left;
  text-indent: 1.7em;
  scroll-margin-top: 90px;
}
.eng-paragraph-original { margin-bottom: .42em; }
.eng-paragraph-translation {
  margin: 0 0 1.45em;
  padding-left: 1em;
  border-left: 2px solid color-mix(in srgb, #3678d4 28%, transparent);
  color: var(--reader-muted);
  font-family: 'Noto Sans SC', 'Microsoft YaHei', sans-serif;
  font-size: .82em;
  line-height: 1.72;
  text-indent: 0;
}
.eng-paragraph-translation.is-pending { color: var(--reader-faint); font-size: .68em; }
.eng-reader[data-translation-mode="original"] .eng-paragraph-translation { display: none; }
.eng-reader[data-translation-mode="translated"] .eng-paragraph-original { display: none; }
.eng-reader[data-translation-mode="translated"] .eng-paragraph-original.eng-paragraph--decorative { display: block; }
.eng-paragraph--decorative { color: var(--reader-faint); text-align: center; text-indent: 0; }
.eng-reader[data-translation-mode="translated"] .eng-paragraph-translation { margin-bottom: 1.45em; padding-left: 0; border-left: 0; color: var(--reader-ink); font-size: 1em; line-height: var(--rs-lh, 1.9); }
.eng-translate-prefetch-note { margin-top: 12px; color: var(--reader-muted, var(--text-tertiary)); font-size: 12px; text-align: center; }
.eng-chapter-content > .eng-paragraph:first-child::first-letter {
  float: none;
  margin: 0;
  color: inherit;
  font: inherit;
}
.eng-phrase-hit {
  border-radius: 2px;
  color: inherit;
  background: transparent;
  cursor: pointer;
  text-decoration-line: underline;
  text-decoration-style: dotted;
  text-decoration-color: color-mix(in srgb, #3678d4 62%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
  transition: background .12s ease, text-decoration-color .12s ease;
}
.eng-phrase-hit:hover,
.eng-phrase-hit:focus-visible {
  outline: 0;
  background: color-mix(in srgb, #3678d4 10%, transparent);
  text-decoration-color: #3678d4;
}
[data-theme="dark"] .eng-phrase-hit {
  text-decoration-color: color-mix(in srgb, #79a9e7 68%, transparent);
}
[data-theme="dark"] .eng-phrase-hit:hover,
[data-theme="dark"] .eng-phrase-hit:focus-visible {
  background: rgba(75, 128, 190, .15);
  text-decoration-color: #8db5e4;
}
.eng-phrase-card {
  position: fixed;
  z-index: 280;
  display: flex;
  flex-direction: column;
  width: min(360px, calc(100vw - 24px));
  max-height: min(62dvh, 520px);
  overflow: hidden;
  border: 1px solid var(--reader-line);
  border-radius: 8px;
  color: var(--reader-ink);
  background: var(--reader-paper);
  box-shadow: 0 16px 40px rgba(22, 27, 31, .2);
  opacity: 0;
  pointer-events: none;
  transform: translateY(4px);
  transition: opacity .12s ease, transform .12s ease;
}
.eng-phrase-card.show {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}
.eng-phrase-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px 12px;
  border-bottom: 1px solid var(--reader-line);
}
.eng-phrase-card-header > div { min-width: 0; }
.eng-phrase-card-header span,
.eng-phrase-card-meaning > span,
.eng-phrase-card-detail > span,
.eng-phrase-card-note > span {
  display: block;
  margin-bottom: 3px;
  color: var(--reader-muted);
  font-family: Inter, 'Segoe UI', sans-serif;
  font-size: 10px;
  font-weight: 700;
}
.eng-phrase-card-header strong {
  display: block;
  overflow-wrap: anywhere;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 20px;
  line-height: 1.25;
}
.eng-phrase-card-close {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 5px;
  color: var(--reader-muted);
  background: transparent;
  cursor: pointer;
}
.eng-phrase-card-close:hover { color: var(--reader-ink); background: var(--reader-bg); }
.eng-phrase-card-close svg { width: 16px; height: 16px; }
.eng-phrase-card-body {
  flex: 1;
  overflow-y: auto;
  padding: 14px 16px;
}
.eng-phrase-card-meaning,
.eng-phrase-card-detail,
.eng-phrase-card-note { margin-bottom: 13px; }
.eng-phrase-card-meaning p,
.eng-phrase-card-detail p,
.eng-phrase-card-note p {
  margin: 0;
  color: var(--reader-ink);
  font-family: 'Noto Sans SC', 'Microsoft YaHei', sans-serif;
  font-size: 13px;
  line-height: 1.65;
}
.eng-phrase-card-meaning p { font-size: 16px; font-weight: 650; }
.eng-phrase-card-note p { color: var(--reader-muted); }
.eng-phrase-card-context {
  margin: 4px 0 12px;
  padding: 8px 0 8px 11px;
  border-left: 2px solid color-mix(in srgb, #3678d4 34%, var(--reader-line));
  color: var(--reader-muted);
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 12px;
  line-height: 1.6;
}
.eng-illustration { margin: 2.4em 0; }
.eng-illus-img {
  display: block;
  max-width: 100%;
  max-height: 76vh;
  margin: 0 auto;
  border-radius: 4px;
  box-shadow: 0 5px 22px rgba(28, 29, 27, .13);
}

.eng-reader-footer {
  position: fixed;
  z-index: 250;
  right: 0;
  bottom: 0;
  left: 0;
  border-top: 1px solid var(--reader-line);
  background: var(--reader-control);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.eng-reader-footer[hidden] { display: none; }
.eng-reader-footer-inner {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  width: min(100%, 760px);
  margin: 0 auto;
  padding: 10px 18px calc(10px + env(safe-area-inset-bottom));
  box-sizing: border-box;
}
.eng-reader .eng-nav-btn {
  min-width: 0;
  min-height: 42px;
  padding: 8px 14px;
  border: 1px solid var(--reader-line);
  border-radius: 6px;
  color: var(--reader-ink);
  background: var(--reader-paper);
  box-shadow: none;
}
.eng-reader .eng-nav-btn:hover {
  border-color: #6f94c3;
  color: #245d9e;
  background: var(--reader-paper);
  transform: none;
}
.eng-reader .eng-nav-btn:disabled {
  visibility: hidden;
  pointer-events: none;
}

.eng-reader .eng-settings-overlay { color: var(--reader-ink); }
.eng-reader .eng-settings-dialog {
  max-width: 460px;
  border: 1px solid var(--reader-line);
  border-radius: 8px;
  color: var(--reader-ink);
  background: var(--reader-paper);
}
.eng-reader .eng-settings-header {
  align-items: center;
  padding: 18px 20px;
  border-bottom-color: var(--reader-line);
}
.eng-reader .eng-settings-header h3 { color: var(--reader-ink); font-size: 16px; }
.eng-settings-eyebrow {
  display: block;
  margin-bottom: 2px;
  color: var(--reader-muted);
  font-size: 10px;
  font-weight: 700;
}
.eng-reader .eng-settings-close { color: var(--reader-muted); border-radius: 5px; }
.eng-reader .eng-settings-body { padding: 18px 20px; }
.eng-settings-group { margin-bottom: 18px; }
.eng-settings-group > label,
.eng-reader .eng-settings-row > label {
  color: var(--reader-ink);
  font-size: 12px;
  font-weight: 650;
}
.eng-settings-group > label { display: block; margin-bottom: 8px; }
.eng-settings-segments {
  display: grid;
  gap: 6px;
  padding: 4px;
  border: 1px solid var(--reader-line);
  border-radius: 6px;
  background: var(--reader-bg);
}
.eng-settings-themes { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.eng-settings-fonts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.eng-settings-translation-modes { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.eng-settings-segments button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 38px;
  padding: 6px 10px;
  border: 1px solid transparent;
  border-radius: 4px;
  color: var(--reader-muted);
  background: transparent;
  cursor: pointer;
}
.eng-settings-segments button svg { width: 15px; height: 15px; }
.eng-settings-segments button.is-active {
  border-color: var(--reader-line);
  color: var(--reader-ink);
  background: var(--reader-paper);
}
.eng-settings-segments small { font-size: 11px; }
.eng-font-serif { font-family: Georgia, serif; font-size: 17px; }
.eng-font-sans { font-family: Arial, sans-serif; font-size: 16px; }
.eng-reader .eng-settings-row { min-height: 48px; padding: 6px 0; }
.eng-reader .eng-settings-controls { gap: 8px; }
.eng-reader .eng-step-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-color: var(--reader-line);
  border-radius: 5px;
  color: var(--reader-ink);
  background: var(--reader-paper);
}
.eng-reader .eng-step-btn svg { width: 15px; height: 15px; }
.eng-reader .eng-step-value { min-width: 56px; color: var(--reader-muted); }
.eng-reader .eng-settings-divider { background: var(--reader-line); }
.eng-reader .eng-settings-reload {
  min-height: 40px;
  margin-top: 0;
  border-radius: 5px;
  background: #326fb9;
}

@media (max-width: 640px) {
  .eng-reader-toolbar-inner {
    grid-template-columns: 38px minmax(0, 1fr) auto;
    min-height: 64px;
    gap: 8px;
    padding-right: 10px;
    padding-left: 10px;
  }
  .eng-reader-sync > span { display: none; }
  .eng-reader-metrics { gap: 8px; }
  .eng-reader-percent { min-width: 32px; }
  .eng-reader-translation-status,
  .eng-reader-phrase-status { max-width: 48px; }
  .eng-reader-body {
    width: min(calc(100% - 32px), var(--rs-width, 700px));
    padding-top: calc(64px + 42px);
    padding-bottom: calc(96px + env(safe-area-inset-bottom));
  }
  .eng-chapter-heading {
    margin-bottom: 44px;
    font-size: 1.55rem;
  }
  .eng-paragraph { margin-bottom: 1.35em; text-indent: 1.45em; scroll-margin-top: 76px; }
  .eng-paragraph-original { margin-bottom: .42em; }
  .eng-paragraph-translation { margin-bottom: 1.35em; padding-left: .75em; font-size: .8em; }
  .eng-reader-footer-inner {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 7px;
    padding: 8px 10px calc(8px + env(safe-area-inset-bottom));
  }
  .eng-reader .eng-nav-btn { min-height: 44px; padding: 7px 8px; font-size: 12px; }
  .eng-reader .eng-settings-overlay { align-items: flex-end; padding: 0; }
  .eng-phrase-card { max-height: min(48dvh, 430px); }
  .eng-reader .eng-settings-dialog {
    max-width: none;
    max-height: min(88dvh, 720px);
    border-right: 0;
    border-bottom: 0;
    border-left: 0;
    border-radius: 8px 8px 0 0;
    padding-bottom: env(safe-area-inset-bottom);
  }
}

[data-theme="dark"] {
  /* 表面色分层（见 :root 的说明）；改色只改 solid。 */
  --rd-bg-solid: #0b0e12;
  --rd-surface-solid: #12161b;
  --rd-surface-2-solid: #171c22;
  --rd-line-solid: #29313a;

  --rd-bg: var(--rd-bg-solid);
  --rd-surface: var(--rd-surface-solid);
  --rd-surface-2: var(--rd-surface-2-solid);
  --rd-line: var(--rd-line-solid);
  --rd-line-strong: #3a4551;
  --rd-ink: #edf1f5;
  --rd-muted: #9aa4b0;
  --rd-faint: #78838f;
  --rd-blue: #76a3ff;
  /* --rd-blue is a *text* blue: it reads well on dark surfaces but white on it
     only reaches 2.5:1. Solid buttons therefore use a darker fill. */
  --rd-blue-strong: #2f5fbe;
  --rd-blue-soft: #182743;
  --rd-green: #55c28d;
  --rd-green-strong: #15803d;
  --rd-green-soft: #153426;
  --rd-amber: #e7a543;
  --rd-amber-soft: #332610;
  --rd-red: #f07d7d;
  --rd-red-soft: #351b1e;
  --nav-active-ink: #9dc0ff;
  --rd-shadow: 0 1px 2px rgba(0, 0, 0, .24), 0 10px 28px rgba(0, 0, 0, .18);
  --rd-shadow-hover: 0 2px 3px rgba(0, 0, 0, .28), 0 16px 34px rgba(0, 0, 0, .24);
}

html { background: var(--rd-bg); }
body {
  background: var(--rd-bg);
  color: var(--rd-ink);
  letter-spacing: 0;
}
/* Reset the legacy tracking, but keep it a plain declaration rather than
   !important so deliberate letter-spacing (uppercase kickers, tabular
   numerals) still applies. */
body * { letter-spacing: normal; }
body::before { display: none; }
#app { min-height: 100vh; }
#top-nav {
  height: 56px;
  background: color-mix(in srgb, var(--rd-bg) 94%, transparent);
  border-bottom-color: var(--rd-line);
  box-shadow: 0 1px 0 rgba(15, 23, 42, .02);
}
.nav-inner { max-width: 1220px; padding: 0 24px; }
.nav-logo { gap: 9px; color: var(--rd-ink); font-size: .94rem; font-weight: 700; }
.logo-icon { width: 30px; height: 30px; border-radius: 7px; background: var(--rd-ink); color: var(--rd-bg); box-shadow: none; }
.logo-icon svg { color: var(--rd-bg); }
.nav-actions { gap: 6px; }
.nav-btn {
  min-height: 36px;
  border-color: var(--rd-line);
  border-radius: 6px;
  background: var(--rd-surface);
  color: var(--rd-muted);
}
.nav-btn:hover { border-color: var(--rd-line-strong); background: var(--rd-surface-2); color: var(--rd-ink); }
.nav-btn.is-active { color: var(--rd-blue); background: var(--rd-blue-soft); border-color: color-mix(in srgb, var(--rd-blue) 28%, var(--rd-line)); }
#page-container {
  max-width: 1220px;
  padding: 84px 28px 72px;
  min-height: 100vh;
}
#page-container.ov-fullwidth { padding: 0; }

button, input, textarea, select { font: inherit; }
button { letter-spacing: 0; }
.btn {
  min-height: 36px;
  padding: 8px 14px;
  border-radius: 6px;
  border-color: var(--rd-line);
  background: var(--rd-surface);
  color: var(--rd-ink);
  box-shadow: none;
}
.btn:hover { background: var(--rd-surface-2); border-color: var(--rd-line-strong); }
.btn-primary { background: var(--rd-blue-strong); border-color: var(--rd-blue-strong); color: #fff; box-shadow: 0 2px 5px color-mix(in srgb, var(--rd-blue-strong) 22%, transparent); }
.btn-primary:hover { background: color-mix(in srgb, var(--rd-blue-strong) 88%, #fff); border-color: color-mix(in srgb, var(--rd-blue-strong) 88%, #fff); }
.btn-success { background: var(--rd-green-strong); border-color: var(--rd-green-strong); }
.btn-danger { background: var(--rd-red); border-color: var(--rd-red); }
.btn-ghost { background: transparent; }
.mod-back-btn, .back-btn, .eng-back-btn {
  width: 38px;
  height: 38px;
  border-radius: 6px;
  border-color: var(--rd-line);
  background: var(--rd-surface);
  color: var(--rd-muted);
}
.mod-back-btn:hover, .back-btn:hover, .eng-back-btn:hover { background: var(--rd-surface-2); color: var(--rd-ink); border-color: var(--rd-line-strong); }

.skeleton, .skeleton-shimmer { background: linear-gradient(90deg, var(--rd-surface-2), color-mix(in srgb, var(--rd-line) 42%, var(--rd-surface-2)), var(--rd-surface-2)); }
.empty-state, .mn-empty, .eng-empty, .sch-empty { color: var(--rd-muted); border: 1px dashed var(--rd-line); background: var(--rd-surface-2); border-radius: var(--rd-radius); }
.modal-dialog, .settings-dialog { border-radius: 8px; border-color: var(--rd-line); background: var(--rd-surface); box-shadow: var(--rd-shadow-hover); }
.modal-header, .settings-header { padding: 16px 20px; border-bottom-color: var(--rd-line); }
.modal-body, .settings-body { padding: 20px; }
.form-group input, .form-group textarea, .form-group select, input[type="text"], input[type="search"], textarea, select {
  border-color: var(--rd-line);
  background: var(--rd-surface);
  color: var(--rd-ink);
  border-radius: 6px;
}
.form-group input:focus, .form-group textarea:focus, .form-group select:focus, input[type="text"]:focus, input[type="search"]:focus, textarea:focus, select:focus { border-color: var(--rd-blue); outline: 3px solid color-mix(in srgb, var(--rd-blue) 18%, transparent); }

/* Shared page header */
.bk-header, .mod-header, .eng-header {
  align-items: flex-start;
  gap: 14px;
  max-width: 1160px;
  margin: 0 auto 28px;
  padding: 0;
}
.bk-title-block, .mod-title-block, .eng-title-block { gap: 5px; }
.mod-subject-badge, .eng-subject-badge {
  width: fit-content;
  padding: 4px 9px;
  border-radius: 5px;
  background: var(--rd-blue-soft);
  border: 1px solid color-mix(in srgb, var(--rd-blue) 20%, var(--rd-line));
  margin-bottom: 4px;
}
.mod-badge-icon, .eng-badge-icon { font-size: 15px; }
/* The per-subject --mc / --eng-color is tuned as a *fill*, so on the badge's
   tinted background it only reached 2.0–4.1:1. The badge already carries the
   subject emoji and name, so the shared accent is used for legibility. */
.mod-badge-text, .eng-badge-text { font-size: .74rem; font-weight: 700; color: var(--rd-blue); }
.mod-page-title { margin: 1px 0 1px; font-size: 1.8rem; line-height: 1.25; color: var(--rd-ink); }
.mod-page-lead { margin: 0; color: var(--rd-muted); font-size: .88rem; }
.mod-subtitle, .eng-subtitle { margin: 1px 0 0; padding: 0; color: var(--rd-muted); font-size: .78rem; }
.eng-page-title { font-size: 1.65rem; color: var(--rd-ink); }

/* Home */
.home-page { max-width: 1160px; margin: 0 auto; padding-bottom: 32px; }
/* The hero copy is left-aligned; the legacy .home-page rule centred it and
   fought the hero grid, so pin the alignment here. */
.home-page .home-hero-copy { text-align: left; }
.home-hero { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(260px, .65fr); gap: 28px; align-items: stretch; margin-bottom: 54px; }
.home-hero-copy { padding: 30px 0 8px; }
.home-kicker, .sch-kicker, .mod-section-kicker { display: block; margin-bottom: 10px; color: var(--rd-blue); font-size: .68rem; font-weight: 800; letter-spacing: .08em; }
.home-hero h1 { margin: 0; max-width: 720px; color: var(--rd-ink); font-size: 3.6rem; line-height: 1.08; }
.home-hero h1 em { color: var(--rd-blue); font-style: normal; }
.home-hero-copy > p { max-width: 560px; margin: 20px 0 24px; color: var(--rd-muted); font-size: 1rem; line-height: 1.8; }
.home-hero-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.home-hero-note { color: var(--rd-faint); font-size: .75rem; }
.home-hero-panel { align-self: end; padding: 22px; border: 1px solid var(--rd-line); border-radius: var(--rd-radius); background: var(--rd-surface); box-shadow: var(--rd-shadow); }
.home-countdown-panel { border-top: 3px solid var(--rd-blue); }
.home-panel-label { color: var(--rd-muted); font-size: .7rem; font-weight: 800; letter-spacing: .08em !important; text-transform: uppercase; }
.home-date-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 12px 0 16px; }
.home-date-value { color: var(--rd-ink); font-size: 1.03rem; font-weight: 750; line-height: 1.35; white-space: nowrap; }
.home-date-tag { flex: none; padding: 4px 6px; border: 1px solid color-mix(in srgb, var(--rd-blue) 30%, var(--rd-line)); border-radius: 4px; color: var(--rd-blue); font-size: .67rem; font-weight: 800; letter-spacing: .08em !important; }
.home-panel-rule { height: 1px; background: var(--rd-line); }
.home-countdown-block { padding: 18px 0 16px; }
.home-countdown-kicker { display: block; color: var(--rd-muted); font-size: .75rem; }
.home-countdown-main { display: flex; align-items: baseline; gap: 8px; margin: 5px 0 3px; }
.home-countdown-main strong { color: var(--rd-blue); font-size: clamp(3.5rem, 7vw, 4.6rem); font-weight: 800; font-variant-numeric: tabular-nums; letter-spacing: -.04em !important; line-height: .95; }
.home-countdown-main span { color: var(--rd-blue); font-size: 1rem; font-weight: 750; }
.home-countdown-target { color: var(--rd-faint); font-size: .68rem; }
.home-panel-quote { position: relative; display: flex; gap: 9px; padding-top: 14px; border-top: 1px solid var(--rd-line); }
.home-panel-quote p { margin: 0; color: var(--rd-muted); font-size: .78rem; line-height: 1.65; }
.home-quote-mark { flex: none; margin-top: -4px; color: var(--rd-amber); font-family: Georgia, serif; font-size: 1.9rem; line-height: 1; }
.home-section-head { display: flex; align-items: end; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
.home-section-head h2 { margin: 0; color: var(--rd-ink); font-size: 1.25rem; }
.home-section-count { color: var(--rd-faint); font-size: .78rem; }
.subject-card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.subject-card { min-height: 142px; overflow: hidden; border: 1px solid var(--rd-line); border-radius: var(--rd-radius); background: var(--rd-surface); cursor: pointer; transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease; }
.subject-card:hover { transform: translateY(-3px); border-color: color-mix(in srgb, var(--subject-color, var(--rd-blue)) 44%, var(--rd-line)); box-shadow: var(--rd-shadow-hover); }
.card-content { position: relative; display: grid; grid-template-columns: 44px 1fr 22px; align-items: center; gap: 14px; min-height: 142px; padding: 22px; }
.card-icon-wrapper { width: 44px; height: 44px; border-radius: 7px; background: var(--rd-surface-2); border: 1px solid var(--rd-line); display: flex; align-items: center; justify-content: center; }
.card-icon-text { font-size: 1.35rem; filter: saturate(.85); }
.card-title { margin: 0; color: var(--rd-ink); font-size: 1rem; font-weight: 700; text-align: left; }
.card-arrow { width: 22px; height: 22px; color: var(--rd-faint); display: flex; align-items: center; justify-content: center; transition: transform .18s ease, color .18s ease; }
.card-arrow svg { width: 17px; height: 17px; }
.subject-card:hover .card-arrow { color: var(--rd-blue); transform: translateX(3px); }
.card-chn { --subject-color: #c24165; }
.card-math { --subject-color: #2563eb; }
.card-eng { --subject-color: #16845a; }
.card-phy { --subject-color: #8b5cf6; }
.card-chem { --subject-color: #b86b00; }
.card-bio { --subject-color: #0f8c72; }

/* Subject workbench */
.modules-page { max-width: 1160px; margin: 0 auto; }
.modules-page .mod-header { margin-bottom: 22px; }
/* auto-fit, not a fixed 4: the row renders 3 stats for most subjects, and a
   fixed 4-column track left the last one orphaned at a third of the width. */
.mod-stats-row { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; margin: 0 0 34px; }
.mod-stat { min-height: 74px; padding: 14px 16px; border: 1px solid var(--rd-line); border-radius: var(--rd-radius); background: var(--rd-surface); box-shadow: none; }
.mod-stat:hover { transform: none; box-shadow: var(--rd-shadow); }
.mod-stat-icon { width: 34px; height: 34px; border-radius: 6px; background: var(--rd-surface-2) !important; color: var(--ms-color, var(--rd-blue)); }
/* The inline --ms-color comes from js/core/constants.js subjectTheme and is
   tuned as a tint, so as the stat number's text colour it only reached 2.15:1
   (chem amber). Numbers are the one place the subject accent must be legible,
   so darken the token for the light theme; dark mode keeps the originals,
   which sit on near-black and read fine. */
.mod-stat-num { color: var(--ms-color, var(--rd-ink)); font-size: 1.2rem; }
[data-theme="light"] .mod-stat[style*="--ms-color"] { --ms-color: var(--rd-ink); }
[data-theme="light"] .mod-stat-num { color: var(--rd-ink); }
.mod-stat-lbl { color: var(--rd-muted); font-size: .68rem; }
.mod-section-head { display: flex; align-items: end; justify-content: space-between; margin-bottom: 12px; }
.mod-section-head h2 { margin: 0; color: var(--rd-ink); font-size: 1.12rem; }
.mod-section-head > span { color: var(--rd-faint); font-size: .75rem; }
.mod-section-kicker { margin-bottom: 3px; font-size: .67rem; }
.mod-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.mod-card { border: 1px solid var(--rd-line); border-radius: var(--rd-radius); background: var(--rd-surface); box-shadow: none; transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease; }
.mod-card:hover { transform: translateY(-3px); border-color: color-mix(in srgb, var(--cci, var(--rd-blue)) 44%, var(--rd-line)); box-shadow: var(--rd-shadow-hover); }
.mod-card-inner { min-height: 104px; padding: 18px; gap: 13px; }
.mod-card-icon-wrap { width: 38px; height: 38px; border-radius: 7px; background: var(--rd-surface-2) !important; border: 1px solid var(--rd-line); color: var(--cci, var(--rd-blue)); }
.mod-card-info h3 { margin-bottom: 5px; color: var(--rd-ink); font-size: .95rem; }
.mod-card-info p { color: var(--rd-muted); font-size: .75rem; }
.mod-card-arrow { width: 22px; height: 22px; color: var(--rd-faint); }
.mod-card:hover .mod-card-arrow { color: var(--cci, var(--rd-blue)); transform: translateX(3px); }

/* Search */
.sch-page { max-width: 1000px; margin: 0 auto; }
.sch-heading { margin: 0 0 26px; }
.sch-heading h1 { margin: 0 0 7px; color: var(--rd-ink); font-size: 1.9rem; }
.sch-heading p { margin: 0; color: var(--rd-muted); font-size: .86rem; }
.sch-sticky { position: sticky; top: 62px; z-index: 10; padding: 12px; margin-bottom: 20px; border: 1px solid var(--rd-line); border-radius: var(--rd-radius); background: color-mix(in srgb, var(--rd-bg) 92%, transparent); box-shadow: 0 6px 18px rgba(15, 23, 42, .05); backdrop-filter: blur(10px); }
.sch-bar { height: 48px; border: 1px solid var(--rd-line-strong); border-radius: 6px; background: var(--rd-surface); }
.sch-bar:focus-within { border-color: var(--rd-blue); box-shadow: 0 0 0 3px color-mix(in srgb, var(--rd-blue) 14%, transparent); }
.sch-bar__icon { color: var(--rd-blue); }
.sch-bar__input { color: var(--rd-ink); font-size: .95rem; }
.sch-filters { display: flex; align-items: center; gap: 12px; padding-top: 10px; }
.sch-filters__chips { gap: 4px; }
.sch-chip { min-height: 30px; padding: 5px 11px; border: 1px solid transparent; border-radius: 5px; color: var(--rd-muted); background: transparent; font-size: .75rem; }
.sch-chip:hover { background: var(--rd-surface-2); color: var(--rd-ink); }
.sch-chip.is-active { background: var(--rd-blue-soft); color: var(--rd-blue); border-color: color-mix(in srgb, var(--rd-blue) 22%, var(--rd-line)); }
.sch-book-btn { min-height: 30px; margin-left: auto; border: 1px solid var(--rd-line); border-radius: 5px; background: var(--rd-surface); color: var(--rd-muted); }
.sch-book-btn:hover { color: var(--rd-ink); border-color: var(--rd-line-strong); }
.sch-groups { padding-top: 8px; }
.sch-group-badge { border-radius: 4px; border: 1px solid var(--rd-line); background: var(--rd-surface); color: var(--rd-muted); }
.sch-results-head { padding: 0 2px 10px; color: var(--rd-muted); }
.sch-card { margin-bottom: 8px; padding: 16px 18px; border: 1px solid var(--rd-line); border-left: 3px solid var(--sc, var(--rd-blue)); border-radius: var(--rd-radius); background: var(--rd-surface); box-shadow: none; }
.sch-card:hover, .sch-card.is-selected { border-color: color-mix(in srgb, var(--sc, var(--rd-blue)) 45%, var(--rd-line)); box-shadow: var(--rd-shadow); transform: none; }
.sch-card__meta { color: var(--rd-faint); }
.sch-card__badge { border-radius: 4px; background: color-mix(in srgb, var(--sc, var(--rd-blue)) 12%, var(--rd-surface)); color: var(--sc, var(--rd-blue)); }
.sch-card__loc { color: var(--rd-faint); }
.sch-card__q { color: var(--rd-ink); font-size: .96rem; line-height: 1.65; }
.sch-card__a { color: var(--rd-muted); border-left-color: var(--rd-line); }
.sch-history { border-top: 1px solid var(--rd-line); }
.sch-history__tag { border-color: var(--rd-line); border-radius: 5px; background: var(--rd-surface); color: var(--rd-muted); }
.sch-book-panel { border: 1px solid var(--rd-line); border-radius: 8px; background: var(--rd-surface); box-shadow: var(--rd-shadow-hover); }
.sch-book-item { border-bottom-color: var(--rd-line); }
.sch-book-item:hover, .sch-book-item.is-selected { background: var(--rd-blue-soft); }

/* Book, chapter and flashcard workspaces */
.books-page, .ch-page, .fc-page { max-width: 1160px; margin: 0 auto; }
.bk-grid, .ch-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.item-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; padding: 0; }
.item-card, .bk-card, .ch-card { border: 1px solid var(--rd-line); border-radius: var(--rd-radius); background: var(--rd-surface); box-shadow: none; }
.item-card:hover, .bk-card:hover, .ch-card:hover { box-shadow: var(--rd-shadow-hover); transform: translateY(-2px); }
.item-card::before, .bk-card-glow, .ch-card-glow { display: none; }
.item-card::after { height: 3px; opacity: 1; background: var(--ic-color, var(--rd-blue)); }
.item-card__inner { min-height: 104px; }
.item-card__body, .bk-card-inner, .ch-card-inner { padding: 18px; }
.item-card__title, .bk-info h3, .ch-name { color: var(--rd-ink); font-size: .94rem; }
.item-card__meta, .bk-info p, .ch-count, .ch-pct { color: var(--rd-muted); }
.item-card__progress, .ch-progress, .bk-progress { background: var(--rd-line); }
.item-card__progress-fill, .ch-progress-bar, .bk-progress-bar { background: var(--ic-color, var(--rd-blue)); box-shadow: none; }
.item-card__ring { width: 42px; height: 42px; }
.fc-page .books-bg-dots, .books-page .books-bg-dots { display: none; }
.flashcard-header-row { max-width: 820px; width: 100%; margin-inline: auto; }
.flashcard-progress-bar, .fc-progress-bar { background: var(--rd-line); box-shadow: none; }
.flashcard-progress-fill, .fc-progress-fill { background: var(--rd-blue); box-shadow: none; }
.review-card { border: 1px solid var(--rd-line); border-radius: var(--rd-radius); background: var(--rd-surface); box-shadow: var(--rd-shadow); }
.review-card-question { padding: 24px 26px 18px; }
.review-card-label { color: var(--rd-faint); font-size: .68rem; }
.review-card-content { color: var(--rd-ink); line-height: 1.8; }
.review-card-answer { border-top-color: var(--rd-line); background: var(--rd-surface-2); }
.review-card-toggle { color: var(--rd-blue); }
.review-card-explanation { background: var(--rd-amber-soft); border-left-color: var(--rd-amber); color: var(--rd-ink); }
.flashcard-actions { max-width: 820px; width: 100%; }
.flashcard-nav-actions .btn-success { background: var(--rd-green-strong); }
.flashcard-nav-actions .btn-danger { background: var(--rd-red); }
.fc-first-btn, .fc-list-btn, .fc-icon-btn { border-radius: 5px; background: var(--rd-surface); border-color: var(--rd-line); }
.fc-first-btn:hover, .fc-list-btn:hover, .fc-icon-btn:hover { background: var(--rd-blue-soft); color: var(--rd-blue); border-color: var(--rd-blue); }
.rv-item { border-bottom-color: var(--rd-line); background: var(--rd-surface); }
.rv-item:hover { background: var(--rd-surface-2); }

/* Quiz selection and question mode */
.quiz-page-inner { max-width: 920px; }
.quiz-scope-list { border: 1px solid var(--rd-line); border-radius: var(--rd-radius); background: var(--rd-surface); overflow: hidden; }
.quiz-scope-group-header, .quiz-scope-book-header { background: var(--rd-surface-2); border-bottom-color: var(--rd-line); }
.quiz-scope-item, .quiz-scope-chapter-item { border-bottom-color: var(--rd-line); }
.quiz-scope-item:hover, .quiz-scope-chapter-item:hover { background: var(--rd-blue-soft); }
.quiz-bottom-bar { border-color: var(--rd-line); background: color-mix(in srgb, var(--rd-surface) 96%, transparent); box-shadow: 0 -6px 20px rgba(15, 23, 42, .06); }
.btn-quiz-start { background: var(--rd-blue) !important; border-radius: 6px !important; }
.qz-question-wrap { max-width: 820px; }
.qz-count-pill { border-radius: 5px; background: var(--rd-blue); }
.qz-actions .qz-btn { border-radius: 6px; }

/* Derivation and math practice */
.dv-problem-card { border-left-width: 3px; border-radius: var(--rd-radius); background: color-mix(in srgb, var(--mc, var(--rd-blue)) 7%, var(--rd-surface)); }
.dv-library-toolbar { display: flex; align-items: end; justify-content: space-between; gap: 16px; margin: 0 0 14px; padding: 0 2px; }
.dv-library-title { display: flex; flex-direction: column; gap: 2px; }
.dv-library-title span { color: var(--rd-blue); font-size: .63rem; font-weight: 800; }
.dv-library-title strong { color: var(--rd-ink); font-size: 1.04rem; }
.dv-library-actions { display: flex; gap: 7px; }
.dv-detail-workspace { max-width: 780px; margin: 0 auto; padding: 0; }
.dv-scene-card, .dv-step.review-card-answer { border-radius: var(--rd-radius); background: var(--rd-surface); border-color: var(--rd-line); }
.dv-nav-bar { background: color-mix(in srgb, var(--rd-surface) 96%, transparent); border-color: var(--rd-line); box-shadow: 0 -6px 20px rgba(15, 23, 42, .06); }
.mp-template-card, .mp-question-card, .mp-diff-btn, .mp-import-panel { border-radius: var(--rd-radius) !important; border-color: var(--rd-line) !important; background: var(--rd-surface) !important; }
.mp-template-card:hover, .mp-diff-btn:hover { border-color: var(--rd-blue) !important; background: var(--rd-blue-soft) !important; }
.mp-diff-btn.active { background: var(--rd-blue-strong) !important; color: #fff !important; border-color: var(--rd-blue-strong) !important; }
.mp-workbench { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 12px; align-items: start; }
.mp-stage { min-width: 0; padding: 18px; border: 1px solid var(--rd-line); border-radius: var(--rd-radius); background: var(--rd-surface); }
.mp-stage:first-child { grid-row: span 2; }
.mp-stage-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.mp-stage-head > div, .mp-stage--launch > div { display: grid; grid-template-columns: 28px 1fr; align-items: center; gap: 8px; }
.mp-stage h3 { margin: 0; color: var(--rd-ink); font-size: .96rem; }
.mp-stage-no { display: flex; align-items: center; justify-content: center; width: 28px; height: 24px; border-radius: 4px; background: var(--rd-blue-soft); color: var(--rd-blue); font-size: .66rem; font-weight: 800; }
.mp-template-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 8px; }
.mp-template-card.selected { border-color: var(--rd-blue) !important; background: var(--rd-blue-soft) !important; box-shadow: inset 0 0 0 1px var(--rd-blue); }
.mp-difficulty-control { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.mp-diff-btn { min-width: 0; width: 100%; }
.mp-stage--launch { display: flex; align-items: center; justify-content: space-between; gap: 12px; grid-column: 1 / -1; }
.mp-stage--launch > div { grid-template-rows: auto auto; }
.mp-stage--launch p { grid-column: 2; margin: 3px 0 0; color: var(--rd-muted); font-size: .76rem; }
.mp-question-area { grid-column: 1 / -1; }

/* Error book and mastered/unmastered lists */
.list-page, .wrong-page { max-width: 1080px; margin: 0 auto; }
/* .list-stat carries `flex: 1` from the legacy flex row. Make the grid intent
   explicit so the cards keep filling their track if the row ever falls back to
   flex (the responsive rules swap the column count). */
.list-stats, .wrong-stats-row { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.list-stat, .wrong-stat-card { width: 100%; border: 1px solid var(--rd-line); border-radius: var(--rd-radius); background: var(--rd-surface); }
.list-stat__num, .wrong-stat-num { color: var(--rd-ink); }
.list-stat__label, .wrong-stat-label { color: var(--rd-muted); }
.list-toolbar, .wrong-toolbar, .eb-toolbar { padding: 10px; border: 1px solid var(--rd-line); border-radius: var(--rd-radius); background: var(--rd-surface-2); }
.list-search, .wrong-search-wrap { border-color: var(--rd-line); background: var(--rd-surface); border-radius: 6px; }
.list-btn, .wrong-tab, .wrong-filter-btn, .wrong-group-btn { border-radius: 5px; border-color: var(--rd-line); }
.list-btn--active, .wrong-tab.active, .wrong-filter-btn.active, .wrong-group-btn.active { background: var(--rd-blue-strong); color: #fff; border-color: var(--rd-blue-strong); }
.list-content, .wrong-list, #error-book-list { border-radius: var(--rd-radius); }
.list-group, .wrong-item, .eb-item { border-color: var(--rd-line); background: var(--rd-surface); border-radius: var(--rd-radius); box-shadow: none; }
.list-group__header { background: var(--rd-surface-2); border-bottom-color: var(--rd-line); }
.list-item { border-bottom-color: var(--rd-line); background: var(--rd-surface); }
.list-item:hover, .wrong-item:hover, .eb-item:hover { background: var(--rd-surface-2); }
.list-item__q, .wrong-question, .eb-question { color: var(--rd-ink); }
.list-item__a, .list-item__e, .wrong-answer, .wrong-explanation, .eb-answer, .eb-explanation { border-left-color: var(--rd-line-strong); background: var(--rd-surface-2); color: var(--rd-muted); }
.eb-toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
#eb-summary { margin-left: auto; color: var(--rd-muted); font-size: .76rem; }
.eb-workspace { padding: 0; }
.eb-category-strip { display: flex; flex-wrap: wrap; gap: 6px; padding: 12px 0; }
.eb-list { display: flex; flex-direction: column; gap: 10px; }
.eb-group-header { margin-top: 8px !important; padding: 5px 2px !important; border-bottom: 1px solid var(--rd-line); }
#eb-categories { padding: 12px 0 !important; }
#eb-categories .nb-cat-btn { border-radius: 5px; border: 1px solid var(--rd-line); background: var(--rd-surface); color: var(--rd-muted); }
#eb-categories .nb-cat-btn.active { background: var(--rd-red-soft); border-color: color-mix(in srgb, var(--rd-red) 38%, var(--rd-line)); color: var(--rd-red); }

/* Notes */
.mn-page, .mn-review-page { max-width: 1160px; margin: 0 auto; }
.mn-shell, .mn-review-shell { padding: 0; }
.mn-toolbar { padding: 12px; border: 1px solid var(--rd-line); border-radius: var(--rd-radius); background: var(--rd-surface-2); }
.mn-start-btn, .mn-add-btn, .mn-act { border-radius: 6px; }
.mn-start-btn { background: var(--rd-blue-strong); color: #fff; }
.mn-act { border-color: var(--rd-line); background: var(--rd-surface); color: var(--rd-muted); }
.mn-act:hover { border-color: var(--rd-blue); color: var(--rd-blue); background: var(--rd-blue-soft); }
.mn-controls { padding: 10px 0; }
.mn-search { border-color: var(--rd-line); border-radius: 6px; background: var(--rd-surface); }
.mn-sort-select { border-color: var(--rd-line); border-radius: 6px; background: var(--rd-surface); }
.mn-filter-bar, .mn-filter-row { border-bottom-color: var(--rd-line); }
.mn-filter-chip, .mn-cat-chip { border-radius: 4px; }
.mn-note-card, .mn-card { border-radius: var(--rd-radius); border-color: var(--rd-line); background: var(--rd-surface); box-shadow: none; }
/* A lone note in a fixed 3-column grid stretched to full width; cap the track
   so one card keeps the same footprint as a full row of cards. */
.mn-grid { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.mn-note-card:hover, .mn-card:hover { border-color: var(--rd-blue); box-shadow: var(--rd-shadow-hover); transform: translateY(-2px); }
.mn-note-card__title, .mn-card-title { color: var(--rd-ink); }
.mn-note-card__meta, .mn-card-meta { color: var(--rd-muted); }
.mn-review-shell { max-width: 820px; margin: 0 auto; }
.mn-fc, .mn-fc-front, .mn-fc-back { border-radius: var(--rd-radius); border-color: var(--rd-line); }
.mn-fc-front { background: var(--rd-surface); }
.mn-fc-back { background: var(--rd-blue-soft); }

/* Overview / print entry */
.overview-page { max-width: 1160px; margin: 0 auto; }
.ov-container { border: 1px solid var(--rd-line); border-radius: var(--rd-radius); background: var(--rd-surface); overflow: hidden; }
.ov-sidebar { background: var(--rd-surface); border-right-color: var(--rd-line); }
.ov-sidebar-header { padding: 14px 16px; border-bottom-color: var(--rd-line); background: var(--rd-surface-2); }
.ov-tree { padding: 10px; }
.ov-group, .ov-book, .ov-folder-node { border-color: var(--rd-line); border-radius: 6px; }
.ov-group-header, .ov-book-header, .ov-folder-hdr { min-height: 42px; padding: 9px 12px; }
.ov-group-header:hover, .ov-book-header:hover, .ov-folder-hdr:hover { background: var(--rd-blue-soft); }
.ov-chapter, .ov-file-node { border-bottom-color: var(--rd-line); border-radius: 4px; }
.ov-chapter:hover, .ov-file-node:hover { background: var(--rd-surface-2); }
.ov-select-count { border-radius: 4px; background: var(--rd-blue); }
.ov-action-btn { border-radius: 5px; border-color: var(--rd-line); background: var(--rd-surface); }
.ov-action-btn:hover { background: var(--rd-blue-soft); color: var(--rd-blue); }
.ovc-item { border-bottom-color: var(--rd-line); }
.ovc-q { color: var(--rd-ink); }
.ovc-a, .ovc-exp { background: var(--rd-surface-2); border-left-color: var(--rd-line-strong); }

/* English subsystem */
.eng-home, .eng-shelf-page, .eng-pre-page { max-width: 1160px; margin: 0 auto; }
.eng-home-bg { display: none; }
.eng-action-row { grid-template-columns: repeat(3, minmax(0, 1fr)); max-width: none; gap: 10px; padding: 0; }
.eng-action-card { min-height: 126px; padding: 18px; gap: 13px; border-radius: var(--rd-radius); border-color: var(--rd-line); background: var(--rd-surface); box-shadow: none; }
.eng-action-card:hover { transform: translateY(-3px); border-color: var(--eng-color); box-shadow: var(--rd-shadow-hover); background: var(--rd-surface); }
.eng-action-icon { width: 40px; height: 40px; border-radius: 6px; }
.eng-action-info h3 { color: var(--rd-ink); font-size: .96rem; }
.eng-action-info p { color: var(--rd-muted); }
.eng-shelf-content { padding: 0; }
.eng-shelf-wrap { gap: 30px; }
.eng-shelf-series { gap: 12px; }
.eng-shelf-series-label { font-size: 1rem; }
.eng-shelf-series-label::before { width: 3px; border-radius: 0; }
.eng-shelf-grid { grid-template-columns: repeat(auto-fill, minmax(142px, 1fr)); gap: 14px; }
.eng-cover-img-wrap { border-radius: 6px; box-shadow: var(--rd-shadow); }
.eng-cover-card:hover .eng-cover-img-wrap, .eng-cover-card:focus-visible .eng-cover-img-wrap { box-shadow: var(--rd-shadow-hover); }
.eng-cover-meta { padding-top: 8px; }
.eng-cover-title { color: var(--rd-ink); }
.eng-cover-sub { color: var(--rd-muted); }
.eng-reading-progress { top: 56px; }
.eng-reader { background: var(--rd-bg); }
.eng-reader-body { max-width: 720px; padding-top: 88px; }
.eng-chapter-heading { color: var(--rd-ink); }
.eng-chapter-heading::after { width: 34px; height: 2px; background: var(--eng-color); }
.eng-paragraph { color: var(--rd-ink); line-height: var(--rs-lh, 1.85); scroll-margin-top: 72px; }
.eng-reader-bottombar { background: color-mix(in srgb, var(--rd-surface) 96%, transparent); border-top-color: var(--rd-line); box-shadow: 0 -6px 20px rgba(15, 23, 42, .07); }
.eng-reader-topbar, .eng-reader-nav { max-width: 760px; }
.eng-reader-btn, .eng-nav-btn { border-radius: 5px; border-color: var(--rd-line); background: var(--rd-surface); }
.eng-reader-btn:hover, .eng-nav-btn:hover { background: var(--rd-blue-soft); border-color: var(--eng-color); }
.eng-step-btn { border-radius: 5px; border-color: var(--rd-line); background: var(--rd-surface); }
.eng-step-btn:hover { border-color: var(--rd-blue); color: var(--rd-blue); background: var(--rd-blue-soft); }
.eng-settings-overlay, .eng-translate-overlay { background: rgba(4, 7, 11, .56); }
.eng-settings-dialog, .eng-translate-sheet { border-radius: 8px; border-color: var(--rd-line); background: var(--rd-surface); box-shadow: var(--rd-shadow-hover); }

/* Existing notebook keeps its task-specific structure, but inherits the same surfaces and controls. */
.nb-page, .nbq-page { background: var(--rd-bg); }
.nb-shell, .nbq-workspace { max-width: 1160px; }
.nb-item, .nbq-card { border-radius: var(--rd-radius); border-color: var(--rd-line); box-shadow: none; }
.nb-item:hover { box-shadow: var(--rd-shadow); }

/* Responsive rules for the shared layer */
@media (max-width: 900px) {
  #page-container { padding: 78px 20px 58px; }
  .home-hero { grid-template-columns: 1fr; gap: 16px; margin-bottom: 38px; }
  .home-hero-copy { padding-top: 10px; }
  .home-hero-panel { max-width: 520px; }
  .subject-card-grid, .mod-grid, .bk-grid, .item-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mod-stats-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .eng-action-row { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  #top-nav { height: 52px; }
  .nav-inner { padding: 0 14px; }
  .nav-logo { font-size: .86rem; }
  .logo-icon { width: 27px; height: 27px; }
  #page-container { padding: 72px 14px 52px; }
  #page-container.ov-fullwidth { padding: 0; }
  .nav-btn { min-width: 36px; padding: 6px 9px; }
  .nav-btn .btn-label { display: none !important; }
  .bk-header, .mod-header, .eng-header { gap: 10px; margin-bottom: 20px; }
  .mod-page-title { font-size: 1.3rem; }
  .home-hero h1 { font-size: 2.35rem; }
  .home-hero-copy > p { font-size: .9rem; line-height: 1.65; }
  .home-hero-panel { padding: 18px; }
  .home-date-value { font-size: .94rem; }
  .home-countdown-main strong { font-size: 3.9rem; }
  .home-section-head { align-items: flex-start; flex-direction: column; gap: 6px; }
  .subject-card-grid, .mod-grid, .bk-grid, .item-grid { grid-template-columns: 1fr; }
  .card-content { min-height: 92px; padding: 16px; }
  .subject-card { min-height: 92px; }
  .mod-stats-row, .list-stats, .wrong-stats-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .mod-stat { min-height: 64px; padding: 11px; }
  .mod-stat-icon { width: 30px; height: 30px; }
  .mod-section-head { align-items: flex-start; }
  .sch-heading h1 { font-size: 1.55rem; }
  .sch-sticky { top: 58px; padding: 8px; }
  .sch-filters { align-items: flex-start; flex-direction: column; gap: 6px; }
  .sch-filters__chips { width: 100%; overflow-x: auto; padding-bottom: 2px; }
  .sch-book-btn { width: 100%; margin-left: 0; justify-content: space-between; }
  .sch-card { padding: 14px; }
  .sch-card__q { font-size: .9rem; }
  .item-card__body, .bk-card-inner, .ch-card-inner { padding: 15px; }
  .review-card-question { padding: 18px 16px 14px; }
  .review-card-content { font-size: .95rem; }
  .flashcard-actions { padding: 0; }
  .flashcard-nav-actions { grid-template-columns: 1fr 1fr; }
  .eb-toolbar { align-items: stretch; }
  .eb-toolbar .btn { flex: 1 1 calc(50% - 8px); }
  #eb-summary { width: 100%; margin-left: 0; }
  .mn-toolbar { align-items: stretch; }
  .mn-start-btn { width: 100%; }
  .mn-actions { width: 100%; }
  .eng-header { padding: 0; }
  .eng-page-title { font-size: 1.35rem; }
  .eng-shelf-content { padding: 0; }
  .eng-shelf-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
  .eng-cover-title { font-size: .74rem; }
  .eng-reader-body { padding: 76px 18px 168px; }
  .eng-paragraph { scroll-margin-top: 64px; }
  .eng-reader-topbar, .eng-reader-nav { padding-left: 14px; padding-right: 14px; }
  .eng-reader-btn span, .eng-nav-btn span { font-size: .72rem; }
  .mp-workbench { grid-template-columns: 1fr; }
  .mp-stage:first-child { grid-row: auto; }
  .mp-stage--launch { grid-column: auto; align-items: stretch; flex-direction: column; }
  .mp-question-area { grid-column: auto; }
}
@media (max-width: 380px) {
  .home-hero h1 { font-size: 2.05rem; }
  .home-hero-actions .btn { width: 100%; }
  .home-hero-note { width: 100%; }
  .eng-shelf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ===== Touch targets (pointer: coarse) =====
   On touch devices the smallest controls sat well under the 44px comfortable
   tap size: the poem pin was 25x25, the question-bank clear button 28x28, the
   scope chips and pagination 31-34px tall. Raise every interactive control to
   a 44px minimum, with 40px for deliberately compact chrome (icon buttons,
   filter chips, pagination). Only min-height is set, so text-led controls grow
   naturally instead of clipping. */
@media (pointer: coarse) {
  /* Explicit selectors, not a bare `button` reset: page rules such as
     `.cm-mode-switch button` (0,1,1) and `.bm-actions .button` (0,2,0) outrank
     an element selector, so a generic rule silently loses to them. Only
     min-height is set, so text-led controls grow instead of clipping. */
  .btn, .btn-sm, .nav-btn, .filter-chip, .sch-chip, .sch-book-btn, .list-btn,
  .wrong-tab, .wrong-filter-btn, .wrong-group-btn, .mn-act, .mn-start-btn,
  .mn-add-btn, .mn-primary-action, .mn-quiet-action, .mn-group-tab,
  .mn-group-add, .eng-icon-btn, .eng-back-btn, .mod-back-btn, .back-btn,
  .eng-segmented button, .fc-first-btn, .fc-list-btn, .fc-icon-btn,
  .qb-page-btn, .qb-clear, .cf-continue-btn, .cf-status-btn, .cf-filter button,
  .ce-primary-button, .ce-step-nav button, .cm-pin, .cm-start, .cm-reveal,
  .cm-status, .cm-nav-btn, .cm-select-all, .cm-mode-switch button,
  .bm-start-btn, .bm-actions .button, .bm-panel .button, .bm-field select,
  .bm-pages-tools button, .bm-panel-tools button,
  .emm-icon-btn, .emm-tab, .emm-filter, .emm-chip, .emm-search,
  .emm-paper-type, .emm-paper-radios label,
  .emm-cal-cell, .emm-cal-nav,
  .ceb-back-btn, .ceb-icon-btn, .ceb-modal-close, .ceb-toolbar-btn,
  .ceb-action-btn, .ceb-filter-btn, .ceb-main-btn,
  .um-group-switch button, .um-mark-group, .um-mark-btn,
  .modal-close, .settings-close, .shortcut-item, .list-item__act {
    min-height: 44px;
  }
  /* compact chrome: comfortably tappable without full row height */
  .nav-btn, .filter-chip, .sch-chip, .eng-icon-btn, .mod-back-btn, .back-btn,
  .eng-back-btn, .fc-icon-btn, .qb-page-btn, .cm-pin, .qb-clear,
  .modal-close, .settings-close { min-height: 40px; }
  /* square icon controls need the same treatment on the width axis */
  .eng-icon-btn, .mod-back-btn, .back-btn, .eng-back-btn, .fc-icon-btn,
  .cm-pin, .qb-clear, .modal-close, .settings-close { min-width: 40px; }
  /* the pin is absolutely positioned in the card corner — keep it inside */
  .cm-pin { top: 6px; right: 6px; }
  /* form controls and search wrappers */
  input[type="text"], input[type="search"], input[type="number"],
  input[type="email"], input[type="password"], select, textarea,
  .bm-search, .cm-search, .cf-search, .sch-bar, .list-search, .mn-search,
  .ceb-search { min-height: 44px; }
  summary { min-height: 44px; }
  /* keep the page-tile grid from growing past its column */
  .bm-page-tile { min-height: 44px; }
}

/* ===== Dark-theme accent ink =====
   Each subject page owns a saturated accent tuned for light surfaces, declared
   on its own page container (.ce-page, .cm-page, ...) — which outranks a bare
   [data-theme] selector, so these are scoped to the container to match.
   IMPORTANT: only the *text* rules are overridden here, never the accent token
   itself. The same token also fills solid buttons (e.g. .bm-start-btn,
   .cm-mode-switch button.is-active) where white text sits on it; lightening
   the token fixed the labels but dropped those buttons to ~2.1:1. The
   originals land between 2.7:1 and 4.3:1 as text on the dark background —
   below AA for the small eyebrows, kickers and badges they colour. */
[data-theme="dark"] .ce-page { --ce-ink: #e8a33c; }  /* 化学专项 text — was #b45309 (2.97:1) */

/* Amber used as *text* on the dark background. --ce-accent itself is left
   alone because it also fills .ce-primary-button and .ce-mode-switch
   [aria-pressed=true], where white text needs the darker amber. */
[data-theme="dark"] .ce-page .ce-kicker,
[data-theme="dark"] .ce-page .ce-section-label,
[data-theme="dark"] .ce-page .ce-hub-summary__copy > span,
[data-theme="dark"] .ce-page .ce-hub-progress strong,
[data-theme="dark"] .ce-page .ce-progress-block strong,
[data-theme="dark"] .ce-page .ce-apparatus-node span,
[data-theme="dark"] .ce-page .ce-step-nav button.is-active,
[data-theme="dark"] .ce-page .ce-mcq-kicker,
[data-theme="dark"] .ce-page .ce-full-chain__head span,
[data-theme="dark"] .ce-page .ce-icon-button:hover,
[data-theme="dark"] .ce-page .ce-loading > span { color: var(--ce-ink); }

[data-theme="dark"] .cm-page .cm-eyebrow,
[data-theme="dark"] .cm-page .cm-kicker,
[data-theme="dark"] .cm-page .mod-badge-text,
[data-theme="dark"] .cm-page .cm-poem-meta b { color: #f2854a; }  /* 语文默写 — was #c2410c (3.73:1) */

[data-theme="dark"] .qb-page .qb-eyebrow,
[data-theme="dark"] .qb-page .qb-toolbar-kicker,
[data-theme="dark"] .qb-page .qb-card-index,
[data-theme="dark"] .qb-page .qb-section-label { color: #9d9ef5; }  /* 题库浏览 — was #6366f1 (4.33:1) */

[data-theme="dark"] .bm-page .bm-eyebrow,
[data-theme="dark"] .bm-page .bm-source-badge,
[data-theme="dark"] .bm-page .bm-progress-head strong { color: #4ec97f; }  /* 生物闪卡 — was #15803d (3.86:1) */

[data-theme="dark"] .mn-page .mn-intro-eyebrow,
[data-theme="dark"] .mn-page .mn-editor-eyebrow,
[data-theme="dark"] .mn-page .mn-group-add { color: #a5a1f0; }  /* 数学笔记 — was #4f46e5 (3.08:1) */

/* ===== Keyboard focus =====
   Only a handful of selectors declared a real focus ring, so tabbing through
   most pages gave no visible indication (some controls changed border colour
   only, which is easy to miss and fails WCAG 2.4.11). One ring for everything,
   in the shared accent, offset so it clears adjacent cards.
   NOTE 1: do NOT wrap this in :where() — that has zero specificity and
   silently loses to the outline:none rules page styles set on :focus.
   NOTE 2: the [class] qualifier is deliberate — it lifts specificity to
   (0,2,0)+ so this wins over the legacy `--accent` (indigo) rings declared in
   main.css, keeping every focus ring the same colour app-wide. */
a[class]:focus-visible, button[class]:focus-visible, input[class]:focus-visible,
select[class]:focus-visible, textarea[class]:focus-visible,
summary[class]:focus-visible, [tabindex][class]:focus-visible,
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--rd-blue);
  outline-offset: 2px;
}
/* Fields inside a focus-within wrapper get their ring from the wrapper instead,
   so the inner input must not draw a second one. */
.bm-search input:focus-visible,
.cm-search input:focus-visible,
.cf-search input:focus-visible,
.sch-bar__input:focus-visible { outline: none; }
.bm-search:focus-within,
.cm-search:focus-within,
.cf-search:focus-within,
.sch-bar:focus-within {
  border-color: var(--rd-blue);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--rd-blue) 20%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; transition-duration: .001ms !important; }
}

/* Keep the dedicated reader independent from shared English page overrides above. */
body.eng-reader-active .eng-reading-progress { top: 0; }
body.eng-reader-active .eng-reader { background: var(--reader-bg); }
body.eng-reader-active .eng-reader-body {
  width: min(calc(100% - 40px), var(--rs-width, 700px));
  max-width: var(--rs-width, 700px);
  padding: calc(70px + clamp(46px, 8vh, 86px)) 0 calc(104px + env(safe-area-inset-bottom));
}
body.eng-reader-active .eng-paragraph {
  color: var(--reader-ink);
  scroll-margin-top: 90px;
}
@media (max-width: 640px) {
  body.eng-reader-active .eng-reader-body {
    width: min(calc(100% - 32px), var(--rs-width, 700px));
    padding: 106px 0 calc(96px + env(safe-area-inset-bottom));
  }
  body.eng-reader-active .eng-paragraph { scroll-margin-top: 76px; }
}
/* ==== refine.css ==== */
/* ============================================================
   refine.css — v7 视觉统一层（2026-10）
   ============================================================

   ## 这一层是干什么的

   站点的样式基础来自 main.css（Design Token）与 redesign.css（统一界面层），
   之后还有 pages/wallpaper.css 负责「有壁纸时的玻璃质感」。这一层排在
   redesign 之后、wallpaper 之前（见 utils/cssBundle.js 的 BUNDLE_SHEETS），
   职责只有一个：**把已经存在但彼此不一致的视觉语言收敛成一套**，并给
   高频页面补一层更克制的排版/留白/层次。

   它不新建 DOM、不改动任何 data-action、不引入外部字体或图片，纯样式覆盖。
   所以出问题时删掉这一个文件、从 bundle 清单里去掉那一行，就能回到原样。

   ## 为什么必须动（不是「换个皮」）

   改造前的站点同时存在两套调色板：main.css 的 --accent 是靛蓝
   （亮 #4c56c0 / 暗 #5e6ad2），redesign.css 的 --rd-blue 是另一支蓝
   （亮 #2563eb / 暗 #76a3ff），而英语子系统又有自己的 --eng-color
   （#3b82f6）。三支蓝并存的结果是：同一个「主按钮」在不同页面颜色不同，
   相邻的 chip / tab / 按钮站在一起能看出色相差异。这一层把三支合并成
   **一支 cobalt（亮 #3e63dd / 暗文本 #8fa1f8）**，并区分「文字用色」与
   「实底填充用色」——深色主题下后者必须足够深，白字才过 AA。

   其余改动同理：圆角从 4/6/8/12 混用收敛为稀疏梯度（控件 8~10、
   卡片 12~16、弹层 18）；阴影从单层硬阴影换成带负扩散的柔光双层；
   字号恢复被 redesign 的 `body * { letter-spacing: normal }` 一并抹掉的标题字距。

   ## ⚠ 三条硬约束（改之前先读）

   1. **表面色只用 Token，不写死颜色**：有壁纸时 wallpaper.css 会把
      --bg-secondary / --rd-surface 等换成半透明玻璃。这里任何写死
      #fff / #111 的 background 都会在壁纸模式下变成贴在照片上的实色块。
      所以本文件只改 solid 真值（--x-solid）与派生 Token，让玻璃层自动跟随。
   2. **实底蓝与文字蓝必须分开**：深色主题里 --accent 是「浅蓝文字色」
      （#8fa1f8），拿它当按钮底色 + 白字只有 2.4:1。所有实底一律用
      --accent-fill（#3e63dd），白字 5.2:1。新增实底控件时不要用 --accent。
   3. **不要在这里给「裸文字」新加容器**：wallpaper.css 有一份按结构兜底的
      页头/标题背衬名单。若在这里给某段直接铺在页面上的说明文字加样式，
      记得把它加进 wallpaper.css 的「零散小字背衬」名单，否则壁纸亮部读不清。
   ============================================================ */

/* ============================================================
   1. Design Token（亮色）
   ============================================================ */

:root {
  color-scheme: light;

  /* ---- 表面色分层 ----
     solid 是不透明真值，别名默认指回它；壁纸模式只重定义别名。
     亮色用极浅的冷灰纸面 + 纯白卡片，靠边框和 1px 高光分层，不靠灰度。 */
  --bg-primary-solid: #f6f6f8;
  --bg-secondary-solid: #ffffff;
  --bg-tertiary-solid: #f1f1f4;
  --surface-solid: #ffffff;
  --surface-strong-solid: #ffffff;

  --bg-primary: var(--bg-primary-solid);
  --bg-secondary: var(--bg-secondary-solid);
  --bg-tertiary: var(--bg-tertiary-solid);
  --bg-hover: #eeeef2;
  --bg-active: #e6e6ec;

  --surface: var(--surface-solid);
  --surface-strong: var(--surface-strong-solid);
  --surface-border: rgba(20, 22, 30, 0.09);

  --text-primary: #17181d;
  --text-secondary: #555862;
  /* #6b6e79 在 #f6f6f8 上是 4.73:1，过 AA；比 secondary 弱但层次仍清楚。 */
  --text-tertiary: #6b6e79;
  --text-inverse: #ffffff;

  /* ---- 主色：一支 cobalt ----
     --accent      文字/图标/描边用（深色主题要够亮）
     --accent-fill 实底填充用（两种主题都要够深，白字过 AA） */
  --accent: #3e63dd;
  --accent-hover: #3457c8;
  --accent-dark: #2b4bb4;
  --accent-light: rgba(62, 99, 221, 0.09);
  --accent-subtle: rgba(62, 99, 221, 0.18);
  --accent-rgb: 62, 99, 221;
  --accent-fill: #3e63dd;
  --accent-fill-hover: #3457c8;
  --accent-fill-active: #2b4bb4;

  --success: #157a49;
  --success-solid: #147247;
  --success-light: rgba(21, 122, 73, 0.10);
  --warning: #9a6208;
  --warning-solid: #8f5a0d;
  --warning-light: rgba(154, 98, 8, 0.10);
  --danger: #c4372f;
  --danger-solid: #bf3a31;
  --danger-light: rgba(196, 55, 47, 0.09);
  /* 「淡底 + 小字」徽章用的文字色：比 --success/--warning/--danger 更深一档，
     保证在 12%~18% 的彩色淡底上仍过 4.5:1（深色主题直接用亮色即可）。 */
  --success-ink: #147247;
  --warning-ink: #8a5506;
  --danger-ink: #b23329;
  /* 淡色底（12%~18% 混色）上的文字色说明见 6c 段。 */

  --border: rgba(20, 22, 30, 0.09);
  --border-light: rgba(20, 22, 30, 0.055);
  --border-hover: rgba(20, 22, 30, 0.18);

  /* ---- 阴影：双层柔光（一层贴边、一层大扩散），避免「灰边」感 ---- */
  --shadow-xs: 0 1px 2px rgba(18, 21, 32, 0.05);
  --shadow-sm: 0 1px 2px rgba(18, 21, 32, 0.05), 0 1px 1px rgba(18, 21, 32, 0.03);
  --shadow-md: 0 2px 4px rgba(18, 21, 32, 0.05), 0 8px 18px -8px rgba(18, 21, 32, 0.10);
  --shadow-lg: 0 4px 10px rgba(18, 21, 32, 0.06), 0 20px 44px -20px rgba(18, 21, 32, 0.18);
  --shadow-xl: 0 8px 22px rgba(18, 21, 32, 0.10), 0 36px 90px -30px rgba(18, 21, 32, 0.28);
  --shadow-card: var(--shadow-sm);
  --shadow-card-hover: var(--shadow-lg);

  --code-bg: #15171e;
  --code-text: #e9ebf1;

  /* ---- 圆角：有序梯度，不再 4/6/8/10/12 混用 ---- */
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 10px;
  --radius-xl: 14px;
  --radius-2xl: 18px;
  --radius-full: 9999px;

  /* ---- 动效：统一缓动 + 统一时长，交互手感才一致 ---- */
  --ease-standard: cubic-bezier(0.2, 0.7, 0.25, 1);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --transition-fast: 110ms var(--ease-standard);
  --transition-base: 150ms var(--ease-standard);
  --transition-normal: 200ms var(--ease-out);
  --transition-slow: 280ms var(--ease-out);

  --nav-height: 60px;
  --max-width: 1220px;
  --sidebar-width: 280px;

  /* ---- 排版 ----
     不引入外部字体：Inter 有则用，否则退到系统 UI 字体。
     Windows 上 Segoe UI Variable 的字面比旧版 Segoe UI 更紧凑，是首选回退。 */
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text",
    "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI",
    "Microsoft YaHei", "Noto Sans SC", sans-serif;
  --font-display: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI Variable Display",
    "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI",
    "Microsoft YaHei", "Noto Sans SC", sans-serif;
  --font-reading: Georgia, "Times New Roman", "Songti SC", "Noto Serif SC", serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Code", "JetBrains Mono", Menlo, Consolas, monospace;

  --fs-xs: 0.75rem;
  --fs-sm: 0.82rem;
  --fs-md: 0.9rem;
  --fs-lg: 1.05rem;
  --fs-xl: 1.25rem;
  --fs-2xl: 1.6rem;
  --lh-tight: 1.25;
  --lh-normal: 1.6;
  --lh-relaxed: 1.8;

  --elevation-1: var(--shadow-sm);
  --elevation-2: var(--shadow-md);
  --elevation-3: var(--shadow-lg);
  --elevation-4: var(--shadow-xl);

  --focus-ring: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);

  /* ---- 统一表面渐变（v10「透明渐变」） ----
     全站承载文字的卡片/面板/弹窗共用同一套渐变。

     ⚠ v10 换的是**颜色思路**，不是角度：
       · v9 把白色掺进表面色（`#fff 16% + #111114`），结果顶部是一块
         发灰的"黑白渐变"，和整体配色不搭；
       · v10 改成**只动透明度**：表面色本身一字节不变，只是从「略透」
         渐变到「实」—— 即玻璃的**厚度渐变**，不引入任何灰调。
         透明度变化 = 壁纸/页面底色透出来的多少，天然跟主题同色系。

     ⚠ 顶部透明度有**可读性上限**：--rd-surface 在壁纸下已是 94% 玻璃，
       再乘一个系数会跌破 AA 下限（深色 + 纯白壁纸时 tertiary 只有
       1.6~2:1）。所以这里的 ramp 只从 96% → 100%，差值很小 ——
       视觉上的"层次"主要靠下面的 --surface-glow（透明彩色泛光）提供，
       不靠压暗/提亮表面。 */
  --surface-grad: linear-gradient(150deg,
    color-mix(in srgb, var(--rd-surface) 96%, transparent) 0%,
    color-mix(in srgb, var(--rd-surface) 99%, transparent) 50%,
    var(--rd-surface) 100%);
  /* 左上角的**透明彩色**泛光：这才是这一版的主视觉 ——
     主色以低透明度径向铺开，不做明度变化，所以不会发灰、不会脏。
     比例刻意压低（7%）：只在"大面板 + 深色"上是一团柔光，
     377px 卡片上只是让左上角微微偏蓝，不破坏中性色。 */
  --surface-glow: radial-gradient(120% 90% at 0% 0%,
    color-mix(in srgb, var(--accent) 7%, transparent) 0%,
    transparent 60%);
  /* 强调面（hero / 倒计时面板）：同一套透明思路，只是泛光加重。 */
  --surface-accent-grad:
    radial-gradient(130% 100% at 0% 0%,
      color-mix(in srgb, var(--accent) 12%, transparent) 0%,
      transparent 65%),
    linear-gradient(150deg,
      color-mix(in srgb, var(--rd-surface) 94%, transparent) 0%,
      var(--rd-surface) 100%);
  /* 内高光：玻璃顶边的一道 1px 反光，配合透明度渐变才有"厚度"。
     斜向光从左上来，所以顶边 + 左边各一道。 */
  --surface-sheen:
    inset 0 1px 0 rgba(255, 255, 255, 0.6),
    inset 1px 0 0 rgba(255, 255, 255, 0.28);

  /* ---- 统一界面层的 --rd-* 家族 ----
     这些 Token 被 redesign.css 之后的 60+ 个组件直接引用。
     这里让它们与上面的主 Token **同源**，而不是再各写一套颜色。 */
  --rd-bg-solid: #f6f6f8;
  --rd-surface-solid: #ffffff;
  --rd-surface-2-solid: #f8f8fa;
  --rd-line-solid: #e4e4ea;

  --rd-bg: var(--rd-bg-solid);
  --rd-surface: var(--rd-surface-solid);
  --rd-surface-2: var(--rd-surface-2-solid);
  --rd-line: var(--rd-line-solid);
  --rd-line-strong: #cfd0d8;

  --rd-ink: #17181d;
  --rd-muted: #555862;
  --rd-faint: #6b6e79;

  /* 文字蓝与实底蓝分开（见文件头第 2 条约束）。 */
  --rd-blue: var(--accent);
  --rd-blue-strong: var(--accent-fill);
  --rd-blue-soft: #eef1fc;
  --nav-active-ink: #2b4bb4;

  --rd-green: var(--success);
  --rd-green-strong: var(--success-solid);
  --rd-green-soft: #eaf5ef;
  --rd-amber: var(--warning);
  --rd-amber-soft: #fbf2e2;
  --rd-red: var(--danger);
  --rd-red-soft: #fcedec;

  --rd-radius: 12px;
  --rd-shadow: 0 1px 2px rgba(18, 21, 32, 0.05), 0 10px 28px -14px rgba(18, 21, 32, 0.14);
  --rd-shadow-hover: 0 2px 4px rgba(18, 21, 32, 0.06), 0 20px 44px -20px rgba(18, 21, 32, 0.22);

  /* 英语子系统的强调色向主色收敛（原来 #3b82f6 与主色是两支蓝）。
     文字色和实底色分开：--eng-ink 才是文字，--eng-color 用于描边/浅底。 */
  --eng-color: #2f66e0;
  --eng-color-dark: #2455c4;
  --eng-light: rgba(47, 102, 224, 0.08);
  --eng-light-2: rgba(47, 102, 224, 0.16);
  --eng-ink: #2455c4;
}

/* ============================================================
   2. Design Token（暗色 · 默认主题）
   ============================================================ */

[data-theme="dark"] {
  color-scheme: dark;

  --bg-primary-solid: #09090c;
  --bg-secondary-solid: #111114;
  --bg-tertiary-solid: #18181d;
  --surface-solid: #111114;
  --surface-strong-solid: #15151a;

  --bg-primary: var(--bg-primary-solid);
  --bg-secondary: var(--bg-secondary-solid);
  --bg-tertiary: var(--bg-tertiary-solid);
  --bg-hover: #1c1c22;
  --bg-active: #24242c;

  --surface: var(--surface-solid);
  --surface-strong: var(--surface-strong-solid);
  --surface-border: rgba(255, 255, 255, 0.09);

  --text-primary: #f1f1f4;
  --text-secondary: #a4a6af;
  /* #8b8e99 在 #111114 上 5.7:1，在 94% 玻璃面上 5.4:1，都过 AA。 */
  --text-tertiary: #8b8e99;

  /* 深色下文字蓝要够亮（#8fa1f8 对比 7.7:1）；
     实底蓝保持 #3e63dd，白字 5.2:1、与近黑底 3.8:1 可辨识。 */
  --accent: #8fa1f8;
  --accent-hover: #a2b1fa;
  --accent-dark: #7c90f2;
  --accent-light: rgba(143, 161, 248, 0.12);
  --accent-subtle: rgba(143, 161, 248, 0.24);
  --accent-rgb: 143, 161, 248;
  --accent-fill: #3e63dd;
  --accent-fill-hover: #4a6fe8;
  --accent-fill-active: #3457c8;

  --success: #4ec48c;
  --success-solid: #267a4d;
  --success-light: rgba(78, 196, 140, 0.12);
  --warning: #e3a94a;
  --warning-solid: #8f5a0d;
  --warning-light: rgba(227, 169, 74, 0.12);
  --danger: #f07b72;
  --danger-solid: #b93b34;
  --danger-light: rgba(240, 123, 114, 0.12);
  --success-ink: #4ec48c;
  --warning-ink: #e3a94a;
  --danger-ink: #f07b72;

  --border: rgba(255, 255, 255, 0.085);
  --border-light: rgba(255, 255, 255, 0.05);
  --border-hover: rgba(255, 255, 255, 0.17);

  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.40);
  --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.35), 0 8px 20px -8px rgba(0, 0, 0, 0.50);
  --shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.35), 0 24px 52px -24px rgba(0, 0, 0, 0.65);
  --shadow-xl: 0 10px 26px rgba(0, 0, 0, 0.45), 0 40px 100px -32px rgba(0, 0, 0, 0.80);
  --shadow-card: var(--shadow-sm);
  --shadow-card-hover: var(--shadow-lg);

  --code-bg: #16171c;
  --code-text: #e9ebf1;

  --rd-bg-solid: #09090c;
  --rd-surface-solid: #111114;
  --rd-surface-2-solid: #17171b;
  --rd-line-solid: #27272e;

  --rd-bg: var(--rd-bg-solid);
  --rd-surface: var(--rd-surface-solid);
  --rd-surface-2: var(--rd-surface-2-solid);
  --rd-line: var(--rd-line-solid);
  --rd-line-strong: #3b3b45;

  --rd-ink: #f1f1f4;
  --rd-muted: #a4a6af;
  --rd-faint: #8b8e99;

  --rd-blue: var(--accent);
  --rd-blue-strong: var(--accent-fill);
  --rd-blue-soft: #1a2340;
  --nav-active-ink: #b3c1ff;

  --rd-green: var(--success);
  --rd-green-strong: var(--success-solid);
  --rd-green-soft: #12291d;
  --rd-amber: var(--warning);
  --rd-amber-soft: #2b2110;
  --rd-red: var(--danger);
  --rd-red-soft: #2e1615;

  --rd-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 12px 32px -18px rgba(0, 0, 0, 0.55);
  --rd-shadow-hover: 0 2px 4px rgba(0, 0, 0, 0.40), 0 24px 52px -24px rgba(0, 0, 0, 0.65);

  /* ---- 表面渐变（深色版 · 透明渐变）----
     与亮色同一套逻辑：**只动透明度，不掺白**，所以永远不会出现
     发灰的"黑白渐变"。深色下泛光可以稍强（暗底上彩色透明光更自然，
     也不容易显脏）。 */
  --surface-grad: linear-gradient(150deg,
    color-mix(in srgb, var(--rd-surface) 95%, transparent) 0%,
    color-mix(in srgb, var(--rd-surface) 99%, transparent) 50%,
    var(--rd-surface) 100%);
  --surface-glow: radial-gradient(120% 90% at 0% 0%,
    color-mix(in srgb, var(--accent) 10%, transparent) 0%,
    transparent 60%);
  --surface-accent-grad:
    radial-gradient(130% 100% at 0% 0%,
      color-mix(in srgb, var(--accent) 16%, transparent) 0%,
      transparent 65%),
    linear-gradient(150deg,
      color-mix(in srgb, var(--rd-surface) 93%, transparent) 0%,
      var(--rd-surface) 100%);
  --surface-sheen:
    inset 0 1px 0 rgba(255, 255, 255, 0.09),
    inset 1px 0 0 rgba(255, 255, 255, 0.04);

  --focus-ring: 0 0 0 3px color-mix(in srgb, var(--accent) 26%, transparent);

  /* 深色下 --eng-color 不再当白字的实底用，只做描边/浅底；
     文字走 --eng-ink（#9db8fb 在近黑上是 8:1）。 */
  --eng-color: #5b8def;
  --eng-color-dark: #7aa8f8;
  --eng-light: rgba(91, 141, 239, 0.12);
  --eng-light-2: rgba(91, 141, 239, 0.22);
  --eng-ink: #9db8fb;
}

/* ============================================================
   3. 基础排版与渲染
   ============================================================ */

body {
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.62;
  letter-spacing: -0.005em;
  color: var(--rd-ink);
  background: var(--rd-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* redesign 用 body * 重置了字距（为了让各页面显式字距生效）。
   标题需要自己的紧字距才立得住，这里统一收回来。
   body * 与 h1 同为 (0,0,1)，本文件在后，所以直接赢。 */
h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  font-weight: 650;
  line-height: 1.28;
  letter-spacing: -0.022em;
  color: var(--rd-ink);
  text-wrap: balance;
}
h1 { letter-spacing: -0.03em; }
h2 { letter-spacing: -0.026em; }
h3, h4, h5 { letter-spacing: -0.018em; }

p { text-wrap: pretty; }

strong, b { font-weight: 650; }

a {
  color: var(--accent);
  text-underline-offset: 2px;
  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
}
a:hover { color: var(--accent-hover); }

::selection {
  background: color-mix(in srgb, var(--accent) 26%, transparent);
  color: var(--rd-ink);
}

/* 滚动条：从「细黑条」换成能跟主题走的半透明胶囊。
   只影响 WebKit/Blink；Firefox 由 scrollbar-color 兜底。 */
* {
  scrollbar-color: color-mix(in srgb, var(--rd-ink) 22%, transparent) transparent;
  scrollbar-width: thin;
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--rd-ink) 20%, transparent);
  border: 2px solid transparent;
  border-radius: var(--radius-full);
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover {
  background: color-mix(in srgb, var(--rd-ink) 34%, transparent);
  background-clip: padding-box;
}
::-webkit-scrollbar-corner { background: transparent; }

code, kbd, samp {
  font-family: var(--font-mono);
  font-size: 0.88em;
  letter-spacing: 0;
}
code {
  padding: 0.1em 0.36em;
  border: 1px solid var(--border-light);
  border-radius: 5px;
  background: color-mix(in srgb, var(--rd-ink) 5%, transparent);
  color: var(--rd-ink);
}
pre code { border: 0; background: none; padding: 0; }

kbd {
  display: inline-flex;
  align-items: center;
  min-width: 20px;
  height: 19px;
  padding: 0 5px;
  border: 1px solid var(--border);
  border-bottom-width: 2px;
  border-radius: 5px;
  background: var(--rd-surface-2);
  color: var(--rd-muted);
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
}

hr { border: 0; border-top: 1px solid var(--border-light); }

/* 数字统一等宽，避免统计卡/倒计时/计数在重绘时跳动。 */
.home-countdown-main strong,
.emm-stat strong,
.emm-gen-tile strong,
.emm-gen-live-count,
.emm-gen-live-meta,
.emm-gen-progress-label,
.emm-word-count,
.emm-word-stat,
.list-stat__num,
.wrong-stat-num,
.mod-stat-num,
.br-today-main strong,
.br-progress-head strong,
.br-stat strong,
.br-session-position > span,
.emm-progress-ring strong {
  font-variant-numeric: tabular-nums;
}

img { max-width: 100%; }
svg { flex-shrink: 0; }

/* ============================================================
   4. 顶部导航 / 页面骨架
   ============================================================ */

#top-nav {
  height: var(--nav-height);
  background: color-mix(in srgb, var(--rd-bg) 84%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--border) 82%, transparent);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  transition: background var(--transition-base), border-color var(--transition-base),
    box-shadow var(--transition-normal);
}
/* 只加投影、不改底色：底色在壁纸模式下由 wallpaper.css 的玻璃规则接管。 */
#top-nav.scrolled {
  box-shadow: 0 10px 30px -24px rgba(8, 10, 18, 0.55);
}

/* 进度条只改配色（位置/尺寸沿用 main.css）；不再重复声明 #nprogress 本体。 */
.nprogress-bar {
  border-radius: 0 2px 2px 0;
  background: linear-gradient(90deg, var(--eng-color), var(--accent));
  box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 55%, transparent);
}

/* 回到顶部：与导航按钮同一套圆角与幽灵底 */
.back-to-top {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  border-color: var(--border);
  background: var(--rd-surface);
  color: var(--rd-muted);
  box-shadow: var(--shadow-md);
}
.back-to-top:hover {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
  background: var(--rd-surface);
}
.back-to-top svg { width: 18px; height: 18px; }

.nav-inner {
  max-width: var(--max-width);
  padding: 0 28px;
}

.nav-logo {
  gap: 10px;
  font-size: 0.95rem;
  font-weight: 650;
  letter-spacing: -0.02em;
}

.logo-icon {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  /* 深色主题下 --accent 是浅蓝文字色，拿它做渐变底 + 白图标只有约 2:1；
     品牌块必须用实底蓝 --accent-fill，两种主题下都是深色块 + 白图标。 */
  background: linear-gradient(150deg,
    color-mix(in srgb, var(--accent-fill) 92%, #ffffff),
    var(--accent-fill-active));
  color: #fff;
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--accent-fill) 34%, transparent),
    inset 0 1px 0 rgba(255, 255, 255, 0.24);
}
.logo-icon svg { width: 16px; height: 16px; color: #fff; }

.nav-actions { gap: 4px; }

.nav-btn {
  height: 34px;
  padding: 0 10px;
  gap: 7px;
  border: 1px solid transparent;
  border-radius: 9px;
  background: transparent;
  color: var(--text-tertiary);
  font-size: 0.8rem;
  font-weight: 550;
  transition: background var(--transition-fast), color var(--transition-fast),
    transform var(--transition-fast);
}
.nav-btn:hover {
  background: color-mix(in srgb, var(--rd-ink) 7%, transparent);
  border-color: transparent;
  color: var(--rd-ink);
}
.nav-btn:active { transform: scale(0.97); }
.nav-btn.is-active {
  background: var(--rd-blue-soft);
  color: var(--nav-active-ink);
  border-color: color-mix(in srgb, var(--rd-blue) 24%, transparent);
}
.nav-btn svg { width: 18px; height: 18px; }

/* 桌面端把「搜索 / 壁纸」的文字标签放出来，图标 + 文字比纯图标更好认；
   窄屏仍只保留图标，避免导航挤成两行。 */
.nav-btn .btn-label { display: none; }
@media (min-width: 1024px) {
  .nav-btn { padding: 0 12px; }
  .nav-btn .btn-label { display: inline; }
}

#page-container {
  max-width: var(--max-width);
  padding: calc(var(--nav-height) + 30px) 28px 88px;
}
#page-container.ov-fullwidth { padding: 0; max-width: none; }

/* 页头 */
.page-header { margin-bottom: 30px; }
.page-header h1 {
  gap: 10px;
  margin-bottom: 6px;
  font-size: clamp(1.5rem, 1.2rem + 1vw, 1.9rem);
  line-height: 1.2;
}
.page-header p { font-size: 0.93rem; line-height: 1.7; color: var(--rd-muted); }
.page-title-row { margin-bottom: 22px; }

/* 英语/墨墨共用的页头：去掉原来 24px/32px 的内边距，
   让页头与页签、正文**左对齐在同一条线上**（改造前页头比正文宽 32px）。 */
.eng-header {
  max-width: none;
  margin: 0;
  padding: 2px 0 18px;
  gap: 14px;
  align-items: center;
}
.eng-title-block { gap: 6px; }
/* 页头下的整条分隔线去掉：页签已经改成独立的胶囊条，
   两条横线上下叠在一起会像「表格线没对齐」。 */
.eng-header.emm-header { border-bottom: 0; }
.eng-subject-badge {
  gap: 7px;
  padding: 4px 11px;
  margin-bottom: 6px;
  border-radius: var(--radius-full);
  background: var(--rd-blue-soft);
  border: 1px solid color-mix(in srgb, var(--rd-blue) 20%, var(--rd-line));
}
.eng-badge-icon { font-size: 15px; font-weight: 700; color: var(--rd-blue); }
.eng-badge-text { font-size: 0.76rem; font-weight: 650; color: var(--nav-active-ink); }
.eng-page-title {
  font-size: clamp(1.45rem, 1.15rem + 1vw, 1.85rem);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -0.032em;
}
.eng-subtitle { margin-top: 3px; font-size: 0.82rem; line-height: 1.65; color: var(--text-tertiary); }

.mod-page-title { font-size: clamp(1.5rem, 1.2rem + 1vw, 1.9rem); letter-spacing: -0.03em; }
.mod-page-lead, .mod-subtitle { font-size: 0.85rem; line-height: 1.65; }

/* 返回/图标按钮：统一 38px、圆角 11、幽灵底 */
.eng-back-btn, .mod-back-btn, .back-btn {
  width: 38px;
  height: 38px;
  border-radius: 11px;
  border: 1px solid var(--border);
  background: var(--rd-surface);
  color: var(--rd-muted);
  transition: background var(--transition-fast), color var(--transition-fast),
    border-color var(--transition-fast), transform var(--transition-fast);
}
.eng-back-btn:hover, .mod-back-btn:hover, .back-btn:hover {
  background: var(--rd-surface-2);
  color: var(--rd-ink);
  border-color: var(--border-hover);
}
.eng-back-btn:active, .mod-back-btn:active, .back-btn:active { transform: scale(0.96); }
.eng-back-btn svg, .mod-back-btn svg, .back-btn svg { width: 18px; height: 18px; }

/* 页头右侧的小图标按钮（墨墨设置等） */
.emm-icon-btn {
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  border-radius: 11px;
  border: 1px solid var(--border);
  background: var(--rd-surface);
  color: var(--rd-muted);
  transition: background var(--transition-fast), color var(--transition-fast),
    border-color var(--transition-fast), transform var(--transition-fast);
}
.emm-icon-btn:hover {
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, var(--rd-surface));
}
.emm-icon-btn:active { transform: scale(0.96); }

/* ============================================================
   5. 按钮
   ============================================================ */

.btn {
  min-height: 36px;
  padding: 7px 14px;
  gap: 7px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--rd-surface);
  color: var(--rd-ink);
  font-size: 0.84rem;
  font-weight: 550;
  letter-spacing: -0.006em;
  box-shadow: none;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    color var(--transition-fast), box-shadow var(--transition-fast),
    transform var(--transition-fast);
}
.btn:hover {
  background: var(--rd-surface-2);
  border-color: var(--border-hover);
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}
.btn:active {
  background: var(--bg-active);
  box-shadow: none;
  transform: translateY(0);
}
.btn:disabled, .btn[disabled] { opacity: 0.42; box-shadow: none; transform: none; }
.btn svg { width: 17px; height: 17px; }

.btn-primary {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent-fill) 94%, #ffffff) 0%,
    var(--accent-fill) 100%);
  border-color: color-mix(in srgb, var(--accent-fill) 72%, #000000);
  color: #fff;
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--accent-fill) 30%, transparent),
    inset 0 1px 0 rgba(255, 255, 255, 0.16);
}
.btn-primary:hover {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent-fill-hover) 92%, #ffffff) 0%,
    var(--accent-fill-hover) 100%);
  border-color: color-mix(in srgb, var(--accent-fill-hover) 72%, #000000);
  color: #fff;
  box-shadow:
    0 4px 12px -4px color-mix(in srgb, var(--accent-fill) 45%, transparent),
    inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.btn-primary:active { background: var(--accent-fill-active); }

.btn-success {
  background: var(--success-solid);
  border-color: color-mix(in srgb, var(--success-solid) 75%, #000000);
  color: #fff;
}
.btn-success:hover { background: color-mix(in srgb, var(--success-solid) 86%, #000000); color: #fff; }

.btn-danger {
  background: var(--danger-solid);
  border-color: color-mix(in srgb, var(--danger-solid) 75%, #000000);
  color: #fff;
}
.btn-danger:hover { background: color-mix(in srgb, var(--danger-solid) 86%, #000000); color: #fff; }

.btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--rd-muted);
}
.btn-ghost:hover {
  background: color-mix(in srgb, var(--rd-ink) 6%, transparent);
  border-color: transparent;
  color: var(--rd-ink);
}

.btn-sm {
  min-height: 30px;
  padding: 5px 11px;
  border-radius: var(--radius-md);
  font-size: 0.79rem;
  gap: 5px;
}
.btn-sm svg { width: 15px; height: 15px; }
.btn-xs {
  min-height: 26px;
  padding: 3px 9px;
  border-radius: 7px;
  font-size: 0.75rem;
  opacity: 1;
}

/* 旧规则里有一批直接把 --accent 当实底、配白字的控件。
   深色主题下 --accent 是浅蓝文字色，白字会掉到 2:1 —— 统一改回实底蓝。 */
.toast.info .toast-icon,
.wrong-tab.active,
.wrong-filter-btn.active,
.wrong-group-btn.active,
.mp-diff-btn.active,
.ov-action-btn.ov-action-print,
.ov-select-count,
.ov-check.checked,
.quiz-check.checked,
.quiz-check.partial,
.qz-count-pill {
  background: var(--accent-fill);
  border-color: var(--accent-fill);
  color: #fff;
}
/* 这两处的底色被 review.css / redesign.css 用 !important 钉住，
   深色主题下会变成「浅蓝底 + 白字」，只能同样用 !important 拉回实底蓝。 */
.btn-quiz-start {
  background: var(--accent-fill) !important;
  border-color: var(--accent-fill) !important;
  color: #fff !important;
}
/* hover 也必须一起改：页面用 !important 把 hover 改回 --accent-hover（深色是浅蓝），
   白字会掉到约 1.9:1。 */
.btn-quiz-start:not(:disabled):hover {
  background: var(--accent-fill-hover) !important;
  border-color: var(--accent-fill-hover) !important;
}
.ov-action-btn.ov-action-print:hover {
  background: var(--accent-fill-hover);
  border-color: var(--accent-fill-hover);
  color: #fff;
}
.qz-btn--next { background: var(--accent-fill); color: #fff; }
.qz-btn--next:hover { background: var(--accent-fill-hover); }
.toast.success .toast-icon { background: var(--success-solid); }
.toast.warning .toast-icon { background: var(--warning-solid); }
.toast.error .toast-icon { background: var(--danger-solid); }

/* ============================================================
   6. 表面 / 卡片 / 标签 / 表单
   ============================================================ */

/* 6a. 中性卡片底座
   只列「没有自带强调色描边」的卡片：像 .br-card / .sch-card / .dv-problem-card
   这类靠 border-top / border-left 表达状态或科目的组件，一律不在这里统一
   border 简写，否则会把它们的强调色边一起盖掉（那是信息，不是装饰）。
   同理排除 .emm-gen-panel--review-*（三块审查面板各有一条 3px 状态左条）、
   .emm-paper-done（打印完成的蓝框蓝底就是它的全部强调）、.emm-gen-live
   （整块淡蓝底表示「正在跑」）—— 它们只单独设圆角，不参与中性底座。

   ⚠ v8：底座改用**统一表面渐变**（--surface-grad）而不是纯色，
   这是把首页 hero / 侧栏面板的玻璃质感铺到全站的地方。渐变 + 内高光
   （--surface-sheen）一起才是「玻璃有厚度」；只加渐变不加高光，
   顶边会显得发灰。 */
:is(
  .subject-card, .mod-card, .mod-stat, .item-card, .bk-card, .ch-card,
  .review-card, .home-hero-panel, .list-stat, .wrong-stat-card, .list-group,
  .mn-note-card, .ov-container, .quiz-scope-list,
  .mp-stage, .mp-template-card, .emm-panel, .emm-card, .emm-hero, .emm-entry,
  .emm-word-card, .emm-gen-rail,
  .emm-paper-form, .emm-dialog, .emm-window,
  .modal-dialog, .settings-dialog, .br-panel, .br-feedback,
  .br-checkin-hero
) {
  border-color: var(--border);
  border-radius: var(--radius-xl);
  background: var(--surface-grad);
  box-shadow: var(--shadow-sm), var(--surface-sheen);
}

/* 大面积「品牌面」：hero、倒计时面板、概览 hero —— 在表面渐变上再掺主色，
   做顶部泛光。只给真正的大面板，卡片上不加（6% 主色在 377px 卡片上
   会看出色偏，在 1160px 面板上才是"氛围"）。 */
:is(.home-hero, .home-hero-panel, .emm-hero, .emm-gen-panel, .emm-gen-rail,
  .br-card, .br-checkin-hero, .mn-page-header) {
  background: var(--surface-accent-grad);
}

/* 卡片内更高一层的「inset 井」（表单区、列表容器、代码块式的信息块）：
   比卡片底色再低/高一档，靠明度而不是边框分层。 */
.emm-hero-progress,
.emm-gen-tile,
.emm-gen-mode,
.emm-gen-words,
.emm-gen-task,
.emm-gen-batch,
.emm-gen-presets,
.emm-gen-grammar,
.emm-gen-scope,
.emm-gen-daypick,
.emm-gen-issues > li,
.emm-gen-live-item,
.emm-detail-facts > div,
.emm-phrase-list li,
.emm-history-list li,
.emm-kind-list li,
.emm-scope-list li,
.emm-analysis,
.emm-reference,
.emm-segments li,
.emm-question-explain,
.emm-option,
.emm-question-prompt span {
  border-radius: var(--radius-lg);
}

/* 6b. 卡片悬停：只做 2px 抬升 + 柔光，不做位移动画（列表里会晕）。 */
.subject-card,
.mod-card,
.item-card,
.bk-card,
.ch-card,
.mn-note-card,
.emm-word-card,
.eng-action-card,
.emm-entry,
.emm-gen-mode,
.emm-gen-task,
.emm-gen-batch,
.mp-template-card {
  transition: transform var(--transition-normal), border-color var(--transition-normal),
    box-shadow var(--transition-normal), background var(--transition-normal);
}

/* 6c. 标签 / 徽标：统一成「浅底 + 细边 + 小圆角」的一套。
   改造前同一个页面能同时出现 4px 圆角、胶囊、无边框纯色块三种标签。 */
.filter-chip,
.sch-chip,
.emm-chip,
.emm-filter,
.emm-gen-chip,
.emm-gen-badge,
.emm-word-stat,
.emm-word-count,
.br-tag,
.sch-group-badge {
  border-radius: var(--radius-full);
  font-weight: 600;
  letter-spacing: 0;
}

.filter-chip {
  padding: 6px 13px;
  font-size: 0.78rem;
  border-color: var(--border);
  color: var(--rd-muted);
  background: transparent;
}
.filter-chip:hover { background: var(--rd-surface-2); color: var(--rd-ink); border-color: var(--border-hover); }
.filter-chip.active {
  background: var(--accent-fill);
  border-color: var(--accent-fill);
  color: #fff;
  box-shadow: 0 2px 8px -3px color-mix(in srgb, var(--accent-fill) 55%, transparent);
}

.emm-chip {
  padding: 2px 9px;
  font-size: 11px;
  background: color-mix(in srgb, var(--rd-ink) 4%, transparent);
  border: 1px solid var(--border);
  color: var(--rd-muted);
}
.emm-chip.is-sticking { border-color: color-mix(in srgb, var(--danger) 42%, var(--border)); color: var(--danger-ink); }
.emm-chip.is-familiar { border-color: color-mix(in srgb, var(--success) 42%, var(--border)); color: var(--success-ink); }
.emm-chip.is-today {
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
  color: var(--eng-ink);
  background: color-mix(in srgb, var(--accent) 9%, transparent);
}
.emm-chip.is-wrong { border-color: color-mix(in srgb, var(--warning) 42%, var(--border)); color: var(--warning-ink); }

.emm-word-stat {
  padding: 2px 8px;
  font-size: 11px;
  background: color-mix(in srgb, var(--rd-ink) 5%, transparent);
  /* 11px 小字：在「5% 底色」上 tertiary 只有约 4.5:1，处在边界上；
     改用 secondary 留出余量，观感上仍是弱化信息。 */
  color: var(--text-secondary);
}
.emm-word-stat.is-wrong { background: color-mix(in srgb, var(--danger) 12%, transparent); color: var(--danger-ink); }
.emm-word-stat.is-due { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--eng-ink); }

.emm-word-count { padding: 2px 8px; border-radius: var(--radius-full); }
.emm-word-count.is-unknown { border-color: var(--border); color: var(--text-secondary); }
.emm-word-count.is-zero { background: color-mix(in srgb, var(--rd-ink) 5%, transparent); color: var(--text-secondary); }
.emm-word-count.is-many {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-color: color-mix(in srgb, var(--accent) 32%, transparent);
  color: var(--eng-ink);
}

/* 淡底徽章的文字一律用 -ink 变体：亮色主题下 --success/--warning/--danger
   压在 12%~18% 的彩色淡底上只有 4.07~4.49:1（10.5~11px 小字不达 AA）。 */
.emm-gen-badge.is-ok { background: color-mix(in srgb, var(--success) 14%, transparent); color: var(--success-ink); }
.emm-gen-badge.is-warn { background: color-mix(in srgb, var(--warning) 16%, transparent); color: var(--warning-ink); }
.emm-gen-badge.is-bad { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger-ink); }
.emm-gen-badge.is-live { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--eng-ink); }

.emm-gen-tile.is-ok strong { color: var(--success-ink); }
.emm-gen-tile.is-warn strong { color: var(--warning-ink); }
.emm-gen-tile.is-bad strong { color: var(--danger-ink); }
.emm-stat.is-warn strong { color: var(--warning-ink); }
.emm-stat.is-danger strong { color: var(--danger-ink); }

.emm-gen-words li.is-ready { border-left-color: color-mix(in srgb, var(--success) 70%, transparent); }
.emm-gen-words li.is-failed { border-left-color: color-mix(in srgb, var(--danger) 75%, transparent); }
.emm-gen-words li.is-selected { border-left-color: color-mix(in srgb, var(--warning) 75%, transparent); }
.emm-gen-words li.is-pick { border-left-color: var(--accent); }

.emm-error-text { color: var(--danger-ink); }
.emm-notice { border-left-color: var(--warning); }
.emm-gen-hint b.is-error { color: var(--danger-ink); }
.emm-gen-hint b.is-warning { color: var(--warning-ink); }
.emm-gen-hint.is-ok { color: var(--success-ink); }
.emm-gen-live-trailing { color: var(--warning-ink); }
.emm-gen-live-item.is-ok { border-left-color: color-mix(in srgb, var(--success) 55%, transparent); }
.emm-gen-live-item.is-warn { border-left-color: color-mix(in srgb, var(--warning) 60%, transparent); }
.emm-gen-live-item.is-bad { border-left-color: color-mix(in srgb, var(--danger) 60%, transparent); }
.emm-gen-live-item.is-warn .emm-gen-live-verdict { color: var(--warning-ink); }
.emm-gen-live-item.is-bad .emm-gen-live-verdict { color: var(--danger-ink); }
.emm-gen-batch.is-live { border-color: color-mix(in srgb, var(--accent) 55%, var(--border)); }
/* 以下两处原来把 --rd-blue-strong（实底蓝）当**文字色**用。
   在深色主题里 #3e63dd 压在深蓝底上只有 3.9:1，小字不达 AA；
   统一换成深色主题下更亮的文字 ink。 */
.emm-gen-mode.is-done .emm-gen-mode-stat { color: var(--success-ink); }
.emm-gen-preset-on,
.emm-gen-batch-now { color: var(--eng-ink); }

.emm-result { border-left-color: var(--success); background: color-mix(in srgb, var(--success) 8%, transparent); }
.emm-result strong { color: var(--success-ink); }
.emm-result.is-wrong { border-left-color: var(--danger); background: color-mix(in srgb, var(--danger) 8%, transparent); }
.emm-result.is-wrong strong { color: var(--danger-ink); }
.emm-history-list li.is-correct strong { color: var(--success-ink); }
.emm-history-list li.is-wrong strong { color: var(--danger-ink); }
.emm-option.is-correct { border-color: color-mix(in srgb, var(--success) 55%, var(--border)); background: color-mix(in srgb, var(--success) 10%, var(--rd-surface)); }
.emm-option.is-wrong { border-color: color-mix(in srgb, var(--danger) 55%, var(--border)); background: color-mix(in srgb, var(--danger) 9%, var(--rd-surface)); }

/* 6d. 表单控件 */
.form-group label { margin-bottom: 7px; font-size: 0.84rem; font-weight: 600; }
.form-group input, .form-group textarea, .form-group select,
input[type="text"], input[type="number"],
input[type="email"], input[type="password"], input[type="date"], textarea, select {
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--rd-surface);
  color: var(--rd-ink);
  font-size: 0.9rem;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast),
    background var(--transition-fast);
}
.form-group input:focus, .form-group textarea:focus, .form-group select:focus,
input:focus, textarea:focus, select:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: var(--focus-ring);
}
/* ⚠ 没有 `input[type="search"]`：全仓 12 个搜索输入框都住在自带容器样式的
   `.qb-search` / `.cf-search` / `.bm-search` / `.ceb-search` 等外壳里，
   通用规则会把它们的图标避让内边距和「无边框」重置掉（文字压到放大镜下、
   框里再套一个框）。搜索框只由各自的外壳规则负责。
   占位符也不给自己加 opacity：--text-tertiary 本身已过 AA，再乘 0.8 会掉到
   浅色 3.4 / 深色 4.1。 */
input::placeholder, textarea::placeholder { color: var(--text-tertiary); }

/* 搜索框类容器（input 自己撑起整个圆角框） */
.emm-search, .mn-search, .sch-bar, .list-search, .br-search,
.cm-search, .bm-search, .cf-search {
  border-color: var(--border);
  border-radius: var(--radius-lg);
  background: var(--rd-surface);
}
.emm-search:focus-within, .mn-search:focus-within, .sch-bar:focus-within,
.br-search:focus-within {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
}
.emm-search input, .mn-search input, .sch-bar__input {
  background: transparent;
  border: 0;
  box-shadow: none;
}
.emm-search input:focus, .mn-search input:focus { box-shadow: none; }
/* 已掌握列表的搜索框是「外层无边框、内层 input 自己成框」的结构，
   通用 input 规则会把它的 36px 图标避让与边框一起改掉，这里按原样恢复。 */
.list-search input {
  height: 38px;
  padding: 0 14px 0 36px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--rd-surface);
  font-size: 0.88rem;
}
.list-search input:focus { border-color: var(--accent); box-shadow: var(--focus-ring); }

/* 搜索页的外层 .sch-bar 才是「框」：内层 input 必须无边框、无底色，
   否则通用 input 规则会把它画成框里再套一个框。
   ⚠ 这里用 .sch-bar .sch-bar__input（0,2,0）压过 input[type="text"]（0,1,1）。
   ⚠⚠ 还必须把内层的 **outline** 一起清掉：redesign.css 给
     `input:focus-visible` 画了 2px 实色环，`.sch-bar__input` 也在名单里，
     于是聚焦时出现「容器 1px 边 + 输入框 2px 蓝环」的双层框（截图里很刺眼）。
     焦点反馈统一交给外层 `.sch-bar:focus-within` 的光晕。 */
.sch-bar {
  height: 48px;
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--rd-surface);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.sch-bar .sch-bar__input,
.br-search input {
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  outline: none;
}
.sch-bar .sch-bar__input { padding: 0 44px; font-size: 0.95rem; }
.sch-bar .sch-bar__input:focus,
.sch-bar .sch-bar__input:focus-visible,
.br-search input:focus { border: 0; box-shadow: none; outline: none; }
.sch-bar:focus-within {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
}

.emm-select, #mn-sort-select {
  height: 38px;
  padding: 0 11px;
  border-radius: var(--radius-lg);
  border-color: var(--border);
  background: var(--rd-surface);
  font-size: 0.84rem;
}

/* 6e. 页签：从「下划线 tab」改成「玻璃胶囊条」。
   同一条 DOM（nav.emm-tabs > button.emm-tab），只换外观。
   ⚠ 有壁纸时底色与圆角由 wallpaper.css 的玻璃规则接管，这里只负责
     内边距与选中态；不要在这里写死背景色。 */
.emm-tabs {
  display: flex;
  gap: 4px;
  width: 100%;
  margin: 12px 0 0;
  padding: 5px;
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--rd-surface);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.emm-tabs::-webkit-scrollbar { display: none; }
.emm-tab {
  flex: 0 0 auto;
  padding: 8px 14px;
  border: 0;
  border-bottom: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--text-tertiary);
  font-size: 13.5px;
  font-weight: 550;
  letter-spacing: -0.006em;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.emm-tab:hover {
  color: var(--rd-ink);
  background: color-mix(in srgb, var(--rd-ink) 6%, transparent);
}
.emm-tab.is-active {
  color: var(--nav-active-ink);
  background: var(--rd-blue-soft);
  border-bottom-color: transparent;
}
.emm-tab.is-active:hover { color: var(--nav-active-ink); }
/* 阅读进度条原来写死 top:56px，导航改 60px 后会被压进导航底下。 */
.eng-reading-progress { top: var(--nav-height); }

/* 页签下方的正文容器与页头左对齐（改造前它比页头窄 32px）。 */
.emm-body { width: 100%; margin: 24px 0 0; }
.emm-page { min-height: calc(100dvh - var(--nav-height)); padding-bottom: 64px; }

/* 6f. 弹层 / 弹窗 / 通知 */
.overlay,
.emm-dialog-overlay,
.emm-window-overlay {
  background: color-mix(in srgb, #05060a 58%, transparent);
  backdrop-filter: blur(8px) saturate(120%);
  -webkit-backdrop-filter: blur(8px) saturate(120%);
}
[data-theme="light"] .overlay,
[data-theme="light"] .emm-dialog-overlay,
[data-theme="light"] .emm-window-overlay {
  background: color-mix(in srgb, #12151f 34%, transparent);
}
/* 深色遮罩要压过 main.css 的 [data-theme="dark"] .overlay（0,2,0），
   否则这里的基础声明只是一句永远不生效的注释。 */
[data-theme="dark"] :is(.overlay, .emm-dialog-overlay, .emm-window-overlay) {
  background: color-mix(in srgb, #05060a 64%, transparent);
}

.modal-dialog, .settings-dialog {
  border-radius: var(--radius-2xl);
  border-color: var(--border);
  background: var(--rd-surface);
  box-shadow: var(--shadow-xl);
}
.modal-header, .settings-header { padding: 18px 22px; border-bottom-color: var(--border); }
.modal-body, .settings-body { padding: 22px; }
.modal-header h3, .settings-header h3 { font-size: 1rem; font-weight: 650; letter-spacing: -0.02em; }
.modal-close, .settings-close {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: var(--rd-surface-2);
  color: var(--text-tertiary);
}
.modal-close:hover, .settings-close:hover { background: var(--bg-active); color: var(--rd-ink); }

.emm-dialog {
  width: min(560px, 100%);
  padding: 26px;
  border-radius: var(--radius-2xl);
  border-color: var(--border);
  background: var(--rd-surface);
  box-shadow: var(--shadow-xl);
}
.emm-dialog h2 { font-size: 1.18rem; letter-spacing: -0.024em; }
.emm-dialog textarea { border-radius: var(--radius-lg); background: var(--rd-surface-2); }
.emm-dialog-actions { gap: 8px; margin-top: 20px; }

.emm-window {
  border-radius: var(--radius-2xl);
  border-color: var(--border);
  box-shadow: var(--shadow-xl);
}
.emm-window-head { padding: 18px 22px 14px; border-bottom-color: var(--border); }
.emm-window-title h2 { font-size: 1.02rem; letter-spacing: -0.02em; }
.emm-window-body { padding: 18px 22px 24px; }
.emm-window-size {
  padding: 3px 9px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--rd-ink) 5%, transparent);
  border-color: var(--border);
  color: var(--text-tertiary);
}

#toast-container { right: 26px; bottom: 26px; gap: 10px; }
.toast {
  padding: 11px 16px;
  border-radius: var(--radius-xl);
  border-color: var(--border);
  background: var(--rd-surface);
  box-shadow: var(--shadow-lg);
  font-size: 0.84rem;
  font-weight: 500;
  letter-spacing: -0.006em;
}

/* 6g. 空状态 / 骨架屏 */
.empty-state {
  padding: 46px 24px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-xl);
  /* ⚠ 必须用不透明 token：壁纸模式下 --rd-surface-2 本身已是 94% 玻璃，
     再乘一个百分比会把空态压到 64% 不透明（深色 + 纯白壁纸下 tertiary
     只有 1.63:1）。空态是承载文字的表面，不参与「更透」的设置。 */
  background: var(--rd-surface-2);
  color: var(--text-tertiary);
}
/* ⚠⚠ 空状态经常被塞进多列网格里当唯一子项（数学练习的 .mp-template-grid
   是 4 列、工作台 .mod-grid 是 3 列）。不跨列的话它只占一格，宽 205px、
   高 247px —— 一个又窄又高的白条，里面的图标和文案挤成一列，非常难看。
   凡是「网格里只有它一个」的情况都应该铺满整行。 */
:is(.mp-template-grid, .mod-grid, .subject-card-grid, .emm-word-grid,
  .mn-grid, .mp-scope-grid, .emm-grid-2) > .empty-state:only-child {
  grid-column: 1 / -1;
  width: 100%;
}
.empty-icon-wrap { width: 96px; height: 78px; margin-bottom: 16px; animation: none; opacity: 0.55; }
.empty-state .empty-icon { font-size: 2.6rem; margin-bottom: 14px; animation: none; opacity: 0.7; }
.empty-state h3 { font-size: 1.05rem; font-weight: 650; color: var(--rd-muted); }
.empty-state p { font-size: 0.88rem; line-height: 1.7; }

.skeleton, .skeleton-shimmer {
  border-radius: var(--radius-md);
  background: linear-gradient(90deg,
    var(--rd-surface-2) 20%,
    color-mix(in srgb, var(--rd-line) 55%, var(--rd-surface-2)) 50%,
    var(--rd-surface-2) 80%);
  background-size: 200% 100%;
}
.skeleton-card { border-radius: var(--radius-xl); border-color: var(--border); background: var(--rd-surface); }

/* 6h. 表格（全局只有少量真表格，改成无竖线的轻量样式） */
table { border-collapse: separate; border-spacing: 0; }
th, td {
  padding: 10px 14px;
  border: 0;
  border-bottom: 1px solid var(--border-light);
  font-size: 0.86rem;
}
th {
  background: transparent;
  color: var(--text-tertiary);
  font-size: 0.76rem;
  font-weight: 650;
  letter-spacing: 0.02em;
}
tr:nth-child(even) { background: transparent; }
tbody tr:hover { background: color-mix(in srgb, var(--rd-ink) 3%, transparent); }

/* ============================================================
   7. 首页
   ============================================================ */

/* 旧版 home.css 把首页设成「flex 居中 + 文字居中 + 额外 24/32px 内边距」，
   导致内容左缘比导航多缩进 24px；这里把横向内边距清零、改左对齐并铺满。 */
.home-page {
  max-width: 1160px;
  padding: 0 0 40px;
  align-items: stretch;
  text-align: left;
}
/* 旧版 home.css 把首页设成了「flex 居中 + 文字居中」；
   redesign 只把 hero 文案改成左对齐，分区标题与科目网格仍然被居中/压窄
   （.home-cards-section 的 max-width:720 会让 3 列卡片挤在中间）。
   这里统一成整页左对齐、满宽。 */
.home-cards-section { width: 100%; max-width: none; }
.home-section-head { text-align: left; }

.home-hero {
  grid-template-columns: minmax(0, 1.4fr) minmax(280px, 0.6fr);
  gap: 44px;
  /* ⚠ 原来是 start：hero 文案区比右侧倒计时面板矮，壁纸背衬按 hero 盒子
     铺出来时，面板会从背衬右侧"戳出去"一截，两块底色对不齐。
     改成 stretch，让面板与文案区等高，背衬/玻璃才是一整块。 */
  align-items: stretch;
  margin-bottom: 56px;
  /* ⚠ 壁纸模式下这里会有一层 94% 的近实色背衬（wallpaper.css 的裸文字兜底）。
     与其让"背衬矩形 + 面板卡片"叠成两块对不齐的深色，不如把 hero 本身
     做成一块真正的玻璃卡：背衬与面板在同一表面里，边界自然消失。 */
  padding: 26px 28px;
  border-radius: var(--radius-2xl);
}
/* ⚠ v12：壁纸下 hero 不再画 1px 边框和投影 ——
   那条硬边框正是用户截图里"边缘生硬"的来源之一（hero 四边一圈清晰直线）。
   现在 hero 的边界由 refine.css 末尾的 ::after 柔化光晕承担，
   这里必须显式清掉，否则 (0,2,1) 的旧规则会盖过末尾的 :is(...)（(0,1,1)）。 */
html.has-wallpaper .home-hero {
  border-color: transparent;
  box-shadow: none;
}
.home-hero-copy { padding: 16px 0 0; }
.home-kicker {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.14em !important;
  color: var(--accent);
}
.home-hero h1 {
  max-width: 720px;
  font-size: clamp(2.4rem, 4.6vw, 3.5rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.045em;
}
.home-hero h1 em { color: var(--accent); }
.home-hero-copy > p {
  max-width: 560px;
  margin: 18px 0 26px;
  font-size: 1rem;
  line-height: 1.8;
  color: var(--rd-muted);
}
.home-hero-actions { gap: 12px; }
.home-hero-actions .btn { min-height: 42px; padding: 0 20px; border-radius: 12px; font-size: 0.9rem; }
.home-hero-note { font-size: 0.78rem; color: var(--text-tertiary); }

.home-hero-panel {
  align-self: stretch;
  padding: 24px;
  border-radius: var(--radius-2xl);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent) 5%, var(--rd-surface)) 0%,
    var(--rd-surface) 55%);
}
.home-countdown-panel { border-top: 2px solid var(--accent); }
.home-panel-label {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.12em !important;
  color: var(--text-tertiary);
}
.home-date-value { font-size: 1rem; font-weight: 650; letter-spacing: -0.01em; }
.home-date-tag {
  padding: 3px 7px;
  border-radius: 6px;
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
  color: var(--accent);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em !important;
}
.home-countdown-block { padding: 20px 0 16px; }
.home-countdown-main strong {
  font-size: clamp(3.4rem, 6.4vw, 4.6rem);
  font-weight: 750;
  line-height: 0.9;
  letter-spacing: -0.05em !important;
  color: var(--accent);
}
.home-countdown-main span { font-size: 1rem; font-weight: 650; color: var(--accent); }
.home-countdown-kicker { font-size: 0.74rem; }
.home-countdown-target { font-size: 0.7rem; color: var(--text-tertiary); }
.home-panel-quote { padding-top: 16px; border-top-color: var(--border-light); }
.home-panel-quote p { font-size: 0.8rem; line-height: 1.7; color: var(--rd-muted); }
.home-quote-mark { color: var(--warning); }

.home-section-head { margin-bottom: 20px; }
.home-section-head h2 { font-size: 1.3rem; letter-spacing: -0.028em; }
.home-section-count { font-size: 0.8rem; color: var(--text-tertiary); }

.subject-card-grid { gap: 14px; }
.subject-card { min-height: 160px; border-radius: 16px; background: var(--rd-surface); }
.subject-card:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--card-color, var(--accent)) 42%, var(--border));
  box-shadow: var(--shadow-lg);
}
.card-content {
  grid-template-columns: 52px minmax(0, 1fr) 22px;
  gap: 16px;
  min-height: 160px;
  padding: 26px;
}
.card-icon-wrapper {
  width: 52px;
  height: 52px;
  border-radius: 14px;
  background: color-mix(in srgb, var(--card-color, var(--accent)) 12%, var(--rd-surface));
  border-color: color-mix(in srgb, var(--card-color, var(--accent)) 24%, transparent);
}
.card-icon-text { font-size: 1.4rem; }
.card-title { font-size: 1.08rem; font-weight: 650; letter-spacing: -0.02em; }
.card-arrow { color: var(--text-tertiary); }

/* ============================================================
   8. 科目工作台
   ============================================================ */

.modules-page { max-width: 1160px; }
.mod-header { margin-bottom: 24px; }
.mod-subject-badge {
  padding: 4px 11px;
  border-radius: var(--radius-full);
  background: var(--rd-blue-soft);
  border-color: color-mix(in srgb, var(--accent) 20%, var(--border));
}
.mod-badge-text { font-size: 0.78rem; font-weight: 650; color: var(--nav-active-ink); }
.mod-stats-row { gap: 12px; margin-bottom: 36px; }
.mod-stat { min-height: 80px; padding: 16px 18px; }
/* ⚠⚠ auto-fit 在「只有 1 条统计」时会把它拉成整行 1160px（数学工作台
   只有「笔记数」一项）—— 数字孤零零贴在左边、右边全空，像没加载完。
   用 flex 让卡片按内容宽度排，只有一条时就是一张正常大小的卡。
   ⚠ 不能用 max-width 百分比：网格轨道已经算成 1160px，子项 max-width
   只是把背景裁窄，卡片仍然占满整行位置，观感没变。 */
.mod-stats-row {
  display: flex;
  flex-wrap: wrap;
}
.mod-stats-row > .mod-stat {
  flex: 0 1 auto;
  min-width: 200px;
}
.mod-stats-row > .mod-stat:only-child { min-width: 240px; }
/* 模块网格：少于 3 个模块时别把空位留在右边。 */
.mod-grid { gap: 12px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.mod-grid:has(> :nth-child(2):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.mod-grid:has(> :first-child:last-child) { grid-template-columns: minmax(0, 1fr); max-width: 520px; }
.mod-stat-icon {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--rd-ink) 4%, var(--rd-surface)) !important;
}
.mod-stat-num { font-size: 1.35rem; font-weight: 650; letter-spacing: -0.02em; }
.mod-stat-lbl { font-size: 0.7rem; }
.mod-grid { gap: 12px; }
.mod-card-inner { min-height: 112px; padding: 20px; gap: 14px; }
.mod-card-icon-wrap { width: 42px; height: 42px; border-radius: 11px; }
.mod-card-info h3 { font-size: 0.98rem; letter-spacing: -0.018em; }
.mod-card-info p { font-size: 0.78rem; line-height: 1.6; }
.mod-section-head h2 { font-size: 1.15rem; letter-spacing: -0.026em; }
.mod-section-head > span { font-size: 0.78rem; }

/* ============================================================
   9. 英语概览
   ============================================================ */

.eng-action-row { gap: 12px; margin-bottom: 34px; }
.eng-action-card { min-height: 132px; padding: 20px; gap: 15px; border-radius: 16px; }
.eng-action-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.eng-action-icon { width: 44px; height: 44px; border-radius: 12px; }
.eng-action-info h3 { font-size: 0.98rem; letter-spacing: -0.018em; }
.eng-action-info p { font-size: 0.8rem; line-height: 1.6; }
.eng-more-tool { border-radius: 12px; }
.eng-segmented { border-radius: var(--radius-lg); }

/* ============================================================
   10. 墨墨子系统（概览 / 词库 / 语境填空 / 生成台 / 长难句 / 打印）
   ============================================================ */

.emm-header-actions { gap: 8px; }
.emm-kicker { font-size: 11px; letter-spacing: 0.14em; color: var(--text-tertiary); }
.emm-muted { font-size: 13px; }
.emm-section-head h2 { font-size: 1.15rem; letter-spacing: -0.026em; }
.emm-grid-2 { gap: 16px; }
.emm-panel { padding: 22px; }
.emm-panel > header h3 { font-size: 0.94rem; letter-spacing: -0.016em; }
.emm-panel > header span { font-size: 11px; }

/* 概览 hero */
.emm-hero {
  grid-template-columns: minmax(0, 1.35fr) 248px;
  gap: 30px;
  padding: 30px;
  border-radius: 18px;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent) 4%, var(--rd-surface)) 0%,
    var(--rd-surface) 60%);
}
.emm-hero-main h2 {
  margin: 10px 0 12px;
  font-size: clamp(1.45rem, 1.1rem + 1.2vw, 1.7rem);
  line-height: 1.3;
  letter-spacing: -0.03em;
}
.emm-hero-main > p { font-size: 0.86rem; line-height: 1.75; }
.emm-hero-actions { margin: 22px 0 14px; gap: 10px; }
.emm-hero-actions .btn { border-radius: 11px; }
.emm-sync-note { font-size: 12px; }

.emm-hero-progress {
  padding: 22px 18px;
  border-radius: 16px;
  border-color: var(--border-light);
  background: color-mix(in srgb, var(--rd-ink) 3%, var(--rd-surface));
}
.emm-progress-ring { width: 132px; height: 132px; }
.emm-progress-ring strong { font-size: 32px; font-weight: 650; letter-spacing: -0.03em; }
.emm-progress-label { font-size: 13px; }
.emm-progress-time { font-size: 11px; }

.emm-stats { border-radius: 14px; margin-top: 16px; border-color: var(--border); }
.emm-stat { min-height: 88px; }
.emm-stat strong { font-size: 1.4rem; font-weight: 650; letter-spacing: -0.02em; }
.emm-stat span { font-size: 11px; }

.emm-entries { margin-top: 32px; }
.emm-entry-grid { gap: 12px; }
.emm-entry { padding: 20px; gap: 15px; }
.emm-entry-icon { width: 44px; height: 44px; border-radius: 12px; }
.emm-entry-body strong { font-size: 0.96rem; letter-spacing: -0.016em; }
.emm-entry-body small { font-size: 12px; line-height: 1.65; }
.emm-empty { border-radius: 16px; }

/* 词库工具栏 + 卡片网格 */
.emm-toolbar { gap: 12px; margin-bottom: 20px; }
.emm-select { border-radius: var(--radius-lg); }
.emm-filter { padding: 7px 14px; font-size: 12.5px; font-weight: 550; }
.emm-filter.is-active { background: var(--accent-fill); border-color: var(--accent-fill); color: #fff; }
.emm-count { font-size: 12px; }

.emm-word-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; }
.emm-word-card {
  gap: 8px;
  padding: 14px 15px;
  border-radius: 14px;
  background: var(--rd-surface);
  box-shadow: var(--shadow-xs);
  /* ⚠ 卡片高度必须统一：释义长短差一行、脚注徽章换行都会让卡片高低不齐，
     网格里就会看到参差的"台阶"。高度取「标题 + 两行释义 + 一行徽章」的
     自然高度，不要多留 —— 实测 132px 会在释义只有一行时留出大片空白。 */
  min-height: 118px;
}
.emm-word-card:hover {
  background: var(--rd-surface);
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
.emm-word-card.is-selected {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 6%, var(--rd-surface));
}
.emm-word-card-head strong { font-family: var(--font-reading); font-size: 16.5px; letter-spacing: -0.01em; }
/* ⚠ 释义严格夹两行：`-webkit-line-clamp` 要求 display 是 -webkit-box，
   这里显式重写（父级 flex 会继承出别的 display，clamp 就静默失效，
   实测出现三行释义把卡片撑高、和相邻卡片对不齐）。 */
.emm-word-card-meaning {
  font-size: 12.5px;
  line-height: 1.55;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.emm-word-card-foot { gap: 6px; margin-top: auto; }
.emm-grid-hint { font-size: 12px; }
.emm-list-end { font-size: 12px; }

.emm-word-list, .emm-wrong-list { border-color: var(--border-light); border-radius: 14px; background: var(--border-light); gap: 1px; }
.emm-word-row { padding: 15px 18px; background: var(--rd-surface); }
.emm-word-row:hover { background: var(--rd-surface-2); }
.emm-word-row.is-selected {
  background: color-mix(in srgb, var(--accent) 6%, var(--rd-surface));
  box-shadow: inset 3px 0 0 var(--accent);
}
.emm-word-head strong { font-family: var(--font-reading); font-size: 16.5px; }
.emm-word-meaning { font-size: 13px; }
.emm-word-meta { font-size: 11.5px; }

/* 单词详情弹窗不在页面里覆写尺寸：窗口尺寸由 listWindow 的 data-size 控制
   （写死 min(700px) 会把「记忆尺寸」变成死参数）。 */
.emm-detail-facts > div { border-radius: 11px; background: var(--rd-surface-2); }
.emm-detail-section { border-top-color: var(--border-light); }
.emm-phrase-list li { border-radius: 0 11px 11px 0; }
.emm-history-list li { border-radius: 10px; }

/* 语境填空 */
.emm-card { min-height: 440px; padding: 30px; border-radius: 18px; }
.emm-card-word { font: 700 34px/1.2 var(--font-reading); letter-spacing: -0.01em; }
.emm-prompt { font-size: 19px; line-height: 1.85; }
.emm-answer-input {
  padding: 14px 16px;
  border-radius: 12px;
  border-color: var(--border);
  background: var(--rd-surface-2);
  font-size: 15px;
}
.emm-answer-input:focus { border-color: var(--accent); box-shadow: var(--focus-ring); }
.emm-card-actions { padding-top: 24px; gap: 10px; }
.emm-result { border-radius: 0 12px 12px 0; }
.emm-reference, .emm-analysis { border-radius: 12px; }
.emm-progress-bar { height: 6px; background: color-mix(in srgb, var(--rd-ink) 8%, transparent); }
.emm-progress-bar span { background: var(--accent-fill); }
.emm-sentence {
  padding: 22px 24px;
  border: 1px solid var(--border-light);
  border-radius: 14px;
  background: var(--rd-surface-2);
  font: 400 19.5px/1.85 var(--font-reading);
}
.emm-step h3 { font-size: 0.95rem; letter-spacing: -0.018em; }
.emm-option { padding: 12px 14px; border-radius: 10px; background: var(--rd-surface-2); }
.emm-question-explain { border-radius: 10px; background: var(--rd-surface-2); }
.emm-segments li { border-radius: 10px; background: var(--rd-surface-2); }
.emm-question-prompt span { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); }
.emm-empty { border-color: var(--border); }

/* 生成台 */
.emm-gen-layout { grid-template-columns: minmax(0, 1fr) 320px; gap: 18px; }
.emm-gen-rail {
  position: sticky;
  top: calc(var(--nav-height) + 14px);
  padding: 16px;
  border-radius: 16px;
}
.emm-gen-rail-head h2 { font-size: 0.92rem; }
.emm-gen-modes { gap: 12px; }
.emm-gen-mode {
  padding: 16px 17px;
  gap: 13px;
  border-radius: 12px;
  border-color: var(--border);
  background: var(--rd-surface-2);
}
.emm-gen-mode:hover { border-color: color-mix(in srgb, var(--accent) 40%, var(--border)); }
.emm-gen-mode.is-active {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, var(--rd-surface));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 28%, transparent);
}
.emm-gen-mode-icon { width: 36px; height: 36px; border-radius: 10px; }
.emm-gen-mode-text strong { font-size: 0.92rem; letter-spacing: -0.016em; }
.emm-gen-mode-text span { font-size: 12px; line-height: 1.6; }
/* ⚠⚠ 生成台的「刷新」按钮单独放在 .emm-gen-layout **之外**的一个全宽
   toolbar 里，而 toolbar 是 justify-content: flex-end —— 于是按钮被推到
   1164px 容器的最右端，比右侧栏（320px）还靠右，看着像脱离页面飘在角落。
   改成左对齐，让它贴住主栏左缘。 */
.emm-gen-toolbar {
  justify-content: flex-start;
  margin: 0 0 12px;
}
/* ⚠ 四个模式卡片：主栏 826px 按 260px 最小宽只能放 3 列，第 4 块单独
   掉到第二行只占 1/3，说明文字被挤成 5 行、右下方留一块空。
   让它跨满两列 —— 既保持 3 列节奏，又不留孤立卡片。 */
.emm-gen-modes { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.emm-gen-modes > .emm-gen-mode:nth-child(4) { grid-column: span 2; }
.emm-gen-panel { padding: 18px; border-radius: var(--radius-xl); }
.emm-gen-panel-head h2 { font-size: 1rem; letter-spacing: -0.02em; }
.emm-gen-panel-head p { font-size: 12.5px; line-height: 1.7; }
.emm-gen-tile { padding: 11px 13px; border-radius: 10px; background: var(--rd-surface-2); }
.emm-gen-tile strong { font-size: 1.2rem; font-weight: 650; }
.emm-gen-bar { height: 6px; background: color-mix(in srgb, var(--rd-ink) 8%, transparent); }
.emm-gen-words { border-color: var(--border); border-radius: 12px; background: var(--rd-surface-2); padding: 6px; gap: 6px; }
.emm-gen-words li { border-radius: 9px; background: var(--rd-surface); }
.emm-gen-task { padding: 10px 12px; border-radius: 10px; background: var(--rd-surface-2); }
.emm-gen-batch { padding: 11px 12px; border-radius: 10px; background: var(--rd-surface-2); }
.emm-gen-grammar { border-radius: 12px; background: var(--rd-surface-2); }
.emm-gen-grammar-progress { background: var(--rd-surface); }
.emm-gen-check { border-radius: 9px; background: var(--rd-surface); }
.emm-gen-check.is-on {
  background: color-mix(in srgb, var(--accent) 8%, var(--rd-surface));
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
}
.emm-gen-grammar-count { border-radius: var(--radius-full); }
.emm-gen-tab { padding: 7px 13px; border-radius: 9px; background: var(--rd-surface-2); font-weight: 550; }
.emm-gen-tab.is-active { background: var(--rd-blue-soft); border-color: color-mix(in srgb, var(--accent) 40%, var(--border)); color: var(--nav-active-ink); }
.emm-gen-actions .btn { border-radius: 10px; }
.emm-gen-issues > li { background: var(--rd-surface-2); }
.emm-gen-live-item { background: var(--rd-surface-2); }
.emm-gen-live {
  padding: 16px;
  border-radius: var(--radius-xl);
  background: color-mix(in srgb, var(--accent) 4%, var(--rd-surface));
}
.emm-gen-live-retry-bar { height: 4px; }

/* 打印出口 */
.emm-paper-layout { gap: 20px; }
.emm-paper-form { padding: 24px; }
.emm-paper-field > label, .emm-paper-field > legend { font-size: 13px; font-weight: 600; }
.emm-paper-radios label { border-radius: 11px; background: var(--rd-surface-2); }
.emm-paper-radios label:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.emm-paper-task-pick { border-radius: 11px; }
.emm-paper-done { border-radius: 14px; }
.emm-paper-side .emm-panel { padding: 20px; }
.emm-paper-note { font-size: 12px; line-height: 1.75; }

/* ============================================================
   11. 生物背诵册
   ============================================================ */

.br-panel { border-radius: 16px; background: var(--rd-surface); box-shadow: var(--shadow-sm); }
/* ⚠ .br-overview 是「今日/统计/进度」三块瓦片的 grid 容器，本身没有底色；
   给它加卡片底会变成「卡里再套卡」。这里只给真正的瓦片加圆角。 */
.br-today, .br-stat, .br-progress, .br-checkin-bar, .br-checkin-hero,
.br-session-bar, .br-start-bar { border-radius: 14px; }
/* ⚠⚠ 概览区原来是「今日 300px | 统计 4 格」+「进度条只占右列」，
   于是第一行左高右矮、第二行只有右边一条进度条，左边空出一块 ——
   三块瓦片的边缘互相对不齐，壁纸模式下那块空白直接露出照片。
   改成：第一行「今日 + 统计」等高，进度条独占第二行整宽，边缘自然对齐。 */
.br-overview { align-items: stretch; }
.br-progress { grid-column: 1 / -1; }
.br-today, .br-stat { align-content: center; }
.br-checkin-bar { box-shadow: var(--shadow-xs); }
.br-card { border-radius: 16px; background: var(--rd-surface); box-shadow: var(--shadow-sm); }
.br-feedback { border-radius: 14px; background: var(--rd-surface-2); }
.br-primary-btn, .br-ghost-btn { border-radius: 11px; }
.br-icon-btn { border-radius: 10px; }
.br-row-go, .br-back-btn { border-radius: 10px; }
.br-tag { padding: 2px 9px; border-radius: var(--radius-full); font-size: 0.68rem; font-weight: 600; }
.br-quiz-tabs { border-radius: 10px; overflow: hidden; }
.br-quiz-tab { border-radius: 0; }
.br-choice { border-radius: 11px; }
.br-today-track { border-radius: 99px; background: color-mix(in srgb, var(--rd-ink) 8%, transparent); }
.br-progress-track, .br-session-track { border-radius: 99px; background: color-mix(in srgb, var(--rd-ink) 8%, transparent); }
.br-mini-track { border-radius: 99px; }
.br-stat strong { font-weight: 650; letter-spacing: -0.02em; }
.br-summary, .br-checkin-hero { border-radius: 16px; }
.br-cal-cell { border-radius: 9px; }
/* 生物背诵册的强调色只有一支 #15803d：浅色下当文字 4.8:1 没问题，
   深色下压在近黑上只有 3.8:1。这里**只换文字**，不换 token ——
   --br-accent 同时是主按钮、激活页签、进度条的实底（白字必须保持深绿）。 */
[data-theme="dark"] :is(
  .br-eyebrow,
  .br-today-main strong,
  .br-progress-head strong,
  .br-session-position > span,
  .br-flip-prompt strong,
  .br-summary-score strong,
  .br-next-note,
  .br-tag--cloze
) { color: var(--success); }
[data-theme="dark"] .br-progress-more > summary::after { color: var(--success); }

/* ============================================================
   12. 错题本 / 掌握本 / 笔记 / 刷题 / 数学练习 / 搜索
   ============================================================ */

.list-stats, .wrong-stats-row { gap: 12px; }
.list-stat { padding: 16px 12px; border-radius: 14px; }
.list-stat__num, .wrong-stat-num { font-size: 1.5rem; font-weight: 650; letter-spacing: -0.02em; }
.list-stat__label, .wrong-stat-label { font-size: 0.72rem; }
.list-toolbar, .wrong-toolbar {
  padding: 10px;
  border-radius: 12px;
  border-color: var(--border-light);
  background: var(--rd-surface-2);
}
.list-search, .wrong-search-wrap { border-radius: 10px; }
.list-btn, .wrong-tab, .wrong-filter-btn, .wrong-group-btn {
  border-radius: 9px;
  font-weight: 550;
  transition: background var(--transition-fast), color var(--transition-fast),
    border-color var(--transition-fast);
}
.list-content { gap: 12px; }
.list-group { border-radius: 14px; }
.list-group__header { background: var(--rd-surface-2); }
.list-item { padding: 15px 18px; }
.list-item__q, .wrong-question { font-size: 0.92rem; line-height: 1.7; }
.list-item__a, .wrong-answer { border-radius: 10px; }

/* 刷题 / 闪卡 */
.quiz-scope-list { border-radius: 14px; }
.quiz-bottom-bar { border-color: var(--border); box-shadow: 0 -8px 24px -18px rgba(8, 10, 18, 0.4); }
.qz-count-pill { border-radius: 8px; background: var(--accent-fill); color: #fff; font-weight: 600; }
.qz-btn { border-radius: 10px; }
.review-card { box-shadow: var(--shadow-md); }
.review-card-question { padding: 26px 28px 20px; }
.review-card-content { font-size: 0.98rem; line-height: 1.85; }
.flashcard-progress-bar, .fc-progress-bar { background: color-mix(in srgb, var(--rd-ink) 8%, transparent); }
.flashcard-progress-fill, .fc-progress-fill { background: var(--accent-fill); }
.fc-first-btn, .fc-list-btn, .fc-icon-btn { border-radius: 9px; }

/* 数学笔记 */
.mn-search { border-radius: 10px; }
.mn-note-card { border-radius: 14px; }
.mn-grid { gap: 14px; }
.mn-icon-btn { border-radius: 8px; }
.mn-viewer-dialog { border-radius: 16px; }

/* 数学练习 */
.mp-stage { padding: 20px; border-radius: 14px; }
.mp-stage-no {
  border-radius: 7px;
  background: var(--rd-blue-soft);
  color: var(--nav-active-ink);
  font-size: 0.7rem;
  font-weight: 700;
}
.mp-stage h3 { font-size: 0.98rem; }
.mp-template-card, .mp-diff-btn { border-radius: 11px !important; }
.mp-diff-btn.active { background: var(--accent-fill) !important; color: #fff !important; border-color: var(--accent-fill) !important; }
.mp-template-grid { gap: 9px; }

/* 搜索页 */
.sch-heading h1 { font-size: clamp(1.6rem, 1.2rem + 1.4vw, 2rem); letter-spacing: -0.03em; }
.sch-heading p { font-size: 0.88rem; }
.sch-sticky {
  top: calc(var(--nav-height) + 10px);
  padding: 12px;
  border-radius: 14px;
  border-color: var(--border);
  /* 用不透明的 --rd-bg 派生，而不是半透明的 --rd-surface：
     这一条本身承载筛选小字，壁纸模式下不能再叠一层透明度。 */
  background: color-mix(in srgb, var(--rd-bg) 94%, transparent);
}
.sch-filters { padding-top: 8px; gap: 10px; }
.sch-chip { min-height: 30px; padding: 5px 11px; border-radius: 8px; font-size: 0.78rem; }
.sch-chip.is-active { background: var(--rd-blue-soft); border-color: color-mix(in srgb, var(--accent) 22%, var(--border)); color: var(--nav-active-ink); }
.sch-book-btn { border-radius: 8px; }
.sch-card { padding: 18px 20px; border-radius: 14px; }
.sch-card__q { font-size: 0.95rem; line-height: 1.7; }
.sch-card__badge { border-radius: 6px; }
.sch-history__tag { border-radius: 7px; }

/* ============================================================
   13. 响应式收口
   ============================================================ */

@media (max-width: 1100px) {
  .home-hero { grid-template-columns: 1fr; gap: 28px; margin-bottom: 44px; }
  .home-hero-panel { align-self: auto; }
  .emm-hero { grid-template-columns: minmax(0, 1fr) 220px; gap: 24px; padding: 26px; }
  .emm-gen-layout { grid-template-columns: minmax(0, 1fr); }
  .emm-gen-rail { position: static; }
  .emm-paper-layout { grid-template-columns: 1fr; }
  .subject-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  /* 导航从 56 / 52px 变成 60px 后，旧断点里的 78px / 72px 顶部内边距
     只剩十几像素的呼吸位；统一按 --nav-height 推。 */
  #page-container { padding: calc(var(--nav-height) + 18px) 20px 64px; }
}

@media (max-width: 760px) {
  #page-container { padding: calc(var(--nav-height) + 20px) 16px 64px; }
  .nav-inner { padding: 0 16px; }
  .nav-logo { font-size: 0.9rem; }
  .eng-header { gap: 10px; padding-bottom: 12px; }
  .eng-page-title { letter-spacing: -0.026em; }
  .emm-tabs { margin-top: 10px; padding: 4px; gap: 2px; border-radius: var(--radius-lg); }
  .emm-tab { padding: 8px 12px; font-size: 13px; }
  .emm-body { margin-top: 18px; }
  /* 手机端窗口本来就是全屏铺满（eng-maimemo.css 的媒体规则），
     这里必须同步去掉 18px 圆角，否则四角会露出遮罩。 */
  .emm-window { border-radius: 0; }
  .emm-hero { grid-template-columns: 1fr; gap: 20px; padding: 22px; }
  .emm-hero-progress { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 10px; }
  .emm-progress-ring { width: 104px; height: 104px; }
  .emm-grid-2 { grid-template-columns: 1fr; gap: 14px; }
  .emm-word-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px; }
  .emm-card { padding: 22px; min-height: 0; }
  .emm-prompt { font-size: 17.5px; }
  .home-hero h1 { letter-spacing: -0.038em; font-size: clamp(2.05rem, 7.6vw, 2.6rem); }
  .home-hero-copy > p { font-size: 0.95rem; margin: 16px 0 22px; }
  .home-countdown-main strong { font-size: clamp(3rem, 16vw, 4rem); }
  .subject-card-grid { grid-template-columns: 1fr; gap: 12px; }
  .card-content { min-height: 124px; padding: 20px; grid-template-columns: 44px minmax(0, 1fr) 22px; }
  .subject-card { min-height: 124px; }
  .card-icon-wrapper { width: 44px; height: 44px; }
  .sch-sticky { top: calc(var(--nav-height) + 8px); }
  .list-toolbar, .wrong-toolbar { padding: 8px; }
  .page-header { margin-bottom: 22px; }
  .modal-body, .settings-body { padding: 18px; }
  .modal-header, .settings-header { padding: 15px 18px; }
  .emm-dialog { padding: 20px; }
  .emm-window-head { padding: 15px 17px 12px; }
  .emm-window-body { padding: 14px 17px 18px; }
}

@media (max-width: 420px) {
  #page-container { padding-left: 12px; padding-right: 12px; }
  .nav-actions { gap: 2px; }
  .nav-btn { padding: 0 8px; }
  /* 首页大标题在 390px 下会被 <br> + em 断成三行、末行只剩两个字；
     这里压字号并去掉强制换行，让它按语义自然折行。 */
  .home-hero h1 { font-size: clamp(1.85rem, 9.2vw, 2.2rem); line-height: 1.18; }
  .home-hero h1 br { display: none; }
  .emm-tab { padding: 7px 10px; font-size: 12.5px; }
  .subject-card-grid { gap: 10px; }
  .card-content { gap: 12px; padding: 18px; }
}

/* ============================================================
   14. 触屏与减动效
   ============================================================ */

@media (pointer: coarse) {
  .nav-btn { min-height: 40px; }
  .emm-tab { min-height: 40px; }
  .emm-icon-btn, .eng-back-btn, .mod-back-btn, .back-btn { min-width: 40px; min-height: 40px; }
  .filter-chip, .emm-filter, .sch-chip { min-height: 36px; }
  .btn { min-height: 42px; }
  .btn-sm { min-height: 36px; }
  .emm-window-open, .emm-gen-tab, .emm-gen-task-retry { min-height: 38px; }
  .emm-gen-mode { min-height: 64px; }
  .list-btn, .wrong-tab, .wrong-filter-btn, .wrong-group-btn { min-height: 40px; }
  .emm-word-card { padding: 15px 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .subject-card:hover, .mod-card:hover, .item-card:hover, .bk-card:hover,
  .ch-card:hover, .mn-note-card:hover, .emm-word-card:hover,
  .eng-action-card:hover, .emm-entry:hover, .btn:hover,
  .emm-gen-mode:hover, .emm-gen-task:hover, .emm-gen-batch:hover {
    transform: none;
  }
}

/* ============================================================
   15. 维护约定（新增组件前先读）
   ============================================================

   1. **先找能不能复用既有类**，不要为「看起来新一点」造一套新的卡片/标签类。
      本层的意义是收敛，不是扩张：每多一套视觉语言，后面就多一处漂移。

   2. **有壁纸时的可读性仍由 wallpaper.css 兜底**。如果新加了「直接铺在
      页面上的说明文字 / 工具栏 / 计数」，把它加进 wallpaper.css 的
      「零散小字背衬」名单；如果新加了会浮在壁纸上的面板，把它加进
      玻璃模糊名单。否则在亮色壁纸上会出现读不清的裸文字。

   3. **深色主题的实底控件一律用 --accent-fill / --success-solid /
      --danger-solid**，不要用 --accent / --success / --danger —— 后者
      是「在深色底上可读的文字色」，当底色配白字不达 AA。

   4. **动效只改 transform / opacity / box-shadow / background-color**。
      不要用 width / height / top / left 做过场，长列表里会掉帧。

   5. 修改本文件后不需要构建：服务端按 mtime/size 现拼 /css/bundle.css，
      浏览器会通过热更新重新拉取。
   ============================================================ */

/* 打印出口（/print/*、打印预览）会复用本样式表：把装饰性阴影与动效去掉，
   避免灰度打印时出现脏边。
   ⚠ 必须同时把文字压成深色：深色主题的 --rd-ink 是近白色，只把底色刷白
     等于白底白字；而 main.css 的打印规则又强制 .btn 背景为白，主按钮的
     白字会一起消失。 */
@media print {
  :is(.subject-card, .mod-card, .mod-stat, .item-card, .bk-card, .ch-card,
    .review-card, .home-hero-panel, .list-stat, .wrong-stat-card, .list-group,
    .list-toolbar, .mn-toolbar, .emm-panel, .emm-card, .emm-hero, .emm-entry,
    .emm-word-card, .br-panel, .br-card, .modal-dialog,
    .settings-dialog, .emm-dialog, .emm-window) {
    box-shadow: none !important;
    background: #fff !important;
    border-color: #ccc !important;
    color: #111111 !important;
  }
  .emm-tabs, .emm-tab, .filter-chip, .emm-chip {
    background: transparent !important;
    box-shadow: none !important;
  }
  .btn-primary, .btn-success, .btn-danger {
    background: #fff !important;
    border-color: #999 !important;
    color: #111111 !important;
  }
}

/* ============================================================
   16. 统一表面渐变（v11 · 边缘渐隐 · 最后一道覆盖）
   ============================================================

   目的：让全站承载文字的卡片/面板/弹窗都带上**边缘渐隐**的玻璃质感 ——
   表面中心实、四周向外淡出，边界融进壁纸/页面底色，没有硬边框。

   ⚠ v11 换的是**渐变结构**（v8/v9 是整体明度或透明度渐变）：
     · 卡片**不再有实心底色 + 硬边框**，改成一层**径向渐变**：
       中心（0~72%）是完整的 --rd-surface，向外到 100% 淡成透明；
     · 因此必须同时 `background-color: transparent` + `border-color: transparent`
       —— 否则纯色底/边框会从渐变边缘透出来，等于白做；
     · 但**文字背衬不能丢**：渐变在 72% 之后才开始淡出，而卡片内边距
       通常 14~30px，正文都落在实心区内。壁纸模式下 --rd-surface 本身
       已是 94% 玻璃，中心区可读性与改动前完全一致。

   ⚠⚠ 为什么这段必须放在文件**最后**：
     前面（含各页面样式表）有 51 处 `background: var(--rd-surface)` 的
     纯色声明，同特异性下只有后出现的才赢。

   ⚠ 为什么用 background-image + 清掉 background-color：
     只加渐变不清底色，底色会在渐变透明处露出来，边缘还是实的。
   ============================================================ */

/* 一级表面：**大面板 / 独立卡片** —— 边缘渐隐。
   ⚠⚠ 这份名单只放"大面积、内边距 ≥18px"的容器。
     密集网格里的卡片（词卡、科目卡、模块卡、笔记卡…）**不能**渐隐：
     它们间距只有 10~14px，渐隐带会把卡片之间的分界吃掉，整片糊成一团。

   ⚠⚠⚠ **绝对不能把 mask 加在容器本身**（这是上一版真实踩到的 bug）：
     `mask-image` 会作用到元素的**全部内容**，包括里面的文字 ——
     靠近边缘的文字被一起淡成半透明，直接压在壁纸上读不清
     （用户反馈"部分文字直接显示在壁纸上不易看见"就是这个原因）。
     正确做法：容器本身透明，把**背景层**放到 `::after` 上，只对
     `::after` 做 mask。这样只有背景淡出，文字始终 100% 不透明。 */
:is(
  .home-hero, .home-hero-panel, .emm-hero, .emm-hero-progress,
  .emm-panel, .emm-card, .emm-window, .modal-dialog, .settings-dialog,
  .emm-dialog, .br-panel, .br-card, .br-feedback, .emm-paper-form,
  .mp-stage, .ov-container
) {
  position: relative;
  isolation: isolate;
  background-color: transparent;
  background-image: none;
  border-color: transparent;
  box-shadow: none;
}
:is(
  .home-hero, .home-hero-panel, .emm-hero, .emm-hero-progress,
  .emm-panel, .emm-card, .emm-window, .modal-dialog, .settings-dialog,
  .emm-dialog, .br-panel, .br-card, .br-feedback, .emm-paper-form,
  .mp-stage, .ov-container
)::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  border-radius: inherit;
  background-color: var(--rd-surface);
  background-image:
    radial-gradient(120% 90% at 0% 0%,
      color-mix(in srgb, var(--accent) 6%, transparent) 0%,
      transparent 55%);
}
/* ⚠⚠ v12：边缘柔化改用**多层柔和投影**，不再用 mask 渐隐。
   踩过两次坑，记录在这里避免重犯：
     1. mask 加在元素上 → 连文字一起淡出，文字压在壁纸上读不清；
     2. mask 加在 ::after 上并向外扩 → 大元素上要么看不见（固定 px 太小），
        要么相邻元素的柔光层互相重叠糊成一片（22px 时科目卡完全并块）。
   投影没有这两个问题：它画在元素**外部**、不参与元素自身的绘制，
   天然不会淡掉文字，也不会被 overflow 裁剪；相邻卡片的投影叠加
   只是让间隙稍暗，不会糊掉卡片边界。
   ⚠ 用**扩散型**（spread 为负、blur 很大）而不是普通投影：
     普通投影是"往下掉一块影子"，扩散型是四边均匀的柔雾，才像边缘柔化。 */
:is(
  .home-hero, .home-hero-panel, .emm-hero, .emm-hero-progress,
  .emm-panel, .emm-card, .emm-window, .modal-dialog, .settings-dialog,
  .emm-dialog, .br-panel, .br-card, .br-feedback, .emm-paper-form,
  .mp-stage, .ov-container
) {
  box-shadow:
    0 0 24px -6px color-mix(in srgb, var(--rd-bg-solid) 78%, transparent),
    0 0 56px -14px color-mix(in srgb, var(--rd-bg-solid) 62%, transparent),
    0 2px 10px -4px rgba(0, 0, 0, 0.28);
}

/* 标准表面：**密集网格里的卡片**。
   ⚠⚠ 必须显式写 background-color：这些组件在各自页面样式表里的底色是
      `var(--bg-secondary)`，壁纸模式下它是半透明的，叠加后整体太透，
      说明文字（--text-tertiary 中灰）压在照片亮部读不清。

   ⚠ v12 给它们也加了**柔边**（用户截图里首页 6 张科目卡是硬边深色块，
     在亮壁纸上"边缘有些生硬"）。做法与一级表面相同：背景层放 ::after
     并向外扩，渐隐只发生在盒子外部 —— 卡片内部仍 100% 不透明，
     文字一点不受影响。
   ⚠ 外扩距离比一级表面小（14px）：这些卡片网格间距只有 14px，
     再大会和邻卡的柔边叠在一起，卡片分界就糊了（上一版踩过）。 */
:is(
  .subject-card, .mod-card, .mod-stat, .item-card, .bk-card, .ch-card,
  .review-card, .list-stat, .wrong-stat-card, .mn-note-card,
  .quiz-scope-list, .mp-template-card, .emm-entry, .emm-word-card,
  .emm-gen-panel, .emm-paper-done, .br-today, .br-stat, .br-progress,
  .br-checkin-bar, .br-session-bar, .br-start-bar, .list-group, .list-item,
  .sch-card, .sch-bar, .mn-search, .emm-search, .emm-select, .mp-diff-btn
) {
  position: relative;
  isolation: isolate;
  background-color: transparent;
  background-image: none;
  border-color: transparent;
  box-shadow: none;
  /* ⚠⚠ 必须解除裁剪：`.subject-card` 原本是 `overflow: hidden`
     （为了裁圆角里的图标/水波纹），但 ::after 是**向外扩 22px** 的，
     overflow:hidden 会把外扩部分整块裁掉 —— 柔边完全不出现
     （实测：hero 柔边生效、科目卡毫无变化，就是这个原因）。
     改成 visible 后柔边才能透出；圆角裁剪由 ::after 自己的
     border-radius 承担，视觉上不受影响。 */
  overflow: visible;
}
:is(
  .subject-card, .mod-card, .mod-stat, .item-card, .bk-card, .ch-card,
  .review-card, .list-stat, .wrong-stat-card, .mn-note-card,
  .quiz-scope-list, .mp-template-card, .emm-entry, .emm-word-card,
  .emm-gen-panel, .emm-paper-done, .br-today, .br-stat, .br-progress,
  .br-checkin-bar, .br-session-bar, .br-start-bar, .list-group, .list-item,
  .sch-card, .sch-bar, .mn-search, .emm-search, .emm-select, .mp-diff-btn
)::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  border-radius: inherit;
  background-color: var(--rd-surface);
  background-image:
    radial-gradient(120% 90% at 0% 0%,
      color-mix(in srgb, var(--accent) 5%, transparent) 0%,
      transparent 55%);
}
/* 密集网格卡片的柔化：投影**收紧**（12~24px）。
   ⚠ 网格间距只有 14px，投影半径必须小于间距的一半左右，
     否则相邻卡片的投影在间隙里叠成一团灰雾，卡片边界反而更糊。
     实测 24px/-6px 是这套间距下的上限。 */
:is(
  .subject-card, .mod-card, .mod-stat, .item-card, .bk-card, .ch-card,
  .review-card, .list-stat, .wrong-stat-card, .mn-note-card,
  .quiz-scope-list, .mp-template-card, .emm-entry, .emm-word-card,
  .emm-gen-panel, .emm-paper-done, .br-today, .br-stat, .br-progress,
  .br-checkin-bar, .br-session-bar, .br-start-bar, .list-group, .list-item,
  .sch-card, .sch-bar, .mn-search, .emm-search, .emm-select, .mp-diff-btn
) {
  box-shadow:
    0 0 18px -5px color-mix(in srgb, var(--rd-bg-solid) 72%, transparent),
    0 1px 4px -2px rgba(0, 0, 0, 0.22);
}

/* 大面积面板：渐变更缓、边缘更软（它们尺寸大，淡出区可以更宽）。 */
:is(
  .home-hero, .home-hero-panel, .emm-hero, .emm-hero-progress,
  .emm-gen-rail, .br-panel, .br-checkin-hero, .mp-stage--launch,
  .emm-panel, .modal-dialog, .settings-dialog, .emm-window, .emm-dialog
) {
  background-image:
    radial-gradient(130% 100% at 0% 0%,
      color-mix(in srgb, var(--accent) 10%, transparent) 0%,
      transparent 60%),
    radial-gradient(ellipse 130% 124% at 50% 40%,
      var(--rd-surface) 0%,
      var(--rd-surface) 64%,
      color-mix(in srgb, var(--rd-surface) 80%, transparent) 84%,
      color-mix(in srgb, var(--rd-surface) 36%, transparent) 95%,
      transparent 100%);
}

/* 二级表面：卡片内部的「井」。
   ⚠ 井**不做**边缘渐隐：它是"凹进去的一块"，边界必须清楚，
     否则和卡片混成一片，层次就没了。只保留很淡的内阴影。 */
:is(
  .emm-gen-tile, .emm-gen-mode, .emm-gen-words, .emm-gen-task, .emm-gen-batch,
  .emm-gen-presets, .emm-gen-grammar, .emm-gen-scope, .emm-gen-daypick,
  .emm-gen-issues > li, .emm-gen-live-item, .emm-detail-facts > div,
  .emm-phrase-list li, .emm-history-list li,
  .emm-kind-list li, .emm-scope-list li, .emm-option, .emm-question-explain,
  .emm-segments li, .emm-gen-tab, .emm-gen-check, .emm-paper-radios label,
  .list-group__header, .emm-word-row, .emm-word-list, .emm-wrong-list
) {
  background-image: linear-gradient(150deg,
    color-mix(in srgb, #000000 0%, transparent) 0%,
    color-mix(in srgb, #000000 5%, transparent) 100%);
}

/* 卡片 hover：现在卡片本身是透明的（背景在 ::after 上），
   所以 hover 必须作用到 ::after，否则改的是看不见的层。
   ⚠ v12 修正：上一版这里给卡片本体设 background-image，
     而本体现在 background-image 是 none、背景全在 ::after 上 ——
     等于 hover 完全没效果。 */
:is(.subject-card, .mod-card, .item-card, .bk-card, .ch-card, .review-card,
  .emm-panel, .emm-card, .emm-word-card, .emm-entry, .eng-action-card,
  .mp-template-card, .br-card):hover::after {
  background-image:
    radial-gradient(120% 90% at 0% 0%,
      color-mix(in srgb, var(--accent) 14%, transparent) 0%,
      transparent 58%);
}

/* ⚠⚠ 壁纸模式下还必须**再压一次**边框与阴影：
   wallpaper.css 在本文件之后加载，它给这些卡片写了
   `html.has-wallpaper .subject-card { border-color: ...; box-shadow: ... }`
   （特异性 (0,2,1)），会把我上面那句 `border-color: transparent` 盖掉 ——
   边缘渐隐就又被一圈硬描边框住了（实测截图里能清楚看到那圈线）。

   ⚠ 这里**必须提高特异性**才能赢：`html.has-wallpaper :is(...)` 只有
     (0,2,1)，和 wallpaper 的那条**打平**，而后者加载更晚 —— 打平就是输。
     改成 `html.has-wallpaper.has-wallpaper :is(...)` = (0,3,1)，
     稳定压过 (0,2,1)，同时不依赖文件加载顺序。 */
html.has-wallpaper.has-wallpaper :is(
  .subject-card, .mod-card, .mod-stat, .item-card, .bk-card, .ch-card,
  .review-card, .home-hero-panel, .list-stat, .wrong-stat-card,
  .mn-note-card, .ov-container, .quiz-scope-list, .mp-stage, .mp-template-card,
  .emm-panel, .emm-card, .emm-hero, .emm-entry, .emm-word-card, .emm-gen-rail,
  .emm-gen-panel, .emm-paper-form, .emm-paper-done, .emm-dialog, .emm-window,
  .modal-dialog, .settings-dialog, .br-panel, .br-card, .br-feedback,
  .br-checkin-hero, .br-today, .br-stat, .br-progress, .br-checkin-bar,
  .br-session-bar, .br-start-bar, .list-group, .list-toolbar, .list-item,
  .sch-card, .sch-bar, .sch-sticky, .mn-search, .mn-viewer-dialog,
  .emm-search, .emm-select, .mp-diff-btn,
  .home-hero, .emm-hero-progress, .emm-gen-rail, .mp-stage--launch
) {
  border-color: transparent;
  box-shadow: none;
}

/* 按钮组：主按钮保持实底（可点击控件必须有清晰边界，不能渐隐），
   只补内高光。 */
.btn-primary, .btn-success, .btn-danger {
  box-shadow: var(--surface-sheen), 0 2px 8px -3px color-mix(in srgb, currentColor 40%, transparent);
}

/* ⚠ 以下组件**不参与**边缘渐隐，各自保留语义底色与边框：
   - .emm-gen-panel--review-*：3px 状态左条 + 整块状态色底
   - .emm-gen-live：淡蓝底表示"正在跑"
   - .emm-paper-done：蓝框蓝底是"打印完成"的全部强调
   - .filter-chip.active / .emm-tab.is-active：激活态用浅色底 + ink 字
   - .br-today.is-clear：左边 3px 绿条
   - 所有按钮 / 输入框 / 弹窗内的表单控件：需要明确边界
   它们的背景与边框由各自规则负责，这里不覆盖。 */

/* ============================================================
   17. 维护约定补充（v8）
   ============================================================

   1. 新增卡片时**不要**再写 `background: var(--rd-surface)` ——
      直接把类名加进上面第 16 段的一级表面名单即可，渐变与内高光会自动跟上。
   2. 需要"井"（比卡片更暗的内层容器）就加进二级表面名单。
   3. 大面板（>600px 宽）才加进品牌面名单；小卡片掺主色会脏。
   ============================================================ */
/* ---- 导航 / 页签 / 统计块：同属「大面积横向容器」 ----
   它们和卡片一样需要玻璃层次；之前漏了，导致页面顶部（导航 + 页签）
   看起来是平的、下面卡片却有渐变 —— 一条竖线上两种质感，反而更割裂。
   ⚠ 这几个是**覆盖在壁纸/页面上的半透明条**，只能用带 alpha 的
     渐变（不能用 --surface-grad：那两端是实色，会在条上变成实心块）。 */
#top-nav {
  background-image: linear-gradient(150deg,
    color-mix(in srgb, var(--rd-surface-solid) 30%, transparent) 0%,
    color-mix(in srgb, var(--rd-surface-solid) 10%, transparent) 55%,
    transparent 100%);
}
#top-nav.scrolled {
  background-image: linear-gradient(150deg,
    color-mix(in srgb, var(--rd-surface-solid) 40%, transparent) 0%,
    color-mix(in srgb, var(--rd-surface-solid) 16%, transparent) 55%,
    transparent 100%);
}
:is(.emm-tabs, .emm-stat, .emm-stats, .list-stats, .wrong-stats-row) {
  background-image: linear-gradient(150deg,
    color-mix(in srgb, var(--rd-surface-solid) 24%, transparent) 0%,
    transparent 62%);
}
/* 激活页签自己已经是浅色底 + ink 字，只补一道左上角高光（与斜向光一致）。 */
.emm-tab.is-active, .filter-chip.active, .sch-chip.is-active {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.10),
    inset 1px 0 0 rgba(255, 255, 255, 0.05);
}

/* ---- 移动端收口：生成台模式卡的统计文字会溢出 ----
   ⚠ 实测 390px 下 `.emm-gen-mode-stat` 的 right 到 402px（超出视口 12px）：
     模式卡是 `display:flex`，图标 34px + 文字块（可压缩到 0）+ 统计块，
     统计块 `white-space: nowrap` 撑着不肯缩，于是顶出卡片。
     窄屏改成纵向堆叠，统计块独占一行。 */
@media (max-width: 560px) {
  .emm-gen-mode {
    flex-wrap: wrap;
    gap: 8px 10px;
  }
  .emm-gen-mode-text { flex: 1 1 100%; min-width: 0; }
  .emm-gen-mode-stat { flex: 0 0 auto; white-space: normal; }
}
/* ==== pages/wallpaper.css ==== */
/**
 * 壁纸系统样式
 *
 * 与玻璃 UI 的配合方式：
 * - 壁纸层固定在底层（z-index: 0），#app 是 z-index: 1，
 *   所以导航栏、卡片、弹窗这些半透明玻璃面板会直接透出壁纸 —— 玻璃质感靠的就是这个。
 * - 压暗遮罩与滤镜只作用在壁纸层内部，不影响页面内容，也不影响玻璃面板自身效果。
 * - --wp-dim 由 JS 按用户设置写入（0~0.8），用来压暗壁纸以保证文字对比度。
 *
 * 层级（每张壁纸一个 .wallpaper-slide）：
 *   .wallpaper-photo     背景图 + 缩放/旋转/翻转 + 颜色滤镜
 *   .wallpaper-vignette  暗角
 *   .wallpaper-tint      叠色
 *   .wallpaper-caption   文字叠加
 */

.wallpaper-layer {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transition: opacity .5s ease;
  background: var(--bg-primary);
}

.wallpaper-layer.is-visible {
  opacity: 1;
}

/* ========== 单张壁纸（两张交叉淡入，切换时不会黑屏） ========== */

.wallpaper-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .9s ease;
}

.wallpaper-slide.is-active {
  opacity: 1;
}

.wallpaper-photo {
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  background-position: 50% 50%;
  background-size: cover;
  transform-origin: center center;
  /* 缩放/旋转后边缘会露底色，稍微放大兜住 */
  will-change: transform, filter;
}

.wallpaper-vignette {
  position: absolute;
  inset: 0;
  opacity: 0;
  background: radial-gradient(ellipse at center, transparent 42%, rgba(0, 0, 0, .82) 100%);
  transition: opacity .2s ease;
}

.wallpaper-tint {
  position: absolute;
  inset: 0;
  opacity: 0;
  background: #000;
  transition: opacity .2s ease;
}

.wallpaper-caption {
  position: absolute;
  max-width: 88%;
  line-height: 1.3;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  letter-spacing: .02em;
}

/* 压暗遮罩：保证玻璃面板上的文字仍有足够对比度 */
.wallpaper-layer::after {
  content: '';
  position: absolute;
  inset: 0;
  background: #000;
  opacity: var(--wp-dim, .35);
  pointer-events: none;
  transition: opacity .2s ease;
}

/* 浅色主题下用偏白的遮罩，避免整站被压得发灰 */
[data-theme="light"] .wallpaper-layer::after {
  background: #fff;
  opacity: calc(var(--wp-dim, .35) * .75);
}

/* 有壁纸时页面底色必须透明，否则壁纸被盖住 */
html.has-wallpaper body {
  background-color: transparent;
}

/* main.css 的 body::before 顶部辉光也是 z-index:0，会和壁纸层抢层。
   有壁纸时藏起来，辉光压在照片上会发灰。 */
html.has-wallpaper body::before {
  display: none;
}

/* 顶部导航在壁纸下保持玻璃质感 */
html.has-wallpaper #top-nav {
  background: color-mix(in srgb, var(--bg-primary) 72%, transparent);
}

/* ============================================================
   玻璃 UI 层：有壁纸时把「硬底表面」变成半透明玻璃
   ============================================================

   做法是**在 token 层单点改写**，而不是逐个组件改样式：
   组件样式全部写成 `background: var(--rd-surface)`，这里只要把
   `--rd-surface` 换成半透明版本，60+ 处组件一次全部生效。

   为什么用 backdrop-filter：半透明只是"透出颜色"，加模糊才有玻璃的
   "厚度感"。两者缺一都会显得像没画完的色块。

   --ui-opacity 由 JS 按用户设置写入（30~100，默认 70）。
   ⚠ 这里刻意**不改** --rd-line-solid：它是描边色，需要保持可辨识的对比度。
------------------------------------------------------------ */
html.has-wallpaper {
  --ui-glass-blur: 18px;
  /* 通透度 → 混色比例。opacity=70 表示表面保留 70% 实色。
     ⚠ 所有派生比例都从这一个变量算出来，这样不支持 backdrop-filter 时
       只要把它改大，整套表面会一起变实（见文末的 @supports 兜底）。 */
  --ui-glass-mix: calc(var(--ui-opacity, 70) * 1%);

  /**
   * ⚠ 承载**文字**的表面有一个可读性下限，不能跟着用户一路调透。
   *
   * ⚠⚠ 这个下限是**实测扫出来**的，不是估算的。最坏情况
   *    （深色主题 + 纯白壁纸 + 用户透明度 70%）实测：
   *
   *      下限    --text-secondary   --text-tertiary
   *      85%        3.93 ✗             3.32 ✗
   *      88%        4.32 ✗             3.65 ✗
   *      90%        4.70 ✓             3.98 ✗
   *      92%        5.00 ✓             4.23 ✗
   *      94%        5.33 ✓             4.51 ✓   ← 取这个
   *     100%        6.25 ✓             5.29 ✓
   *
   *    也就是说：**原先的 85% 并没有兑现它的承诺** —— 注释里曾写
   *    「85% 保证次级文字 4.59:1」，但真实像素只有 3.93:1，
   *    连次级文字都不达标（tertiary 更低）。改成 94% 后两者才都过 AA。
   *
   *    ⚠ 为什么不再往低调：90% 时 tertiary 只有 3.98，要达标就得把
   *      --text-tertiary 调亮到 rgb(148)，与 --text-secondary(154)
   *      几乎同色 —— 三级文字的层次就没了。94% 能在**不改配色**的前提下达标。
   *
   *    用户想更透时，卡片表面不低于 94%；而纯装饰性/无文字的表面
   *    （下面单独处理）仍可跟着 --ui-glass-mix 一起透。
   */
  --ui-glass-text-mix: max(var(--ui-glass-mix), 94%);

  /* 给"直接压在壁纸上的零散小字"（标签条、工具栏、进度…）垫背衬的实色比例。
     它们用同一份下限：实测 --text-tertiary 要到 94% 才够 4.51:1。
     ⚠ 不要在这里另写一个数 —— 两处一旦不一致，就会出现
       "卡片上的字看得清、卡片外的字看不清"这种很难查的差异。 */
  --wp-text-backing: color-mix(in srgb, var(--rd-bg-solid) var(--ui-glass-text-mix), transparent);

  --surface: color-mix(in srgb, var(--surface-solid) var(--ui-glass-mix), transparent);
  --surface-strong: color-mix(in srgb, var(--surface-strong-solid) var(--ui-glass-text-mix), transparent);
  /* ⚠ --bg-secondary 也必须用**有下限**的那份。
     实测：`.emm-panel` 这类卡片底色就是它，若跟着 --ui-glass-mix 一路调透
     （透明度 30% 时只剩 30% 实色），面板里的小标题在纯白壁纸上只有 1.74:1。
     全仓它被用作背景 218 处、只有 1 处当 border-color（math-notes 的色板
     外框，那里偏透一点不影响可读性）—— 所以按"承载文字的表面"处理是对的。 */
  --bg-secondary: color-mix(in srgb, var(--bg-secondary-solid) var(--ui-glass-text-mix), transparent);
  --bg-tertiary: color-mix(in srgb, var(--bg-tertiary-solid) var(--ui-glass-mix), transparent);

  /* ⚠ --rd-surface / --rd-surface-2 铺在**大量含文字的容器**上
     （卡片、面板、列表项、工具栏），所以用有下限的那份。 */
  --rd-surface: color-mix(in srgb, var(--rd-surface-solid) var(--ui-glass-text-mix), transparent);
  --rd-surface-2: color-mix(in srgb, var(--rd-surface-2-solid) var(--ui-glass-text-mix), transparent);
  --rd-line: color-mix(in srgb, var(--rd-line-solid) 68%, transparent);
}

/* ⚠⚠ 亮色主题的玻璃不能用 94% 的白：白底 94% 盖在照片上基本就是一张
   纯白纸（实测卡片 = rgb(255,255,255) / 0.94），整页像贴了两层白纸，
   壁纸完全看不见，玻璃感彻底消失。
   亮色下文字是**深色压在浅底**上，对比度本来就高，不需要那么实的底 ——
   降到 78% 白 + 更强模糊，既透出壁纸又保持文字可读。
   ⚠ 只覆盖「承载文字的表面」，描边与文字色不动。
   ⚠⚠ 选择器必须写成 `html.has-wallpaper[data-theme="light"]`：
     `data-theme` 和 `has-wallpaper` **都挂在 <html> 上**，写成
     `[data-theme="light"] html.has-wallpaper` 是「html 的后代」，
     永远不匹配 —— 这条规则会静默失效（实测截图毫无变化）。 */
html.has-wallpaper[data-theme="light"] {
  --ui-glass-text-mix: max(var(--ui-glass-mix), 78%);
  --wp-text-backing: color-mix(in srgb, var(--rd-bg-solid) max(var(--ui-glass-mix), 86%), transparent);
  --ui-glass-blur: 22px;
}

/* 承载类组件统一加模糊，让玻璃有"厚度"。
   只列真正需要"浮在壁纸上"的容器；文字、图标不加，避免变成糊的。 */
html.has-wallpaper .subject-card,
html.has-wallpaper .mod-card,
html.has-wallpaper .mod-stat,
html.has-wallpaper .review-card,
html.has-wallpaper .bk-card,
html.has-wallpaper .chapter-card,
html.has-wallpaper .item-card,
html.has-wallpaper .list-group,
html.has-wallpaper .list-item,
html.has-wallpaper .wrong-item,
html.has-wallpaper .eb-item,
html.has-wallpaper .sch-card,
html.has-wallpaper .sch-sticky,
html.has-wallpaper .eng-action-card,
html.has-wallpaper .mn-note-card,
html.has-wallpaper .mn-card,
html.has-wallpaper .home-hero-panel,
html.has-wallpaper .ov-container,
html.has-wallpaper .ov-sidebar,
html.has-wallpaper .quiz-scope-list,
html.has-wallpaper .modal-dialog,
html.has-wallpaper .settings-dialog,
html.has-wallpaper .list-toolbar,
html.has-wallpaper .mn-toolbar,
html.has-wallpaper .mp-stage,
html.has-wallpaper .dv-scene-card,
html.has-wallpaper .toast,
/* 英语（墨墨）页的半透明面板与统计块：底色是 --bg-secondary，
   不给它们加模糊的话，半透明会显得像一块没画完的色块。 */
html.has-wallpaper .emm-panel,
html.has-wallpaper .emm-hero,
html.has-wallpaper .emm-stat,
html.has-wallpaper .emm-entry,
/* v7 精修层新纳入的承载面板：底色是 --rd-surface（壁纸下即 94% 玻璃），
   不补模糊会与相邻玻璃面板看起来不是同一套材质。 */
html.has-wallpaper .emm-card,
html.has-wallpaper .emm-gen-panel,
html.has-wallpaper .emm-gen-rail,
html.has-wallpaper .emm-paper-form,
html.has-wallpaper .emm-paper-done,
html.has-wallpaper .br-panel,
html.has-wallpaper .br-card,
html.has-wallpaper .br-feedback,
html.has-wallpaper .br-checkin-hero,
/* 通用刷题模块（.pra-*）：卡片/面板/结果卡都是 --bg-secondary 半透明底，
   不补模糊会与相邻玻璃面板看起来不是同一套材质。手写画布**不在此列** ——
   它的纸面是固定浅色（导出 PNG 给模型批改用），加模糊只会糊掉笔迹。 */
html.has-wallpaper .pra-card,
html.has-wallpaper .pra-panel,
html.has-wallpaper .pra-question,
html.has-wallpaper .pra-answer,
html.has-wallpaper .pra-grade-result,
html.has-wallpaper .pra-stream-panel,
html.has-wallpaper .pra-wrong-detail,
html.has-wallpaper .pra-wrong-item,
html.has-wallpaper .pra-wrong-filter,
html.has-wallpaper .pra-empty,
/* 英语（墨墨）页的横向标签条：它是个"漏网"的容器 —— 自己没有底色、
   子项 .emm-tab 也是 background: transparent，而且不承载 h1/h2，
   所以玻璃层的两份名单（有底色的面板 / 裸标题垫背衬）都盖不到它。
   实测压在亮色天空上时，未选中标签用的 --text-tertiary 几乎看不见。
   这里按"导航玻璃条"给它一层底（见下方 .emm-tabs 的底色规则）。 */
html.has-wallpaper .emm-tabs,
/* 长列表窗口（候选词 / 选词记录 / 长难句…）：它铺在最上层，
   不给模糊会像贴在壁纸上的一块死板实色，和周围玻璃面板格格不入。 */
html.has-wallpaper .emm-window,
html.has-wallpaper .mod-secondary-item,
html.has-wallpaper .sch-empty,
html.has-wallpaper .sch-bar,
html.has-wallpaper .card-icon-wrapper {
  backdrop-filter: blur(var(--ui-glass-blur)) saturate(140%);
  -webkit-backdrop-filter: blur(var(--ui-glass-blur)) saturate(140%);
}

/* 底部固定条/顶栏：模糊要更强，因为内容会从它们下面滚过 */
html.has-wallpaper .quiz-bottom-bar,
html.has-wallpaper .dv-nav-bar,
html.has-wallpaper .eng-reader-bottombar,
html.has-wallpaper #top-nav,
html.has-wallpaper .nb-actions-bar,
html.has-wallpaper .mn-main-actions {
  backdrop-filter: blur(24px) saturate(150%);
  -webkit-backdrop-filter: blur(24px) saturate(150%);
}

/* 标签条要有一层**底**，否则上面的模糊无从体现（透明背景上模糊等于没做）。
   ⚠ 用 --wp-text-backing（92%）而不是 --rd-surface：标签用的是
     --text-tertiary（中灰），在 85% 的表面上只有 3.59:1，仍低于 AA。
   ⚠ 只加 background / 圆角，**不动 padding 与 border**：
     它们参与布局，改了会让标签整体位移。背景不参与布局，零位移。
   ⚠ 标签条从 v7 起是**胶囊容器**（四周都有 padding/圆角），必须四角都圆；
     只给上面两角的话，底部两个直角会和胶囊形状对不上（一眼可见）。 */
html.has-wallpaper .emm-tabs {
  background: var(--wp-text-backing);
  border-radius: var(--radius-xl, 14px);
}

/* 玻璃边缘：1px 内高光 + 略强的描边，模拟玻璃的厚度与反光。
   没有这一层，半透明色块看起来只是"变淡了"，不像玻璃。 */
html.has-wallpaper .subject-card,
html.has-wallpaper .mod-card,
html.has-wallpaper .mod-stat,
html.has-wallpaper .review-card,
html.has-wallpaper .bk-card,
html.has-wallpaper .chapter-card,
html.has-wallpaper .item-card,
html.has-wallpaper .list-group,
html.has-wallpaper .sch-card,
html.has-wallpaper .eng-action-card,
html.has-wallpaper .mn-note-card,
html.has-wallpaper .mn-card,
html.has-wallpaper .home-hero-panel,
html.has-wallpaper .modal-dialog,
html.has-wallpaper .settings-dialog,
html.has-wallpaper .emm-card,
html.has-wallpaper .emm-gen-rail,
html.has-wallpaper .emm-paper-form,
html.has-wallpaper .br-panel,
html.has-wallpaper .br-feedback,
html.has-wallpaper .emm-window,
html.has-wallpaper .pra-card,
html.has-wallpaper .pra-panel,
html.has-wallpaper .pra-question,
html.has-wallpaper .pra-answer,
html.has-wallpaper .pra-grade-result,
html.has-wallpaper .pra-stream-panel,
html.has-wallpaper .pra-wrong-detail,
html.has-wallpaper .pra-wrong-item,
html.has-wallpaper .pra-wrong-filter,
html.has-wallpaper .pra-empty {
  border-color: color-mix(in srgb, var(--rd-line-strong) 62%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 16%, transparent),
    var(--rd-shadow);
}

/* 浅色主题下壁纸通常是亮的，白玻璃会糊成一片 —— 改用略深的描边压出轮廓 */
[data-theme="light"] html.has-wallpaper .subject-card,
[data-theme="light"] html.has-wallpaper .mod-card,
[data-theme="light"] html.has-wallpaper .review-card,
[data-theme="light"] html.has-wallpaper .modal-dialog,
[data-theme="light"] html.has-wallpaper .settings-dialog,
[data-theme="light"] html.has-wallpaper .emm-card,
[data-theme="light"] html.has-wallpaper .emm-gen-rail,
[data-theme="light"] html.has-wallpaper .br-panel,
[data-theme="light"] html.has-wallpaper .emm-window,
[data-theme="light"] html.has-wallpaper .pra-card,
[data-theme="light"] html.has-wallpaper .pra-panel,
[data-theme="light"] html.has-wallpaper .pra-question,
[data-theme="light"] html.has-wallpaper .pra-answer,
[data-theme="light"] html.has-wallpaper .pra-grade-result,
[data-theme="light"] html.has-wallpaper .pra-stream-panel,
[data-theme="light"] html.has-wallpaper .pra-wrong-detail {
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 55%, transparent),
    0 1px 2px color-mix(in srgb, #000 8%, transparent),
    var(--rd-shadow);
}

/* ========== 文字可读性兜底 ==========
   ⚠ 这一层是必需的，不是装饰。

   页面上大部分文字都坐在卡片上（卡片自己的半透明表面就是背衬），
   少数"裸文字"直接压在壁纸上：首页 hero、分区标题、以及各页页头
   （`.home-hero` / `.home-section-head` / `.page-header` / `.eng-header` 等，
   实测它们到 body 之间没有任何不透明背景）。这一层专门给它们垫背衬。

   ⚠ 实测最坏情况：纯白壁纸 + 不压暗时，深色主题的大标题只有 2.25:1
     （AA 需要 4.5:1）—— 不加这层就是真的看不清。

   ⚠ 为什么不做「整页蒙层」：那会把壁纸整体压灰，玻璃观感全毁。
     实测 30 个有文字的元素里只有 8 个需要背衬，所以只补这些容器。

   ⚠ 这里是**按结构兜**，不是逐个列页面类名：页头/标题区在实现上普遍是
     「透明容器 > 标题块 > h1/h2」，逐页列类名必然漏（实测就漏了
     `.eng-header`、`.sch-heading`、`.mod-header`、`.mod-section-head` ——
     每个都让对应页面的标题在亮色壁纸上掉到 1.14:1）。所以选择器覆盖三类：
       1. 已知的具体页头/分区标题容器（明确、零副作用）
       2. `#page-container > * > header`（页面级页头）
       3. 直接承载 h1/h2 的透明容器（`*:has(> h1)` / `*:has(> h2)`）
     新增页面只要沿用「页头容器 + h1/h2」的既有结构就自动被覆盖。

   ⚠⚠ 必须防"嵌套叠加"：这些容器会互相嵌套（`.page-title-row > .page-header > h1`
     有三层都命中，首页 `.home-hero > .home-hero-copy` 两层都命中）。
     两层 79% 蒙层叠起来约等于 96% 不透明 —— 实测把 hero 压成 rgb(12,14,18)
     的近实色块，玻璃感全没（算术验证见 tmp/stack-math.mjs）。
     所以只让**最外层**的那个容器出蒙层。

   ⚠ 排除时必须用**并集**：不同选择器家族之间会互相嵌套
     （`.home-hero` 属类名列表，`.home-hero-copy` 属 `:has(> h1)`），
     按单个家族排除是看不见对方的，两层照样叠。
     因此这里把全部选择器并成一个 `:is(...)`，再 `:not(:is(全部) *)`。 */
html.has-wallpaper :is(
  .home-hero,
  .home-section-head,
  .page-header,
  .page-title-row,
  .eng-header,
  .emm-header,
  .mod-header,
  .mod-title-block,
  .mod-section-head,
  .sch-heading,
  .bk-title-block,
  .mod-hero,
  #page-container *:has(> h1),
  #page-container *:has(> h2)
):not(:is(
  .home-hero,
  .home-section-head,
  .page-header,
  .page-title-row,
  .eng-header,
  .emm-header,
  .mod-header,
  .mod-title-block,
  .mod-section-head,
  .sch-heading,
  .bk-title-block,
  .mod-hero,
  #page-container *:has(> h1),
  #page-container *:has(> h2)
) *) {
  position: relative;
  isolation: isolate;
}
html.has-wallpaper :is(
  .home-hero,
  .home-section-head,
  .page-header,
  .page-title-row,
  .eng-header,
  .emm-header,
  .mod-header,
  .mod-title-block,
  .mod-section-head,
  .sch-heading,
  .bk-title-block,
  .mod-hero,
  #page-container *:has(> h1),
  #page-container *:has(> h2)
):not(:is(
  .home-hero,
  .home-section-head,
  .page-header,
  .page-title-row,
  .eng-header,
  .emm-header,
  .mod-header,
  .mod-title-block,
  .mod-section-head,
  .sch-heading,
  .bk-title-block,
  .mod-hero,
  #page-container *:has(> h1),
  #page-container *:has(> h2)
) *)::before {
  content: '';
  position: absolute;
  /* 向外扩一点，让背衬有柔和边缘，不像贴了块补丁 */
  inset: -12px -16px;
  z-index: -1;
  pointer-events: none;
  border-radius: calc(var(--rd-radius, 8px) * 2);
  /* ⚠ 蒙层有**可读性下限**，不随 --ui-opacity 一路变薄。
     这里直接用 --ui-glass-text-mix（= max(用户透明度, 94%)），
     与卡片表面、零散小字背衬**共用同一个实测下限** ——
     三处各写一个数迟早会不一致，出现"卡片里看得清、卡片外看不清"。

     ⚠ 曾经写成 `calc(96% - mix * 0.2)`（随 uiOpacity 升高而变薄），
       方向是**反的**：uiOpacity=100 意味着"界面最实、最不需要透明"，
       蒙层却是最薄的 76%，对比度掉到 3.63:1。
     ⚠ 也曾写成 `max(86%, calc(96% - mix * 0.1))`，实测最坏只有
       3.93:1（次级文字）—— 同样没达标。94% 是实测扫出来的下限。
     蒙层的职责是保证文字永远可读，不该被透明度设置削弱。 */
  background: color-mix(in srgb, var(--rd-bg-solid) var(--ui-glass-text-mix), transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  /* ⚠⚠ 边缘必须**渐隐**：这一层是 94% 的近实色，硬边在壁纸上就是一块
     突兀的深色矩形（首页 hero、工作区 TOOLS 标题、数学笔记页头都能看到
     那块"补丁"的直边）。用 mask 把四周 16px 拉成透明渐变 ——
     底色比例一点不用降，可读性下限不动，只是让边界融进壁纸。 */
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%),
    linear-gradient(180deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
  mask-image:
    linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%),
    linear-gradient(180deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

/* ========== 页头内层：不垫背衬，外层页头补上 ==========
   ⚠⚠ `:has(> h1)` / `:has(> h2)` 会命中**页头内部**的标题行容器
   （`.mn-heading-title`、`.br-heading`、`.bk-title-block` 这类
   「直接含 h1 的 div」），于是那块 94% 的近实色蒙层被垫进了页头内部 ——
   在壁纸上就是一块比页头小一圈的深色直边矩形，压在标题后面，
   比卡片本身还突兀（数学笔记、生物背诵册、数学练习三页都能看到）。

   ⚠ 但直接关掉内层还不够：这些页头的外层（`.mn-page-header` 是
     `<header>`、h1 在**孙层**）不满足 `:has(> h1)`，于是内层关掉之后
     整页标题就彻底裸在壁纸上了（实测副标题直接读不清）。
     所以这里成对处理：内层 ::before 关掉，外层显式补一份背衬。 */
html.has-wallpaper :is(
  .mn-heading-title,
  .mn-page-heading > .mn-heading-title,
  .br-heading,
  .bk-title-block,
  .mn-page-header .mn-page-heading,
  .br-header .br-heading,
  .bk-header .bk-title-block
)::before {
  display: none;
}
html.has-wallpaper :is(
  .mn-page-header,
  .br-header,
  .bk-header
) {
  position: relative;
  isolation: isolate;
}
html.has-wallpaper :is(
  .mn-page-header,
  .br-header,
  .bk-header
)::before {
  content: '';
  position: absolute;
  inset: -10px -14px;
  z-index: -1;
  pointer-events: none;
  border-radius: calc(var(--rd-radius, 8px) * 2);
  background: color-mix(in srgb, var(--rd-bg-solid) var(--ui-glass-text-mix), transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  /* 与主背衬同一套边缘渐隐：近实色块硬边在壁纸上太突兀。 */
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%),
    linear-gradient(180deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
  mask-image:
    linear-gradient(90deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%),
    linear-gradient(180deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

/* ========== 首页分区标题：只垫文字块，不铺整行 ==========
   ⚠ `.home-section-head` 是 `display:flex; justify-content:space-between`
   的全宽容器：左边是「YOUR CURRICULUM + 选择一个学习方向」，右边是
   「六个科目 · 各自的复习路径」。背衬铺在容器上就是一条 1160px 宽的
   深色横带，横穿整个页面 —— 比标题本身抢眼得多。
   真正需要可读性兜底的只有左边那块标题文字，所以这里把整行容器的背衬
   关掉，改由内层文字块承担。 */
html.has-wallpaper .home-section-head::before { display: none; }
html.has-wallpaper .home-section-head > :first-child {
  position: relative;
  isolation: isolate;
}
/* ⚠ v12 把背衬从「硬边圆角贴片」改成**径向柔和光晕**。
   原因：用户截图里 "YOUR CURRICULUM / 选择一个学习方向" 背后是一块
   边缘齐整的深色小方块，压在壁纸上非常突兀 —— 比文字本身还抢眼。
   径向渐变让背衬中心实、四周自然消散，读起来像"壁纸局部压暗了一点"，
   而不是"贴了一张纸"。
   ⚠ 椭圆尺寸要比文字块大（140% / 170%），否则光晕收得太紧又变回贴片。 */
html.has-wallpaper .home-section-head > :first-child::before {
  content: '';
  position: absolute;
  inset: -14px -26px;
  z-index: -1;
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(ellipse 62% 58% at 50% 50%,
    var(--wp-text-backing) 0%,
    color-mix(in srgb, var(--wp-text-backing) 72%, transparent) 46%,
    transparent 78%);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
/* 右侧那句说明文字也要能读，但它更短，给更紧的背衬。 */
html.has-wallpaper .home-section-count {
  position: relative;
  isolation: isolate;
  padding: 2px 6px;
}
html.has-wallpaper .home-section-count::before {
  content: '';
  position: absolute;
  inset: -10px -18px;
  z-index: -1;
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(ellipse 60% 56% at 50% 50%,
    var(--wp-text-backing) 0%,
    color-mix(in srgb, var(--wp-text-backing) 70%, transparent) 46%,
    transparent 78%);
}

/* ========== 工作台/通用分区标题：只垫文字块 ==========
   ⚠ `.mod-section-head` 与首页 `.home-section-head` 同构：全宽 flex，
   左边「TOOLS / 学习工具」、右边「1 个模块可用」。背衬铺在容器上就是
   一条横贯页面的深色带（实测 1160×44 的整条），比标题抢眼。
   同理只让左侧文字块承担背衬。 */
html.has-wallpaper .mod-section-head::before { display: none; }
html.has-wallpaper .mod-section-head > :first-child {
  position: relative;
  isolation: isolate;
}
html.has-wallpaper .mod-section-head > :first-child::before {
  content: '';
  position: absolute;
  /* v12：径向柔光，取代硬边贴片（同 .home-section-head）。 */
  inset: -14px -26px;
  z-index: -1;
  pointer-events: none;
  border-radius: 50%;
  border-radius: var(--rd-radius, 8px);
  background: var(--wp-text-backing);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0, #000 10px, #000 calc(100% - 10px), transparent 100%),
    linear-gradient(180deg, transparent 0, #000 8px, #000 calc(100% - 8px), transparent 100%);
  mask-image:
    linear-gradient(90deg, transparent 0, #000 10px, #000 calc(100% - 10px), transparent 100%),
    linear-gradient(180deg, transparent 0, #000 8px, #000 calc(100% - 8px), transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
/* 右侧计数同样单独垫。 */
html.has-wallpaper .mod-section-head > :last-child {
  position: relative;
  isolation: isolate;
}
html.has-wallpaper .mod-section-head > :last-child::before {
  content: '';
  position: absolute;
  inset: -2px -6px;
  z-index: -1;
  pointer-events: none;
  border-radius: 6px;
  background: var(--wp-text-backing);
}
/* ⚠ 「更多工具」的 <summary> 也是整行宽（实测 1160×23），背衬铺上去
   就是一条细长横带。改成按内容收缩，只包住文字和计数。 */
html.has-wallpaper .mod-secondary-tools > summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: auto;
}

/* ========== v11 补漏：整块区域文字（实测扫描发现） ==========
   ⚠ 这一批是**成组的标题 + 说明文字**，不属于任何卡片，整条祖先链透明。
     实测扫描（找"文字元素往上 8 层都没有画上背景"的）发现：
       · 首页 `.home-section-head` 左侧的 YOUR CURRICULUM / 选择一个学习方向
       · 英语页 `.emm-section-head` 的 MODULES / 复习模块
       · 词库页 `.emm-count`（共 382 个）
       · 数学笔记页 `.mn-intro` 里的 eyebrow / h2 / p / 条笔记 / 新建分组
     这些在深色主题 + 亮壁纸下是**看不清**的（浅灰压亮照片）。
     ⚠ 上一版只给 `.home-section-head` 和 `.mod-section-head` 做了，
       漏了 `.emm-section-head` 与 `.mn-intro` —— 现在一并补上。
     ⚠ 用 -6px -10px 的紧背衬（配标题级字号），不要用页头那套 -12px -16px。 */
html.has-wallpaper :is(
  .home-section-head > :first-child,
  .emm-section-head > :first-child,
  .mn-intro > :first-child
) {
  position: relative;
  isolation: isolate;
}
html.has-wallpaper :is(
  .home-section-head > :first-child,
  .emm-section-head > :first-child,
  .mn-intro > :first-child
)::before {
  content: '';
  position: absolute;
  /* v12：径向柔光，取代硬边贴片。 */
  inset: -16px -30px;
  z-index: -1;
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(ellipse 60% 56% at 50% 50%,
    var(--wp-text-backing) 0%,
    color-mix(in srgb, var(--wp-text-backing) 70%, transparent) 46%,
    transparent 78%);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
/* 右侧的计数/说明文字（"六个科目 · 各自的复习路径"、"共 382 个"）单独垫。 */
html.has-wallpaper :is(
  .home-section-count,
  .emm-section-head > :last-child,
  .emm-count
) {
  position: relative;
  isolation: isolate;
  padding: 1px 5px;
}
html.has-wallpaper :is(
  .home-section-count,
  .emm-section-head > :last-child,
  .emm-count
)::before {
  content: '';
  position: absolute;
  /* v12：径向柔光，取代硬边小贴片。 */
  inset: -10px -18px;
  z-index: -1;
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(ellipse 60% 56% at 50% 50%,
    var(--wp-text-backing) 0%,
    color-mix(in srgb, var(--wp-text-backing) 70%, transparent) 46%,
    transparent 78%);
}
/* 数学笔记页的 intro 区：h2 是整段标题，p 是说明，右下是计数。
   ⚠ `.mn-intro` 是 flex 两端布局，直接给整个容器垫会变成一条横带，
     所以拆成"左块 / 右侧计数"两部分。 */
html.has-wallpaper .mn-intro > :last-child {
  position: relative;
  isolation: isolate;
  padding: 2px 6px;
}
html.has-wallpaper .mn-intro > :last-child::before {
  content: '';
  position: absolute;
  /* v12：径向柔光，取代硬边小贴片。 */
  inset: -10px -18px;
  z-index: -1;
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(ellipse 60% 56% at 50% 50%,
    var(--wp-text-backing) 0%,
    color-mix(in srgb, var(--wp-text-backing) 70%, transparent) 46%,
    transparent 78%);
}

/* 数学笔记页的「新建分组」是虚线描边的**透明按钮**（设计上就是要透出底色），
   在壁纸下文字直接压在照片上：`--mn` 淡紫压在亮部几乎看不见。
   ⚠ 不要给它实底 —— 那会破坏"虚线 + 空槽"的语义。只垫一层很淡的背衬。 */
html.has-wallpaper .mn-group-add {
  background: var(--wp-text-backing);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* ========== 零散小字的背衬 ==========
   上面那份名单是"页头/标题区"，按结构兜。但还有一类漏网的：
   **页面正文流里的小号提示文字**（计数、过滤标签、进度、"更多工具"），
   它们不属于任何卡片，背后就是壁纸本身，而且用的是最弱的
   --text-tertiary（中灰）—— 实测对着亮色壁纸只有 3.24:1。

   ⚠ 为什么单独一份名单、不复用上面的：上面的 inset 是 -12px -16px，
     配大标题合适；套到"共 174 个"这种小字上会糊成一大块补丁。
     这里用更紧的 -4px -8px。
   ⚠ 底色用 --wp-text-backing（与卡片表面同一个实测下限），
     不跟随 --ui-opacity 变薄：背衬的职责是保证文字可读，
     跟上面那份蒙层同理（有测试与实机核对钉住）。

   实测来源：全站结构扫描（找出"整条祖先链都透明"的文字元素）
   只找到这 4 个容器，其余页面都是 0 处。

   ⚠ 第 45 轮补进 `.emm-grid-hint`：词库改成卡片网格后新加的一行说明文字。
     它就是同一类问题（裸文字、祖先链全透明），实测在壁纸亮部**读不清**
     （浅灰 `--text-tertiary` 压在角色图的亮色区域上）。

   ⚠ 第 46 轮补进**通用刷题模块**（`css/pages/practice.css`，`.pra-*`）的裸文字：
      页头的「共 10 题 · 12 分钟」、单元行的题数/时长、知识点组的计数、
      流面板的通道标签、进度计数、错题本副标题。它们要么祖先链全透明
      （页头、面板外），要么住在一层很淡的
      `color-mix(... 4%, var(--bg-secondary))` 里 —— 壁纸亮部下同样是 3.x:1。
      `.pra-unit-desc` 住在 `.pra-unit-pick`（玻璃）里本可豁免，但它是
      `--text-secondary` 且常被单行截断，垫一层不影响观感、更稳。
      ⚠ `.pra-hint` / `.pra-meta` 是**契约第 7.4 节点名的**两个类，
        新增同类裸文字时照这份名单继续加。

   ⚠ 第 47 轮：题库从「平铺列表行」改成「知识点 → 单元 → 难度」三层结构，
      `.pra-bank-meta` / `.pra-bank-desc` 已随旧结构删除，换成
      `.pra-unit-meta` / `.pra-topic-meta` / `.pra-unit-desc`。
      **知识点组的计数（`.pra-topic-meta`）尤其需要背衬** ——
      它直接坐在 `.pra-topic` 的半透明底上，壁纸亮部下几乎读不出。

     新增这类"直接铺在页面上的说明文字"时，记得一并加进这份名单。 */
html.has-wallpaper :is(
  .emm-toolbar,
  .emm-progress,
  .emm-window-more,
  .emm-grid-hint,
  .mod-secondary-tools > summary,
  .pra-hint,
  .pra-meta,
  .pra-unit-meta,
  .pra-topic-meta,
  .pra-unit-desc,
  .pra-stream-pane-label,
  .pra-ink-foot,
  .pra-grade-wrongbook,
  .pra-progress-label,
  .pra-wrong-sub
) {
  position: relative;
  isolation: isolate;
}
html.has-wallpaper :is(
  .emm-toolbar,
  .emm-progress,
  .emm-window-more,
  .emm-grid-hint,
  .mod-secondary-tools > summary,
  .pra-hint,
  .pra-meta,
  .pra-unit-meta,
  .pra-topic-meta,
  .pra-unit-desc,
  .pra-stream-pane-label,
  .pra-ink-foot,
  .pra-grade-wrongbook,
  .pra-progress-label,
  .pra-wrong-sub
)::before {
  content: '';
  position: absolute;
  inset: -4px -8px;
  z-index: -1;
  pointer-events: none;
  border-radius: var(--rd-radius, 8px);
  background: var(--wp-text-backing);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* 高透明模式（--ui-opacity < 60，由 JS 打标记）：背衬加满。 */
html.has-wallpaper[data-ui-transparent="high"] :is(
  .home-hero,
  .home-section-head,
  .page-header,
  .page-title-row,
  .eng-header,
  .emm-header,
  .mod-header,
  .mod-title-block,
  .mod-section-head,
  .sch-heading,
  .bk-title-block,
  .mod-hero,
  #page-container *:has(> h1),
  #page-container *:has(> h2)
):not(:is(
  .home-hero,
  .home-section-head,
  .page-header,
  .page-title-row,
  .eng-header,
  .emm-header,
  .mod-header,
  .mod-title-block,
  .mod-section-head,
  .sch-heading,
  .bk-title-block,
  .mod-hero,
  #page-container *:has(> h1),
  #page-container *:has(> h2)
) *)::before {
  background: color-mix(in srgb, var(--rd-bg-solid) 98%, transparent);
}

/* 旧浏览器不支持 backdrop-filter 时退回"更实的表面"：
   宁可少一点玻璃感，也不能让文字压在照片上读不清。
   只改 --ui-glass-mix，所有派生表面会一起变实。 */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  html.has-wallpaper {
    --ui-glass-mix: 94%;
  }
}

/* ========== 编辑时的「所见即所得」预览 ========== */

/* 弹窗打开时把遮罩调淡，让用户看清身后真实壁纸的编辑效果 */
.overlay.wp-previewing {
  background: rgba(0, 0, 0, .18);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  /* 这个弹窗比通用弹窗高得多：main.css 的 padding-top:18vh 会把它顶出视口 */
  padding-top: 4vh;
  align-items: center;
}

[data-theme="dark"] .overlay.wp-previewing {
  background: rgba(0, 0, 0, .3);
}

/* ========== 弹窗 ========== */

.wp-dialog {
  max-width: 760px;
  width: min(94vw, 760px);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
}

.wp-dialog .settings-header h3 {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.wp-count {
  font-size: .72rem;
  font-weight: 500;
  color: var(--text-tertiary, var(--rd-faint));
  font-variant-numeric: tabular-nums;
}

.wp-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-md, 12px);
  overflow-y: auto;
  padding: var(--space-lg, 16px) var(--space-xl, 20px);
}

.wp-body.is-dragover {
  outline: 2px dashed var(--rd-blue);
  outline-offset: -6px;
  border-radius: var(--radius-md);
}

.wp-upload-row {
  display: flex;
  align-items: center;
  gap: var(--space-md, 12px);
  flex-wrap: wrap;
}

.wp-upload-btn {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  position: relative;
  overflow: hidden;
  flex: none;
}

.wp-hint {
  margin: 0;
  font-size: .76rem;
  line-height: 1.5;
  color: var(--text-tertiary, var(--rd-faint));
}

/* ========== 缩略图网格 ========== */

.wp-preview {
  border: 1px solid var(--border, var(--rd-line));
  border-radius: var(--radius-md, var(--rd-radius));
  padding: 8px;
  background: var(--bg-tertiary, var(--rd-surface-2));
  flex: none;
}

.wp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 8px;
  max-height: 200px;
  overflow-y: auto;
}

.wp-card {
  position: relative;
  border-radius: 6px;
  overflow: hidden;
  border: 2px solid transparent;
  cursor: pointer;
  background: var(--bg-hover, var(--rd-line));
  aspect-ratio: 16 / 10;
}

.wp-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transform-origin: center center;
}

.wp-card:hover {
  border-color: var(--border-hover, var(--rd-line-strong));
}

/* 当前选中的壁纸：描边 + ✓ 角标（不只靠颜色表意） */
.wp-card.is-active {
  border-color: var(--rd-blue);
}

.wp-card.is-active::after {
  content: '✓';
  position: absolute;
  top: 4px;
  left: 4px;
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--rd-blue-strong, var(--rd-blue));
  color: #fff;
  font-size: .68rem;
  line-height: 1;
}

/* 已自定义角标 */
.wp-card-badge {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(0, 0, 0, .6);
  color: #fff;
  font-size: .66rem;
  line-height: 1;
}

.wp-card-bar {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 3px 4px 3px 6px;
  background: linear-gradient(to top, rgba(0, 0, 0, .72), transparent);
  color: #fff;
}

.wp-card-name {
  flex: 1;
  min-width: 0;
  font-size: .66rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.wp-card-del {
  flex: none;
  position: relative;
  overflow: hidden;
  width: 18px;
  height: 18px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font-size: .8rem;
  line-height: 1;
  cursor: pointer;
}

.wp-card-del:hover {
  background: var(--rd-red);
}

.wp-empty {
  padding: var(--space-lg, 16px);
  text-align: center;
  color: var(--text-secondary, var(--rd-muted));
  font-size: .85rem;
}

.wp-empty p {
  margin: 0 0 4px;
}

.wp-empty-hint {
  font-size: .76rem;
  color: var(--text-tertiary, var(--rd-faint));
}

/* ========== 编辑面板 ========== */

.wp-editor {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: var(--space-md, 12px);
  border: 1px solid var(--border, var(--rd-line));
  border-radius: var(--radius-md, var(--rd-radius));
  background: var(--bg-secondary, var(--rd-surface));
}

.wp-editor-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

.wp-title-row {
  flex: 1;
  min-width: 180px;
}

.wp-editor-tools {
  display: flex;
  gap: 6px;
  flex: none;
}

.wp-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.wp-preset {
  padding: 4px 11px;
  border: 1px solid var(--border, var(--rd-line));
  border-radius: var(--radius-full, 999px);
  background: transparent;
  color: var(--text-secondary, var(--rd-muted));
  font-size: .76rem;
  cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}

.wp-preset:hover {
  background: var(--bg-hover, var(--rd-surface-2));
  color: var(--text-primary, var(--rd-ink));
  border-color: var(--border-hover, var(--rd-line-strong));
}

/* 折叠分区：默认只展开第一段，避免弹窗一开就是几十个滑块 */
.wp-section {
  border: 1px solid var(--border, var(--rd-line));
  border-radius: var(--radius-md, var(--rd-radius));
  overflow: hidden;
}

.wp-section > summary {
  padding: 8px 12px;
  font-size: .82rem;
  font-weight: 600;
  color: var(--text-primary, var(--rd-ink));
  background: var(--bg-tertiary, var(--rd-surface-2));
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.wp-section > summary::-webkit-details-marker {
  display: none;
}

.wp-section > summary::after {
  content: '▾';
  font-size: .7rem;
  color: var(--text-tertiary, var(--rd-faint));
  transition: transform .15s ease;
}

.wp-section[open] > summary::after {
  transform: rotate(180deg);
}

.wp-section-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
}

.wp-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: .82rem;
  color: var(--text-primary, var(--rd-ink));
}

.wp-row-col {
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
}

.wp-row input[type="text"],
.wp-row textarea,
.wp-row select {
  font-size: .82rem;
  padding: 5px 8px;
  border: 1px solid var(--border, var(--rd-line));
  border-radius: var(--radius-sm, 6px);
  background: var(--bg-primary, var(--rd-bg));
  color: var(--text-primary, var(--rd-ink));
  font-family: inherit;
  resize: vertical;
}

.wp-row textarea {
  width: 100%;
  box-sizing: border-box;
  line-height: 1.45;
}

.wp-row select {
  min-width: 120px;
}

.wp-row-switch input[type="checkbox"] {
  width: 18px;
  height: 18px;
  accent-color: var(--rd-blue);
  cursor: pointer;
  flex: none;
}

.wp-row-range {
  flex-wrap: wrap;
}

.wp-row-range input[type="range"] {
  flex: 1;
  min-width: 150px;
  accent-color: var(--rd-blue);
  cursor: pointer;
}

.wp-row em {
  font-style: normal;
  color: var(--text-tertiary, var(--rd-faint));
  font-variant-numeric: tabular-nums;
}

.wp-row-btns,
.wp-row-color {
  flex-wrap: wrap;
}

.wp-btn-group,
.wp-color-group {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.wp-color-group input[type="range"] {
  flex: 1;
  min-width: 110px;
  accent-color: var(--rd-blue);
}

.wp-color-group input[type="color"] {
  width: 34px;
  height: 26px;
  padding: 0;
  border: 1px solid var(--border, var(--rd-line));
  border-radius: var(--radius-sm, 6px);
  background: transparent;
  cursor: pointer;
}

/* 小号按钮（编辑面板里的工具） */
.btn.btn-sm {
  padding: 4px 10px;
  font-size: .76rem;
  line-height: 1.5;
  min-width: 0;
}

/* 处于开启状态的开关型按钮（翻转）：加粗描边，不只靠颜色 */
.btn.is-on {
  border-color: var(--rd-blue);
  color: var(--rd-blue);
  background: var(--rd-blue-soft, rgba(37, 99, 235, .1));
}

/* ========== 整体设置 ========== */

.wp-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding: var(--space-md, 12px) var(--space-xl, 20px);
  border-top: 1px solid var(--border, var(--rd-line));
  flex: none;
}

.btn.wp-danger {
  color: var(--rd-red);
  border-color: color-mix(in srgb, var(--rd-red) 40%, transparent);
  margin-right: auto;
}

.btn.wp-danger:hover {
  background: var(--rd-red-soft);
}

.wp-actions .btn[disabled],
.wp-editor-tools .btn[disabled] {
  opacity: .45;
  cursor: not-allowed;
}

/* ========== 响应式 ========== */

@media (max-width: 620px) {
  .wp-dialog {
    width: 96vw;
    max-height: 92vh;
  }
  .wp-grid {
    grid-template-columns: repeat(auto-fill, minmax(86px, 1fr));
    max-height: 160px;
  }
  .wp-row {
    flex-wrap: wrap;
  }
  .wp-row select {
    min-width: 0;
    flex: 1;
  }
  .wp-actions {
    flex-wrap: wrap;
  }
  .wp-actions .btn {
    flex: 1;
    min-width: 90px;
  }
}

/* ========== 减少动态效果 ========== */

@media (prefers-reduced-motion: reduce) {
  .wallpaper-layer,
  .wallpaper-slide,
  .wallpaper-layer::after,
  .wallpaper-vignette,
  .wallpaper-tint {
    transition: none;
  }
  .wp-section > summary::after {
    transition: none;
  }
}
