/* ============================================================
   CoRead 全局样式 v1.4 —— 青绿 teal 简约风
   主色 #3EBBA7 + 淡灰底；登录/注册浮窗化；错误提示色统一
   单色图标随文字色；无渐变、无彩色图标、无花哨动效
   ============================================================ */

:root {
  --primary: #3EBBA7;        /* 主题色（青绿 teal）：按钮/链接/选中态，后台可改 */
  --primary-dark: #2F9C8A;   /* 主色加深（hover） */
  --primary-soft: #E6F4F1;   /* 主色浅底（hover/选中/徽章） */
  --primary-line: #C7E7DF;   /* 主色 30% 混白的描边（徽章边框），后台可改 */
  --primary-tint: #F3FBFA;   /* 主色 6% 混白的极浅底（生词行背景），后台可改 */
  --bg: #F4F5F6;             /* 很淡的灰：页面底色，后台可改 */
  --card: #FFFFFF;
  --text: #2F3438;           /* 中性深灰正文 */
  --text-sub: #6B7280;       /* 中性灰次级文字 */
  --border: #E4E7E9;         /* 中性淡边框 */
  --danger: #C4573F;
  --success: #2E9E86;
  --radius: 10px;
  --shadow: 0 1px 3px rgba(60, 80, 90, .06);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; scrollbar-gutter: stable; }

body {
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Noto Sans SC",
               "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
  font-size: 16px; line-height: 1.7; color: var(--text); background: var(--bg);
  min-height: 100vh; display: flex; flex-direction: column;
}

a { color: var(--primary); text-decoration: none; }
a:hover { color: var(--primary-dark); }

.wrap { width: 100%; max-width: 1080px; margin: 0 auto; padding: 0 20px; }
.main { flex: 1; padding: 30px 20px 52px; }

/* ---------- 顶栏 ---------- */
.topbar { background: var(--card); border-bottom: 1px solid var(--border); }
.topbar-in { display: flex; align-items: center; gap: 24px; height: 58px; }
.brand {
  font-size: 20px; font-weight: 700; color: var(--text); letter-spacing: .5px;
}
.brand:hover { color: var(--primary); }
.nav { display: flex; gap: 4px; flex: 1; }
.nav-link {
  padding: 6px 12px; border-radius: 8px; color: var(--text-sub); font-size: 15px;
}
.nav-link:hover { color: var(--primary); background: var(--primary-soft); }
.nav-link.active { color: var(--primary); font-weight: 600; background: var(--primary-soft); }
.userbox { display: flex; align-items: center; gap: 10px; position: relative; }
.user-nick { font-size: 14px; color: var(--text-sub); }

/* ---------- 顶栏会员名二级菜单：帐号信息 / 阅读履历 / 退出登录 ---------- */
.ub-trigger {
  display: inline-flex; align-items: center; gap: 4px;
  background: none; border: none; padding: 6px 8px; border-radius: 8px;
  font-size: 14px; color: var(--text-sub); cursor: pointer;
  transition: background .15s, color .15s;
}
.ub-trigger:hover, .ub-trigger[aria-expanded="true"] { color: var(--primary); background: var(--primary-soft); }
.ub-trigger:focus { outline: 2px solid var(--primary-soft); outline-offset: 2px; }
.ub-caret { font-size: 10px; line-height: 1; }
.ub-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
  width: 168px; max-width: calc(100vw - 24px);
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(60, 80, 90, .14);
  padding: 4px 0; text-align: left;
}
/* 菜单项：链接与按钮（退出登录）共用同一视觉，不做特殊强调 */
.ub-item {
  display: block; width: 100%; text-align: left;
  background: none; border: none; padding: 10px 14px;
  font-size: 14px; line-height: 1.4; color: var(--text);
  text-decoration: none; cursor: pointer;
  transition: background .15s, color .15s;
}
.ub-item:hover { color: var(--primary); background: var(--primary-soft); }
.ub-item:focus { outline: 2px solid var(--primary-soft); outline-offset: -2px; }
.ub-item-form { display: block; margin: 0; }
.ub-item-form + .ub-item, .ub-item + .ub-item-form { border-top: 1px solid var(--border); }

/* ---------- 按钮 ---------- */
.btn {
  display: inline-block; border: 1px solid transparent; border-radius: 8px;
  padding: 8px 16px; font-size: 15px; line-height: 1.4; cursor: pointer;
  background: none; text-align: center; transition: background .15s, color .15s, border-color .15s;
}
.btn-primary { background: var(--primary); color: #fff; }
.btn-primary:hover { background: var(--primary-dark); color: #fff; }
.btn-ghost { border-color: var(--border); color: var(--text); background: var(--card); }
.btn-ghost:hover { border-color: var(--primary); color: var(--primary); }
.btn-sm { padding: 4px 10px; font-size: 13px; border-radius: 6px; }
.btn-block { width: 100%; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

/* ---------- 卡片 ---------- */
.card {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 22px 24px; margin-bottom: 18px;
  box-shadow: var(--shadow);
}
.card-title { font-size: 17px; font-weight: 600; margin-bottom: 12px; }
.muted { color: var(--text-sub); font-size: 14px; margin-bottom: 10px; }
.count { color: var(--text-sub); font-size: 13px; font-weight: 400; margin-left: 4px; }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }

.hero { padding: 10px 0 24px; }
.hero h1 { font-size: 24px; font-weight: 700; margin-bottom: 6px; }
.hero-sub { color: var(--text-sub); font-size: 15px; }

.empty-box {
  border: 1px dashed var(--border); border-radius: var(--radius);
  padding: 28px; text-align: center; color: var(--text-sub); font-size: 14px;
  background: #FBFCFC;
}

/* ---------- 表单 ---------- */
.field { margin-bottom: 16px; }
.field label { display: block; font-size: 14px; color: var(--text-sub); margin-bottom: 6px; }
.req { color: var(--primary); font-weight: 700; }
/* 全站输入框的**标准外观**（单一来源）：.field 里的文本框 / 邮箱 / 密码 / 数字 / 多行文本。
   ⚠️ `type="number"` 原先漏在这个列表里 —— 所以「每个通道每日发信上限」那个数字框
      一直没有边框内边距（2026-09-17 补上）。以后新增输入类型也加到这里。
   ⚠️ 不在 .field 里的输入框（如 .reason-*、.ci-*）**不会**继承这份样式，要单独补。 */
.field input[type="text"],
.field input[type="email"],
.field input[type="password"],
.field input[type="number"],
.field textarea {
  width: 100%; padding: 9px 12px; font-size: 15px; color: var(--text);
  border: 1px solid var(--border); border-radius: 8px; background: var(--card);
  outline: none; transition: border-color .15s, box-shadow .15s;
}
.field input:focus, .field textarea:focus {
  border-color: var(--primary); box-shadow: 0 0 0 3px rgba(62, 187, 167, .15);
}
.field textarea { resize: vertical; min-height: 80px; }
.field textarea::placeholder {
  color: var(--text-sub); opacity: .7; font-size: 14px; line-height: 1.6;
}
.field-hint {
  margin-top: 6px; padding: 8px 12px; background: #F2F4F5;
  border-radius: 8px; font-size: 13px; line-height: 1.6; color: var(--text-sub);
}
/* 登录/注册浮窗内的提示：颜色用主题色（--primary），随管理员设置更改 */
.field-err { color: var(--primary); font-size: 13px; margin-top: 5px; }

/* Honeypot 隐藏（人看不见） */
.honeypot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.auth-wrap { display: flex; justify-content: center; padding-top: 44px; }
.auth-card { width: 100%; max-width: 440px; }
.auth-title { font-size: 21px; font-weight: 700; margin-bottom: 4px; }
.auth-sub { color: var(--text-sub); font-size: 13px; margin-bottom: 18px; line-height: 1.6; }
.auth-alt { margin-top: 14px; font-size: 14px; color: var(--text-sub); text-align: center; }

/* ---------- 注册两步流程（验证邮箱 → 填资料） ---------- */
.auth-steps { display: flex; gap: 8px; list-style: none; margin: 0 0 16px; padding: 0; }
.auth-steps li {
  flex: 1 1 0; text-align: center; font-size: 12px; padding: 6px 8px;
  border-radius: 8px; border: 1px solid var(--border); color: var(--text-sub); background: var(--bg);
}
.auth-steps li.active {
  border-color: var(--primary-line); color: var(--primary-dark);
  background: var(--primary-soft); font-weight: 600;
}
/* 输入框与「发送验证码」按钮同一行 */
.field-row { display: flex; gap: 8px; align-items: stretch; }
.field-row input[type="email"], .field-row input[type="text"] { flex: 1 1 auto; min-width: 0; }
.field-row .btn { flex: 0 0 auto; white-space: nowrap; }
/* 第二步顶部的「已验证邮箱」 */
.auth-verified {
  font-size: 13px; color: var(--text-sub); margin: 0 0 14px;
  padding: 8px 12px; background: var(--primary-soft); border-radius: 8px;
}
.auth-verified strong { color: var(--primary-dark); }

/* ---------- 后台：邮件设置 ---------- */
.mail-ch {
  margin-top: 18px; padding: 14px 16px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--bg);
}
.mail-ch-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
/* .muted 自带 margin-bottom:10px，放进 flex 行会把文字顶偏，必须清零 */
.mail-ch-head .muted { margin: 0; }
.mail-ch-name { font-size: 14px; font-weight: 600; }
.mail-ch-badge {
  font-size: 11px; padding: 1px 8px; border-radius: 999px;
  border: 1px solid var(--border); color: var(--text-sub); background: var(--card);
}
/* ---------- .field 里的复选框行（如后台「注册需要验证邮箱」）----------
   标记与全站其它复选框一致，都用 `.ci-check`（见下方「打卡」那节的 .ci-check 定义，
   含 `input { accent-color: var(--primary); width:15px; height:15px }`）。
   ⚠️ **为什么必须写 `.field label.ci-check` 而不是只靠 `.ci-check`**：
      `.field label` 的特异性是 (0,1,1)，而单类的 `.ci-check` 只有 (0,1,0)
      → 光用 `.ci-check` 会被 `.field label` 盖回 `display:block; color:var(--text-sub)`，
        复选框就变成「块级 + 换行 + 灰色」（2026-09-17 踩过，肉眼看就是"样式没生效"）。 */
.field label.ci-check {
  display: inline-flex; align-items: center; gap: 6px;
  margin-bottom: 0; font-size: 14px; color: var(--text);
}
.mail-ch-badge.on { border-color: var(--primary-line); color: var(--primary-dark); background: var(--primary-soft); }
.mail-ch-badge.off { border-color: var(--danger, #C4573F); color: var(--danger, #C4573F); }
.mail-ch-grid { display: grid; grid-template-columns: 1fr 90px 1fr 1fr; gap: 0 12px; }
.mail-ch-acts { margin-bottom: 8px; }
@media (max-width: 720px) {
  .mail-ch-grid { grid-template-columns: 1fr 1fr; }
}

.notice {
  margin-top: 12px; padding: 10px 14px; background: var(--primary-soft);
  border: 1px solid var(--border); border-radius: 8px; font-size: 14px; color: var(--primary-dark);
}

/* ---------- 提示 ---------- */
.flash {
  padding: 10px 14px; border-radius: 8px; font-size: 14px; margin-bottom: 16px;
}
.flash-ok { background: #EEF5EC; border: 1px solid #CFE0CB; color: var(--success); }
.flash-err { background: #FBEFEB; border: 1px solid #EED2C6; color: var(--danger); }

/* ---------- 表格 ---------- */
.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th, .table td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: top; }
.table th { color: var(--text-sub); font-weight: 600; font-size: 13px; background: #F2F4F5; }
.table tr:last-child td { border-bottom: none; }
.td-bio { color: var(--text-sub); max-width: 260px; }
.td-actions { white-space: nowrap; }
.th-actions { width: 170px; }

.kv { width: 100%; border-collapse: collapse; font-size: 14px; }
.kv th, .kv td { text-align: left; padding: 8px 12px; border-bottom: 1px solid var(--border); }
.kv th { width: 140px; color: var(--text-sub); font-weight: 400; }
.kv tr:last-child td, .kv tr:last-child th { border-bottom: none; }

/* ---------- 角色徽章（中性/teal 系） ---------- */
.role-badge {
  display: inline-block; padding: 2px 9px; border-radius: 12px;
  font-size: 12px; border: 1px solid var(--border); color: var(--text-sub);
}
.role-admin { color: var(--primary-dark); border-color: var(--primary-soft); background: var(--primary-soft); }
.role-senior { color: #4B5563; border-color: #E1E5E8; background: #F2F4F5; }
.role-member { color: var(--text-sub); }
.role-pending { color: #B7791F; border-color: #F0E2C2; background: #FBF3DF; }
.role-superadmin { color: #fff; border-color: var(--primary); background: var(--primary); }
.role-trainee { color: #8A9199; border-color: #E9ECEE; background: #F7F8F9; }

.select-sm { padding: 4px 6px; font-size: 13px; border: 1px solid var(--border); border-radius: 6px; background: var(--card); }
.inline { display: inline; }

/* ---------- 页脚 ---------- */
.footer {
  border-top: 1px solid var(--border); background: var(--card);
  padding: 18px 0; color: var(--text-sub); font-size: 13px;
}

/* ---------- 响应式 ---------- */
@media (max-width: 768px) {
  .grid-2 { grid-template-columns: 1fr; }
  .nav { gap: 0; }
  .user-nick { display: none; }
}
@media (max-width: 576px) {
  .main { padding: 20px 14px 42px; }
  .wrap { padding: 0 14px; }
  .brand { font-size: 18px; }
}

/* ---------- 首页引导按钮组 ---------- */
.hero-cta { margin-top: 18px; display: flex; gap: 10px; }

/* ---------- 登录/注册浮窗 ---------- */
.modal-mask {
  position: fixed; inset: 0; z-index: 100; display: flex;
  align-items: flex-start; justify-content: center;
  background: rgba(30, 40, 45, .45); padding: 8vh 16px 16px;
  overflow-y: auto;
}
.modal-mask[hidden] { display: none; }
.modal {
  background: var(--card); border-radius: 12px; box-shadow: 0 12px 40px rgba(20, 30, 35, .18);
  width: 100%; max-width: 440px; animation: modal-in .18s ease-out;
}
@keyframes modal-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px 0;
}
.modal-title { font-size: 19px; font-weight: 700; }
.modal-close {
  border: none; background: none; font-size: 24px; line-height: 1;
  color: var(--text-sub); cursor: pointer; padding: 2px 6px; border-radius: 6px;
}
.modal-close:hover { color: var(--text); background: var(--primary-soft); }
.modal-body { padding: 8px 20px 20px; }
/* 浮窗内联错误（登录表单级 / 注册字段级），颜色见 .field-err（主题色，随管理员设置更改） */
.form-error { margin: 0 0 14px; }

/* ---------- 错误提示统一色（全站错误文字一律 --danger） ---------- */
.error-text { color: var(--danger); }

/* ============================================================
   阶段 2（M2/M3/M4/M7）：书库 / 书卡 / 分析面板 / 喜欢
   ============================================================ */

/* ---------- 后台快捷操作 ---------- */

/* ---------- 上传预览 ---------- */
.upload-preview { margin: 6px 0 10px; }
.upload-preview:empty { display: none; }
.upload-preview .kv { margin-top: 4px; }

/* ---------- 面包屑 ---------- */
.breadcrumb { font-size: 13px; color: var(--text-sub); margin-bottom: 12px; }
.breadcrumb a { color: var(--primary); text-decoration: none; }
.breadcrumb a:hover { text-decoration: underline; }
.breadcrumb .sep { margin: 0 6px; }
.breadcrumb .bc-current {
  display: inline-block; max-width: 420px; vertical-align: bottom;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---------- 书库筛选 ---------- */
.book-filters .filter-row { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.book-filters .filter-row:last-child { margin-bottom: 0; }
.book-filters { padding-bottom: 12px; border-bottom: 1px solid var(--border); margin-bottom: 12px; }
.filter-label { font-size: 13px; color: var(--text-sub); min-width: 38px; }

/* 全站统一 chip / 按钮三种样式：
   1) 主色填充（.active）：用于当前选中态、主要操作
   2) 中性描边（默认）：用于未选中标签/筛选、默认按钮
   3) 主色描边（.outline-primary）：用于次级操作、轮廓按钮 */
.chip {
  display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 12px;
  border: 1px solid var(--border); color: var(--text-sub); background: var(--card);
  transition: background .15s, color .15s, border-color .15s;
}
.chip:hover { color: var(--primary); border-color: var(--primary); }
.chip.active { background: var(--primary); border-color: var(--primary); color: #fff; }
.chip.outline-primary { border-color: var(--primary); color: var(--primary); }
.chip.outline-primary:hover { background: var(--primary-soft); }

.sort-row { align-items: center; flex-wrap: wrap; }
/* ⚠️ 「上传书籍解析」chip（`.admin-shelf-link`）**刻意不给靠右边距** ——
   它要按 DOM 顺序紧跟在「↑升序 / ↓降序」按钮右侧。
   （这条选择器上原先挂着一条 `margin-left: auto`，那是搜索框还没进排序行、
     这一行只有它一个靠右元素时留下的；两个 auto 边距会平分剩余空间，
     结果它被推到行中段、离升降序按钮很远。2026-09-18 按要求删掉 ——
     行尾现在由 `.sort-row .shelf-search` 的 `margin-left:auto` 独占。） */
.sort-select {
  appearance: none; -webkit-appearance: none;
  padding: 5px 28px 5px 12px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--card) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23999' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 10px center;
  font-size: 13px; color: var(--text); cursor: pointer; min-width: 90px;
}
.sort-select:focus { outline: none; border-color: var(--primary); }
.sort-dir-btn {
  display: inline-flex; align-items: center; gap: 4px;
}

/* ---------- 书库整体块 ---------- */
.bookshelf { padding: 20px 24px 24px; }
.shelf-stats { font-size: 13px; color: var(--text-sub); margin-bottom: 16px; }
.shelf-body { padding: 0 8px; }

/* ---------- 书卡网格 ---------- */
.book-grid {
  display: grid; grid-template-columns: repeat(6, 1fr); gap: 14px;
}
@media (max-width: 1100px) { .book-grid { grid-template-columns: repeat(5, 1fr); } }
@media (max-width: 920px) { .book-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 720px) { .book-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 520px) { .book-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 360px) { .book-grid { grid-template-columns: 1fr; } }

/* ⚠️ 必须显式写这一条：`.book-card` 自己有 `display:flex`，光靠 `hidden` 属性盖不住它
   （本站没有全局的 `[hidden]{display:none}`）。书库页的搜索过滤 / 分页就是靠它隐藏卡片的。 */
.book-grid > .book-card[hidden] { display: none; }

/* ---------- 书库页：动态搜索（放在排序行最右侧） ----------
   视觉**完全复用**上面「词频列表」那一段的 `.search`（书籍词汇列表页的搜索框就是它），
   这里只覆盖三件事：靠右推、固定宽度、去掉 `.search` 自带的上下外边距（排序行里要与其它元素同高）。 */
.sort-row .shelf-search {
  margin: 0 0 0 auto;                /* 推到整行最右边；压掉 .search 的 6px/10px 上下外边距 */
  width: 200px; max-width: 100%;
  flex: 0 1 auto;
}

/* ---------- 书库页：分页条 ---------- */
.shelf-pager {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 8px; margin-top: 20px;
}
.shelf-pager[hidden] { display: none; }
.shelf-pager .pg-num {
  min-width: 32px; height: 32px; padding: 0 8px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--card); color: var(--text);
  font-size: 14px; cursor: pointer;
}
.shelf-pager .pg-num:hover { border-color: var(--primary); color: var(--primary); }
.shelf-pager .pg-num.active {
  background: var(--primary); border-color: var(--primary); color: #fff; cursor: default;
}
.shelf-pager .pg-gap { color: var(--text-sub); }
.shelf-pager .pg-info { margin-left: 4px; font-size: 13px; color: var(--text-sub); }

/* 搜索无结果的提示（显隐由 JS 控制） */
#shelf-empty[hidden] { display: none; }

.book-card {
  background: var(--card); border: 1px solid var(--border); border-radius: 10px;
  overflow: hidden; display: flex; flex-direction: column; box-shadow: var(--shadow);
  transition: border-color .15s, transform .15s;
}
.book-card:hover { border-color: var(--primary); transform: translateY(-2px); }
.book-cover {
  display: block; position: relative; aspect-ratio: 2 / 3; background: #EEF1F2; overflow: hidden;
}
.book-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.book-cover-ph {
  width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;
  font-size: 32px; color: #B6C2C5; background: linear-gradient(180deg, #F2F5F6, #E7ECEE);
}
.book-body { padding: 10px 11px 12px; display: flex; flex-direction: column; gap: 5px; flex: 1; }
.book-title { font-size: 14px; font-weight: 600; line-height: 1.35; }
.book-title a { color: var(--text); }
.book-title a:hover { color: var(--primary); }
.book-author { font-size: 12px; color: var(--text-sub); margin: 0; }
.book-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.book-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.book-foot {
  margin-top: auto; padding-top: 5px;
  display: flex; align-items: center; gap: 12px;
}

/* ---------- 蓝思 / 共读徽章 ---------- */
.lexile-badge {
  display: inline-block; padding: 2px 9px; border-radius: 12px; font-size: 12px;
  background: var(--primary-soft); color: var(--primary-dark); font-weight: 600;
}
.lexile-badge.big { font-size: 15px; padding: 4px 14px; border-radius: 16px; }
/* 共读卡的「总词汇数k/词汇量」数值标签（如 96.2k/4920）：与难度徽章同排在 .book-meta 里。
   ⚠️ 用**中性灰底**而不是 --primary-soft —— 蓝思徽章已经占了主题色，再用主题色两个徽章会分不清。
   tabular-nums 让数字等宽，多张卡片并排时不会因字形宽度跳动。 */
.word-stat {
  display: inline-block; padding: 2px 9px; border-radius: 12px; font-size: 12px;
  background: var(--bg); color: var(--text-sub); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.status-badge {
  display: inline-block; padding: 2px 9px; border-radius: 12px; font-size: 12px; font-weight: 600;
  /* ⚠️ 必须 nowrap：中文（CJK）没有空格也能断行，窄卡里「本期共读」会被 flex 压成两行（"本期"/"共读"）。 */
  white-space: nowrap;
}
.status-hidden, .status-locked { background: #FBEFEB; color: #C4573F; border: 1px solid #F0C9BD; }
/* 共读徽章：跟随后台主题色（浅底/描边由 PHP 派生） */
.status-coreading { background: var(--primary-soft); color: var(--primary-dark); border: 1px solid var(--primary-line); }

/* ---------- 标签 chip（统一中性灰，与全站 chip 风格一致） ---------- */
.tag-chip {
  display: inline-block; padding: 1px 7px; border-radius: 10px; font-size: 11px;
  color: var(--text-sub); border: 1px solid var(--border); background: var(--card);
}

/* ---------- 后台「标签管理」：一行能放多少放多少（自动换行），点击 chip 即删 ---------- */
.tag-manage { display: flex; flex-wrap: wrap; gap: 8px; }
/* 每颗 chip 外面套了一个 <form>（为了带 CSRF + 隐藏字段）。form 是 flex 项、宽度由内容决定，
   所以视觉上就是「一颗颗 chip」，不需要给它任何盒模型。 */
.tag-manage .tag-del-form { display: flex; }
/* ⚠️ <button> 不继承字体，必须显式 font-family: inherit，否则会掉回系统默认字体（与全站不一致）。 */
.tag-del {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: inherit; font-size: 13px; line-height: 1.6;
  padding: 3px 10px; border-radius: 12px; cursor: pointer;
  color: var(--text); background: var(--bg); border: 1px solid var(--border);
  transition: color .15s, border-color .15s, background .15s;
}
/* hover 用**危险色**预告「这一下是删除」，避免误点（真正的确认走站点风格弹窗） */
.tag-del:hover, .tag-del:focus-visible {
  color: var(--danger, #C4573F); border-color: currentColor; background: #FBEDEA;
}
.tag-use {
  font-size: 12px; font-weight: 600; color: var(--text-sub);
  font-variant-numeric: tabular-nums;     /* 次数等宽，多行时右侧不跳 */
}
.tag-del:hover .tag-use { color: inherit; }

/* ---------- 喜欢按钮 ---------- */
.like-btn {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer; user-select: none;
  font-size: 14px; color: var(--text-sub); transition: color .15s;
}
.like-btn:hover { color: var(--primary); }
.like-btn .heart { font-size: 16px; line-height: 1; }
.like-btn.liked { color: var(--primary); }
.like-btn.liked .heart { color: var(--primary); }
.like-btn.busy { opacity: .6; pointer-events: none; }
.like-btn:focus { outline: 2px solid var(--primary-soft); outline-offset: 2px; border-radius: 6px; }

/* ---------- 评论按钮（与喜欢按钮风格统一） ---------- */
.comment-btn {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 14px; color: var(--text-sub); text-decoration: none;
  transition: color .15s;
}
.comment-btn:hover { color: var(--primary); }
.comment-btn .bubble { display: inline-block; width: 16px; height: 16px; vertical-align: middle; }

/* ---------- 在读人数（与喜欢/评论同一风格；目前只在首页「本期共读」用） ---------- */
.readers-num {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 14px; color: var(--text-sub);
}
/* 它是 <a>（点了去该书打卡标签）。全局 a{color:var(--primary)} 的特异性低于 .readers-num，
   所以上面那行灰字会胜出 —— 但 hover 要显式补上，才会和 .like-btn / .comment-btn 一致。 */
.readers-num:hover { color: var(--primary); }
.readers-num .user { display: inline-block; width: 16px; height: 16px; vertical-align: middle; }

/* ---------- 管理按钮（与喜欢/评论风格统一，仅管理员可见） ---------- */
.manage-btn {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 14px; color: var(--text-sub); background: none; border: none; padding: 0;
  cursor: pointer; transition: color .15s; font-family: inherit;
}
.manage-btn:hover { color: var(--primary); }
.manage-btn .ic { width: 16px; height: 16px; vertical-align: middle; }
.manage-btn:focus { outline: 2px solid var(--primary-soft); outline-offset: 2px; border-radius: 6px; }

/* ---------- 书籍管理浮窗内部 ---------- */
.manage-sec { padding: 14px 0; border-bottom: 1px solid var(--border); }
.manage-sec:last-of-type { border-bottom: none; }
.manage-sec-title { font-size: 13px; color: var(--text-sub); font-weight: 600; margin-bottom: 8px; }
.manage-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; padding-top: 16px; }
.manage-actions .btn { margin: 0; }
.manage-hint { font-size: 12px; color: var(--text-sub); margin: 8px 0 0; line-height: 1.6; }
.manage-msg { font-size: 13px; margin-top: 10px; padding: 8px 10px; border-radius: 8px; }
.manage-msg.ok { color: var(--primary-dark); background: var(--primary-soft); }
.manage-msg.err { color: #C4573F; background: #FBEFEB; }
.btn.danger { background: #C4573F; border-color: #C4573F; color: #fff; }
.btn.danger:hover { background: #AD4A34; border-color: #AD4A34; }

/* 已选标签 */
.mb-selected-tags { display: flex; flex-wrap: wrap; gap: 8px; min-height: 28px; margin-bottom: 10px; align-items: center; }
.mb-tag-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: 10px; font-size: 12px;
  color: var(--text-sub); border: 1px solid var(--border); background: var(--card);
}
.mb-tag-chip.selected { padding-right: 5px; }
.mb-tag-remove {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 50%; border: none; background: transparent;
  color: inherit; font-size: 14px; line-height: 1; cursor: pointer; padding: 0;
}
.mb-tag-remove:hover { background: rgba(0,0,0,.08); color: var(--text); }
.mb-tag-input {
  width: 100%; padding: 8px 12px; border: 1px solid var(--border); border-radius: 10px;
  font-size: 14px; background: var(--card); color: var(--text);
}
.mb-tag-input:focus { outline: 2px solid var(--primary-soft); border-color: var(--primary); }

/* ---------- 可点星级控件（豆瓣式）----------
   两处共用同一套字形与状态规则，只由各自的容器决定字号：
     · 管理浮窗的「推荐度」  → .mb-star（22px，点完等「完成」才提交）
     · 「我的共读」的「我的评分」→ .rate-star（16px，点完**立即**提交）
   ⚠️ 每颗星里预置 ☆ / ★ 两个字形，**只切 .on 类**（CSS 决定显隐）——
      JS 不去改 textContent，免得和字形/编码纠缠。
   ⚠️ <button> 不继承字体/颜色 → 必须显式声明，否则字号会掉回浏览器默认。 */
.mb-rating, .rate-stars { display: flex; align-items: center; gap: 2px; }
.mb-star, .rate-star {
  background: none; border: none; padding: 0 1px; cursor: pointer;
  font-family: inherit; font-weight: 400; line-height: 1;
  color: var(--border-strong, #C9CFD2);
}
.mb-star .s-on, .rate-star .s-on { display: none; }
.mb-star.on .s-on, .rate-star.on .s-on { display: inline; }
.mb-star.on .s-off, .rate-star.on .s-off { display: none; }
/* 点亮 = 主题色（与全站强调色一致，不用金色 —— 站上只有青绿一个强调色） */
.mb-star.on, .rate-star.on { color: var(--primary); }
.mb-star:focus-visible, .rate-star:focus-visible {
  outline: 2px solid var(--primary-soft); outline-offset: 1px; border-radius: 4px;
}
.mb-star { font-size: 22px; }
.rate-star { font-size: 16px; }
.mb-rating-text, .rate-text { margin-left: 10px; font-size: 13px; color: var(--text-sub); }

/* ---------- 「我的共读」列表里的「我的评分」（仅本人可见）----------
   `.rate-form` 由 render_my_rating() 渲染，包着隐藏 input + 星级；
   点星由 JS 写值后 dispatch submit，走全站 form[data-ajax] 拦截器（没有提交按钮）。
   ⚠️ 列表项本身已有上下间距（.mr-item padding 12px + .mr-prog margin-top 10px），
      这里只给一点点，免得那一块空隙被撑得太大。 */
.rate-form { margin-top: 6px; }
.rate-label { font-size: 12px; color: var(--text-sub); margin-right: 8px; }
/* AJAX 出错时 errBox() 会往 form 里插一个 .field-err.ajax-err（它是 form 的第一个子节点），
   在列表里会是星星**上方**一行小字 —— 不给额外样式，沿用全站 .field-err。 */

/* 书籍标题输入 */
.mb-title {
  width: 100%; padding: 8px 12px; border: 1px solid var(--border); border-radius: 10px;
  font-size: 14px; background: var(--card); color: var(--text);
}
.mb-title:focus { outline: 2px solid var(--primary-soft); border-color: var(--primary); }

/* 全部标签云 */
.mb-tag-cloud { display: flex; flex-wrap: wrap; gap: 8px; }
.mb-tag-chip.cloud {
  cursor: pointer; user-select: none; transition: transform .08s, box-shadow .15s, background .15s, color .15s, border-color .15s;
  background: var(--card); border: 1px solid var(--border); color: var(--text);
}
.mb-tag-chip.cloud:hover { border-color: var(--primary); color: var(--primary); }
.mb-tag-chip.cloud.active {
  background: var(--primary); border-color: var(--primary); color: #fff;
}

/* 状态单选 */
.mb-status-group { display: flex; flex-wrap: wrap; gap: 10px; }
.radio-chip {
  display: inline-flex; align-items: center; cursor: pointer; user-select: none;
}
.radio-chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.radio-chip span {
  display: inline-block; padding: 5px 14px; border-radius: 16px; font-size: 13px;
  border: 1px solid var(--border); color: var(--text-sub); background: var(--card);
  transition: background .15s, color .15s, border-color .15s;
}
.radio-chip input:checked + span {
  background: var(--primary); border-color: var(--primary); color: #fff;
}
.radio-chip:hover span { color: var(--primary); border-color: var(--primary); }
.radio-chip input:checked:hover + span { color: #fff; }

/* 简介输入 */
.mb-desc {
  width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px;
  font-size: 14px; line-height: 1.7; background: var(--card); color: var(--text);
  resize: vertical; min-height: 80px;
}
.mb-desc:focus { outline: 2px solid var(--primary-soft); border-color: var(--primary); }

/* modal 宽度适配新内容 */
#modal-book-manage .modal { width: min(520px, 92vw); }

/* ---------- 书籍详情 + 分析面板 ---------- */
.book-detail { max-width: 1080px; }
.back-link { display: inline-block; font-size: 14px; color: var(--text-sub); margin-bottom: 16px; }
.back-link:hover { color: var(--primary); }
/* 书籍头部：整块白卡（宽度与下方书评卡一致）
   内部：书名 / 作者 → [封面 | 第一行 喜欢+徽章+标签 / 第二行 难度·总词汇·词汇量 / 第三行 简介] */
.book-head { display: block; margin-bottom: 18px; }
.bh-top { margin-bottom: 14px; }
.bh-top .book-title { font-size: 24px; margin-bottom: 0; }
/* 作者跟在书名后，斜杠分隔 */
.bh-top .book-author {
  font-size: 15px; font-weight: 400; color: var(--text-sub);
  margin-left: 2px;
}
.bh-main { display: flex; gap: 24px; align-items: flex-start; }
.book-cover-lg {
  width: 160px; flex: 0 0 160px; aspect-ratio: 2 / 3; border-radius: 10px; overflow: hidden;
  background: #EEF1F2; border: 1px solid var(--border);
}
.book-cover-lg img { width: 100%; height: 100%; object-fit: cover; display: block; }
.book-cover-lg .book-cover-ph { font-size: 52px; }
.book-like-row { display: flex; align-items: center; gap: 8px; }

/* 封面右侧信息列：三行（喜欢+徽章+标签 / 数据统计 / 简介） */
.bh-side { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 12px; }
.bh-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.bh-row .book-tags { margin-bottom: 0; }
/* 数据统计行：难度 / 638L   总词汇 / 6,576   词汇量 / 2,527 */
.bh-stats { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 22px; }
.bh-stat { display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap; }
.bh-k { font-size: 13px; color: var(--text-sub); }
.bh-sl { font-size: 13px; color: var(--border-strong, #C9CFD2); }
.bh-v { font-size: 16px; font-weight: 600; color: var(--text); }
/* ⚠️ .bh-stat 是 display:inline-flex → **会盖过 UA 的 [hidden]{display:none}**
   （同为 0-1-0 特异性，作者样式在 UA 之后）→ 未评分时那一项收不起来，必须显式补这条。
   这是本项目第三次踩「自己写的 display 盖掉 [hidden]」（另两处：.btn / .desc-short）。 */
.bh-stat[hidden] { display: none; }
/* 详情页的「评价」星级（豆瓣式）：实心 ★ 用主题色，空心 ☆ 用弱灰。
   ⚠️ 字号比 .bh-v（16px）大一点、字重 400 —— 星星要看得清，且不要因为 600 字重显得笨重。 */
.stars { font-size: 17px; font-weight: 400; letter-spacing: 1px; color: var(--primary); }
/* 书卡上的「推荐度」：书卡内宽只有约 140px，17px 五颗星放不下 → 收一档、去掉字距。
   ⚠️ 必须排在 .stars **之后**（同为单类选择器，靠顺序覆盖）。 */
.stars-sm { font-size: 11px; letter-spacing: 0; }
.book-head .book-desc {
  font-size: 15px; line-height: 1.8; color: var(--text); margin-top: 0;
  white-space: pre-line;   /* 段落换行要保留 —— 与共读卡 .pick-desc 口径一致（2026-09-17 要求） */
}
@media (max-width: 820px) {
  .bh-main { flex-direction: column; }
  .bh-side { flex: 1 1 auto; }
}
@media (max-width: 820px) {
  .bh-main { flex-direction: column; }
  .book-vocab { flex: 1 1 auto; }
}

.panel-sub { font-size: 15px; font-weight: 600; margin: 20px 0 10px; }

/* ---------- 统计行 ---------- */
.stat-row { display: flex; flex-wrap: wrap; gap: 12px; }
.stat {
  flex: 1; min-width: 96px; background: #FBFCFC; border: 1px solid var(--border);
  border-radius: 8px; padding: 12px 14px; text-align: center;
}
.stat b { display: block; font-size: 20px; color: var(--primary-dark); }
.stat span { font-size: 12px; color: var(--text-sub); }

/* ========== 柯林斯分级配色（固定调色板，不随主题变动） ========== */
:root{
  --b5:#5b9bd5; --b4:#7ecce7; --b3:#7cc576; --b2:#f5d76e; --b1:#f4a582; --b0:#d7b8e8; --bp:#f4a6c3;
}
/* 字号三档的**基数**（=「我的设置 → 字号设置」里的「中」）：
     --ep-word 单词（词汇列表 + 弹层词头）／--ep-def 词典释义／--ep-ex 例句。
   设置页把这三个变量写到 <html> 的行内 style 上覆盖它（存在浏览器 localStorage）。
   ⚠️ 必须定义在 html 而不是 body —— 页面 <head> 里的内联脚本只能拿到 <html>；
      写在 body 上的话，会盖不住 body 自己那条声明。 */
html{ --ep-word:15px; --ep-def:14px; --ep-ex:14px; }

/* ---------- 分级堆叠条 + 图例（还原原始站 buildBar/buildLegend） ---------- */
.bar{ display:flex; height:8px; border-radius:6px; overflow:hidden; margin:10px 0 6px; background:#eee; }
.bar > span{ height:100%; }
.legend{ display:flex; flex-wrap:wrap; gap:8px 14px; font-size:11.5px; color:var(--text-sub); margin-top:4px; }

.legend i{ display:inline-block; width:9px; height:9px; border-radius:2px; margin-right:4px; vertical-align:middle; }

/* ---------- 分级标签（全部 + 各星级） ---------- */
.tabs{ display:flex; gap:4px; overflow-x:auto; padding:2px 0 10px; -webkit-overflow-scrolling:touch; }
/* 分级筛选标签：尺寸 = 下方「我的词表」按钮（.wf-btn）；未选中 = 灰底淡边框，选中 = 实心主题色，悬停 = 浅主色底 */
.tab{
  flex:0 0 auto; padding:3px 12px; border-radius:999px; font-size:13px; font-weight:600;
  color:var(--text-sub); border:1px solid var(--border); background:var(--card);
  cursor:pointer; white-space:nowrap; transition:background .15s, color .15s, border-color .15s;
}
.tab:hover{ color:var(--primary); background:var(--primary-soft); border-color:var(--primary); }
.tab.active{ background:var(--primary); border-color:var(--primary); color:#fff; font-weight:600; }
.tab.active:hover{ background:var(--primary); border-color:var(--primary); color:#fff; }

/* ---------- 书籍详情：书评 / 打卡 / 词汇 标签页 ---------- */
.book-tabs {
  display: flex; gap: 8px; margin: 4px 0 16px;
  border-bottom: 1px solid var(--border);
}
.book-tab {
  appearance: none; background: transparent; border: none; cursor: pointer;
  text-decoration: none;
  padding: 9px 14px; font-size: 14px; color: var(--text-sub);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color .15s, border-color .15s;
}
.book-tab:hover { color: var(--primary); }
.book-tab.active {
  color: var(--primary); border-bottom-color: var(--primary); font-weight: 600;
}
.book-tab-count {
  font-size: 13px; color: var(--text-sub); font-weight: 400; margin-left: 2px;
}
.book-tab.active .book-tab-count { color: inherit; }
.book-tab-panel[hidden] { display: none; }

/* ---------- 我的词表过滤行 ---------- */
.mfilter{ display:flex; align-items:center; gap:8px; padding:2px 0 8px; flex-wrap:wrap; }\n/* 词频筛选行（说明文字 + 分级标签）：替代原「词汇列表」小标题，与上方图例留出间距 */\n.vfilter{ margin-top:12px; }\n.vfilter .tabs{ flex:1 1 auto; min-width:0; padding:0; }
.mfilter .mlabel{ font-size:13px; color:var(--text-sub); font-weight:600; }
/* 我的词表按钮：未选中/选中/悬停表现与词频筛选标签（.tab）一致，尺寸保持原样（padding 6px 13px） */
.wf-btn{ padding:6px 13px; border-radius:999px; cursor:pointer; font-size:13px; font-weight:600;
  white-space:nowrap; color:var(--text-sub); border:1px solid var(--border); background:var(--card);
  transition:background .15s, color .15s, border-color .15s, transform .1s; }
.wf-btn:hover{ color:var(--primary); background:var(--primary-soft); border-color:var(--primary); }
.wf-btn.active{ background:var(--primary); border-color:var(--primary); color:#fff; }
.wf-btn.active:hover{ background:var(--primary); border-color:var(--primary); color:#fff; }
.wf-btn:active{ transform:scale(.97); }
.wf-btn:disabled{ opacity:.45; cursor:default; transform:none; }
.wf-btn.nw-del{ background:#fde8e8; color:#c0392b; }
.wf-btn.nw-del:hover:not(:disabled){ background:#f9d6d6; }

/* ---------- 分页 ---------- */
.pager{ display:flex; align-items:center; justify-content:center; gap:6px; padding:16px 0 4px; flex-wrap:wrap; }
.pager button{ min-width:36px; height:36px; padding:0 9px; border-radius:9px; border:1px solid var(--border);
  background:#fff; color:var(--text); font-size:13px; cursor:pointer; transition:background .15s; }
.pager button.active{ background:var(--primary); color:#fff; border-color:var(--primary); }
.pager button:disabled{ opacity:.45; cursor:default; background:#fff; }
.pager .pg-info{ font-size:12px; color:var(--text-sub); margin:0 4px; }

/* ---------- 词频列表 ---------- */
/* ⚠️ `-webkit-appearance:none` 是**刻意**的：Safari 会给 `input[type=search]` 加一个左置放大镜
   （Chrome 不显示，所以只在 Safari 上看得出来 —— 别以为是自己加的背景图）。
   书籍词汇列表页与书库页两个搜索框**共用这一条**，外观才完全一致。 */
.search{ width:100%; padding:10px 12px; border:1px solid var(--border); border-radius:10px; font-size:14px; margin:6px 0 10px; background:#fbfcfd;
  -webkit-appearance:none; appearance:none; }
/* 有些 WebKit 版本光靠 appearance:none 不够，再把放大镜那两个伪元素显式清掉 */
.search::-webkit-search-decoration, .search::-webkit-search-results-decoration{ -webkit-appearance:none; }
.word{ display:flex; align-items:flex-start; gap:10px; padding:9px 4px; border-bottom:1px solid var(--border); }
.word .w{ flex:1; min-width:0; }
.word .wtext{ font-weight:600; font-size:var(--ep-word); line-height:1.45; }
.word .ipa{ color:#9AA3AC; font-weight:400; font-size:var(--ep-word); margin-left:10px; }
/* 列表行内的小星级（书籍词汇列表 / 生词本共用）：跟在音标后面，灰色弱化、不抢词头。
   ⚠️ 与弹层里的 `.wm-stars`（主题色 + 补满五格）**不是同一个东西**：
      列表只给柯林斯 1~5 星的词显示 n 颗星、**不补空星**，其余一律不显示。 */
.w-star{ color:#C2C8CE; font-size:calc(var(--ep-word)*0.65); letter-spacing:0.5px; margin-left:4px;
  display:none; }   /* ⚠️ **默认不显示**：开关在「我的设置 → 词典设置」 */
/* ⚠️ 刻意比同一行里的音标（`.word .ipa` 用 **#9AA3AC**、字号 = --ep-word）**更淡更小**：
      星级只是个弱化提示，不能抢词头，也不能跟音标抢视觉重量。
      ⚠️⚠️ 调星级时**只改上面这条**，别顺手动 `.word .ipa` —— 用户明确要求音标保持不变。 */
/* 开关打开后由 <html> 上的 `.stars-on` 放行（见 layout.php 的 window.CoReadStars）。
   ⚠️ 用 CSS 类做闸门而不是让列表各自判断：生词本首屏是 PHP 渲染的，
      JS 事后删 DOM 会闪；类闸门对三处列表一次生效、切换瞬时。 */
html.stars-on .w-star{ display:inline; }
/* 词头后面附的「不规则变形 + 次数」（如 was 770 · were 173）。规则变形不列。
   每个变形可单独点击查看它自己的释义。 */

.word .wforms{ display:block; margin-top:2px; font-size:11.5px; font-weight:400; line-height:1.5;
  color:var(--text-sub); word-break:break-word; }
.word .wform{ cursor:pointer; border-bottom:1px dotted var(--border); padding-bottom:1px; }
.word .wform:hover{ color:var(--primary); border-bottom-color:var(--primary); }
.word.ignored .wforms{ text-decoration:line-through; }
.word .cnt-link{ color:var(--primary); font-weight:600; cursor:pointer; text-decoration:underline dotted; }
.word .def{ font-size:var(--ep-def); line-height:1.8; color:#3a3f47; margin-top:3px; }
.word .def .src{ color:var(--text-sub); font-size:11px; margin-right:4px; }
.word .cnt{ font-size:12px; color:var(--text-sub); min-width:46px; text-align:right; flex-shrink:0; }
.word .mas{ display:flex; align-items:center; gap:5px; flex-shrink:0; font-size:12px; color:var(--text-sub); cursor:pointer; user-select:none; }
.word .mas input{ width:15px; height:15px; flex-shrink:0; margin:0; accent-color:var(--primary); }
.word .mas span{ white-space:nowrap; }
.word .mas.newword{ color:var(--primary-dark); }
.word .mas.newword input:checked{ accent-color:var(--primary); }
.word.newword{ background:var(--primary-tint); border-radius:8px; }
.word.ignored .wtext{ color:var(--text-sub); text-decoration:line-through; }
.dot{ display:inline-block; width:8px; height:8px; border-radius:50%; margin-right:5px; }
.loading{ text-align:center; color:var(--text-sub); padding:18px; font-size:13px; }

/* ---------- 单词释义弹层（还原原始站 ensureWordModal 样式） ---------- */
.wm-mask{ position:fixed; inset:0; background:rgba(15,20,28,.45); z-index:100; }
.wm-card{ position:fixed; left:50%; top:50%; transform:translate(-50%,-50%); width:min(560px,calc(100vw - 32px));
  max-height:82vh; overflow-y:auto; background:#fff; border-radius:16px; box-shadow:0 12px 40px rgba(0,0,0,.22);
  z-index:101; font-size:14px; color:#1f2329; }
.wm-head{ display:flex; align-items:center; gap:10px; padding:14px 18px; border-bottom:1px solid var(--border);
  position:sticky; top:0; background:#fff; z-index:2; }
.wm-word{ font-size:calc(var(--ep-word)*1.5); font-weight:700; color:#1f2329; }
.wm-stars{ color:var(--primary); font-size:calc(var(--ep-word)*0.95); letter-spacing:2px; margin-left:4px; }
.wm-ipa{ color:#0d7377; font-size:calc(var(--ep-word)*0.9); margin-left:6px; }
.wm-meta{ font-size:12px; color:var(--text-sub); padding:12px 18px 0; }
.wm-ignore{ margin-left:auto; display:inline-flex; align-items:center; gap:5px; font-size:12.5px; color:var(--text-sub); white-space:nowrap; cursor:pointer; user-select:none; }
.wm-newword{ margin-left:10px; display:inline-flex; align-items:center; gap:5px; font-size:12.5px; color:var(--primary-dark); white-space:nowrap; cursor:pointer; user-select:none; }
.wm-x{ border:none; background:#eef1f5; width:36px; height:36px; border-radius:50%; font-size:18px; cursor:pointer; color:var(--text); flex-shrink:0; margin-left:auto; }
.def-tabs{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; padding:12px 18px 0; border-bottom:1px solid var(--border); }
.def-tab{ border:1px solid transparent; background:#eef1f5; color:var(--text); font-size:12.5px; font-weight:600; padding:6px 14px; border-radius:999px; cursor:pointer; }
.def-tab.active{ background:#fff; color:var(--text); border-color:var(--border); }
/* 词典标签与「本书例句」之间的竖线分隔 */
.def-sep{ color:var(--border); font-weight:300; user-select:none; }
.def-panel{ display:block; }
.def-panel.hidden{ display:none; }
.wm-body{ padding:4px 18px 18px; }
.collins-summary{ background:#f0f4f8; border-radius:12px; padding:12px 14px; font-size:calc(var(--ep-def)*1.2); line-height:1.7; color:#2a3f54; margin:10px 0 14px; }
.sense{ margin:14px 0; padding-bottom:10px; border-bottom:1px solid #f0f2f5; }
.sense:last-child{ border-bottom:none; padding-bottom:0; }
.sense-hd{ display:flex; align-items:baseline; gap:8px; margin-bottom:4px; flex-wrap:wrap; }
.sense-no{ font-size:calc(var(--ep-word)*1.05); font-weight:700; color:#2b5bbf; line-height:1; min-width:22px; }
.sense-pos{ font-size:calc(var(--ep-def)*1.05); color:#9f3b34; font-weight:600; font-style:italic; }
.sense-cn{ font-size:calc(var(--ep-def)*0.95); color:#4a5568; }
.sense-cnshort{ display:inline; font-size:calc(var(--ep-def)*1.1); font-weight:600; color:#2b5bbf; margin-left:6px; }
.sense-def{ font-size:var(--ep-def); line-height:1.65; color:#1f2937; margin:6px 0 10px; }
.sense-ex{ display:flex; gap:8px; margin:8px 0 6px; padding-left:2px; }
.sense-ex .dot{ color:#9aa0a6; font-size:calc(var(--ep-ex)*1.05); line-height:1.6; flex-shrink:0; }
.ex-en{ display:inline; font-size:var(--ep-ex); line-height:1.65; color:#2d3748; }
.ex-cn{ display:inline; font-size:calc(var(--ep-ex)*0.95); line-height:1.65; color:#718096; margin-left:4px; }
.oxford-hd{ display:flex; align-items:baseline; gap:10px; margin:12px 0 14px; }
.oxford-word{ font-size:calc(var(--ep-word)*1.6); font-weight:700; color:#c0392b; }
.oxford-pos{ background:#c0392b; color:#fff; font-size:12px; padding:3px 10px; border-radius:999px; font-weight:600; }
.sense-cn-ox{ color:#c0392b; font-size:13.5px; font-weight:500; }
.sense-ex.ox .ex-en{ color:#0d7377; }
.sense-ex.ox .ex-cn{ color:#c0392b; }
.oxford-note{ background:#fbf4f2; border:1px solid #f0dcd6; border-radius:10px; padding:10px 12px; margin-top:14px; }
.oxford-note-hd{ font-size:12.5px; font-weight:700; color:#c0392b; margin-bottom:4px; }
.oxford-note-body{ font-size:calc(var(--ep-def)*0.95); line-height:1.7; color:#6b4a44; }
.blk-line{ margin:5px 0; line-height:1.65; }
.blk-en{ color:#6b4a44; }
.blk-cn{ color:#9c6a5f; }
.word-hl{ font-weight:600; text-decoration:underline dotted; text-underline-offset:2px; }
.wm-missing{ color:#9aa0a6; font-size:13px; padding:12px 0; }
.ex-meta{ font-size:calc(var(--ep-ex)*0.85); color:var(--text-sub); margin:10px 0 4px; }
.ex{ font-size:var(--ep-ex); line-height:1.75; color:#2a2f36; padding:7px 2px; border-bottom:1px solid #f0f2f5; }
.ex mark{ background:#ffe58f; color:#1f2329; padding:0 2px; border-radius:3px; font-weight:600; }

/* ============================================================
   阶段 3：共读 / 打卡 / 评论
   ============================================================ */

/* ---------- 通用补充（btn 别名 / 小字号 / 徽章） ---------- */
.btn.primary { background: var(--primary); color: #fff; }
.btn.primary:hover { background: var(--primary-dark); color: #fff; }
.btn.ghost { border-color: var(--border); color: var(--text); background: var(--card); }
.btn.ghost:hover { border-color: var(--primary); color: var(--primary); }
.btn.sm { padding: 4px 10px; font-size: 13px; border-radius: 6px; }
.sm { font-size: 13px; }

.sub-title { font-size: 14px; font-weight: 600; color: var(--text); margin: 16px 0 8px; }
/* 标题后的小字开关：展开/折叠饼图 */
.pie-toggle{ margin-left:8px; padding:0; border:none; background:none; cursor:pointer;
  font-size:12px; font-weight:400; color:var(--text-sub); transition:color .15s; }
.pie-toggle:hover{ color:var(--primary); }

.badge {
  display: inline-block; padding: 1px 8px; border-radius: 10px;
  font-size: 12px; line-height: 1.6; font-weight: 500; vertical-align: middle;
  background: #EFF1F2; color: var(--text-sub);
}
.badge.done { background: #E2F3EE; color: var(--success); }
/* 「已读完」徽章现在是**链接**（共读卡上点击直达该书打卡标签）→ 补 hover 反馈，否则看不出能点。
   ⚠️ 必须比 .badge.done 更具体（a.badge.done:hover），否则被上面那条压住。 */
a.badge.done:hover { background: #D2EDE5; color: var(--success); }
.badge.paused { background: #F6F1E4; color: #9A7B3F; }
.badge.adm { background: var(--primary-soft); color: var(--primary-dark); }
.badge.band,
.badge.prog { background: var(--primary-soft); color: var(--primary-dark); }

/* ---------- 共读头部（人数 / 进度 / 加入退出） ---------- */
.rd-head { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.rd-stat { display: flex; align-items: baseline; gap: 6px; }
.rd-num { font-size: 26px; font-weight: 700; color: var(--primary); line-height: 1.1; }
.rd-unit { font-size: 13px; color: var(--text-sub); }
.rd-prog { flex: 1; min-width: 200px; }
.rd-tip { font-size: 13px; color: var(--text-sub); flex: 1; min-width: 200px; }
.rd-act { margin-left: auto; }

.prog-bar {
  height: 10px; background: #EDF0F1; border-radius: 6px; overflow: hidden;
}
.prog-fill {
  height: 100%; background: var(--primary); border-radius: 6px;
  transition: width .3s ease; min-width: 2px;
}
.prog-meta { display: flex; align-items: center; gap: 10px; margin-top: 6px; flex-wrap: wrap; }
.prog-meta .muted { margin: 0; }
.prog-pct { font-size: 14px; font-weight: 600; color: var(--text); }

/* ---------- 打卡表单 ---------- */
.ci-form {
  margin-top: 16px; padding-top: 16px;
  border-top: 1px dashed var(--border);
}
.ci-row { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.ci-row.col { flex-direction: column; align-items: stretch; }
.ci-label { flex: 0 0 86px; font-size: 14px; color: var(--text-sub); }
.ci-inputs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ci-pct {
  width: 80px; padding: 7px 10px; font-size: 15px; font-weight: 600; color: var(--text);
  border: 1px solid var(--border); border-radius: 8px; background: var(--card); outline: none;
}
.ci-pct:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(62,187,167,.15); }
.ci-pctmark { color: var(--text-sub); }
.ci-quick { display: flex; gap: 5px; flex-wrap: wrap; }
.ci-hint { font-size: 13px; color: var(--text-sub); margin: 2px 0 10px; }

.ci-pages {
  margin: 4px 0 12px; padding: 10px 14px;
  border: 1px solid var(--border); border-radius: 8px; background: #FAFBFC;
}
.ci-pages summary { cursor: pointer; font-size: 13px; color: var(--text-sub); }
.ci-pages[open] summary { margin-bottom: 10px; }
/* 页数换算块降级为次要信息：字号（含输入框）小于「本次进度」输入框 */
.ci-pages .ci-label { font-size: 13px; flex-basis: 72px; }
.ci-page, .ci-total {
  width: 110px; padding: 6px 9px; font-size: 13px; color: var(--text);
  border: 1px solid var(--border); border-radius: 8px; background: var(--card); outline: none;
}
.ci-page:focus, .ci-total:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(62,187,167,.15); }
.ci-note-row { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 10px; }
.ci-note-row .ci-label { flex: 0 0 auto; }
.ci-note {
  width: 100%; padding: 8px 10px; font-size: 14px; color: var(--text);
  border: 1px solid var(--border); border-radius: 8px; background: var(--card);
  outline: none; resize: vertical;
}
.ci-note:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(62,187,167,.15); }
.ci-note::placeholder { color: var(--text-sub); opacity: .7; }

.ci-actions {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.ci-check {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 14px; color: var(--text); cursor: pointer;
}
.ci-check.sm { font-size: 13px; }
.ci-check input { accent-color: var(--primary); width: 15px; height: 15px; }

.ci-history { margin-top: 6px; }
.ci-list { list-style: none; }
.ci-list li {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 0; border-bottom: 1px solid var(--border);
}
.ci-list li:last-child { border-bottom: none; }
.ci-h-pct { font-weight: 700; color: var(--primary); }
.ci-h-time { font-size: 13px; margin: 0; }
/* 通用确认框（JS 动态创建，替代原生 confirm）：取消 / 确定 */
.cr-modal-mask {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(30, 40, 45, .45);
}
.cr-modal-box {
  position: fixed; z-index: 201; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(400px, 92vw); background: var(--card);
  border-radius: 12px; box-shadow: 0 12px 40px rgba(20, 30, 35, .18);
  padding: 20px; animation: modal-in .18s ease-out;
}
.cr-modal-msg { font-size: 14px; line-height: 1.7; color: var(--text); }
.cr-modal-acts { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }
.ci-del-form { margin-left: auto; }
.ci-del {
  background: none; border: none; padding: 2px 4px; cursor: pointer;
  font-size: 13px; color: var(--text-sub);
}
.ci-del:hover { color: var(--danger); }
/* 必填标记 */
.req { color: var(--danger); margin-right: 2px; }
.ci-h-note {
  flex: 0 0 100%; margin-top: 4px; padding: 8px 10px; border-radius: 8px;
  background: #F7F9FA; font-size: 14px; color: var(--text);
  white-space: pre-wrap; word-break: break-word;
}

/* ---------- AJAX 轻提示（全站操作成功/失败反馈，不打断操作） ---------- */
.cr-toast {
  position: fixed; left: 50%; top: 18px; z-index: 9999;
  max-width: 86vw; padding: 10px 18px; border-radius: 10px;
  background: var(--text); color: #fff; font-size: 14px; line-height: 1.5;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .16);
  opacity: 0; pointer-events: none;
  transform: translate(-50%, -14px);
  transition: opacity .22s ease, transform .22s ease;
}
.cr-toast.show { opacity: 1; transform: translate(-50%, 0); }
.cr-toast.err { background: var(--danger); }
/* 提交中：轻微降透明度 + 禁用，避免重复提交 */
form.is-busy { opacity: .6; }

/* ---------- 评论区 ---------- */
.cm-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cm-count { font-size: 13px; color: var(--text-sub); font-weight: 400; }
/* 「书评」标题后跟的当前进度（仅已加入共读/已读完时显示） */
.cm-cur-prog { font-size: 13px; font-weight: 400; color: var(--text-sub); margin-left: 6px; }
/* 排序（左）+ 发表书评按钮（右），紧贴列表上方 */
.cm-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 8px 12px; margin: 2px 0 4px;
  padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.cm-toolbar .cm-sort { margin-left: 0; }
.cm-sort { display: flex; gap: 4px; }
.cs-btn {
  padding: 2px 10px; border-radius: 12px; font-size: 12px;
  color: var(--text-sub); border: 1px solid transparent;
  /* ⚠️ 排序按钮已从 <a> 改成 <button>（排序走 AJAX、不再整页跳转）。
     <button> 自带浏览器的灰底与默认光标，且字体不自动继承 —— 必须显式抹掉。
     .btn 那套之所以没写这些，是因为它本来就是 <button>；别照抄它的写法。 */
  background: none; cursor: pointer; font-family: inherit;
  appearance: none; -webkit-appearance: none;   /* 去掉 <button> 的原生外观（Safari 尤其明显） */
}
/* 没有书评时不显示排序按钮。
   ⚠️ .cm-sort 自己设了 display:flex，会盖掉 [hidden] 的 display:none，
   所以必须补这一条（本站没有全局 .hidden 规则）。 */
.cm-sort[hidden] { display: none; }
/* 排序藏起来后，右侧的「发表书评 / 登录后发表书评」仍要留在行尾 */
.cm-sort[hidden] ~ .btn { margin-left: auto; }
.cs-btn:hover { color: var(--primary); background: var(--primary-soft); }
.cs-btn.active { background: var(--primary); color: #fff; }
/* 排序按钮上的升降序箭头（只用在「评论时间」）：↓ 从新到旧，↑ 从旧到新 */
.cs-btn .cs-dir {
  margin-left: 3px; font-size: 11px; line-height: 1; position: relative; top: -1px; opacity: .9;
}
/* 书评分页：上一页 / 页码 / 下一页。
   ⚠️ 翻页与排序都走 AJAX，所以是 <button> 不是 <a href>，别照链接的写法去调样式。 */
.cm-pager {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border);
}
.cm-pg {
  min-width: 30px; padding: 4px 9px; border-radius: 6px; font-size: 13px; line-height: 1.4;
  color: var(--text-sub); background: transparent; border: 1px solid var(--border); cursor: pointer;
}
.cm-pg:hover:not(:disabled):not(.active) { color: var(--primary); border-color: var(--primary); }
.cm-pg.active { background: var(--primary); border-color: var(--primary); color: #fff; }
.cm-pg:disabled { opacity: .45; cursor: default; }
.cm-pg-nav { font-size: 12px; }
.cm-pg-gap { color: var(--text-sub); padding: 0 2px; }
/* 我的共读：标题独占一行，在读/已读完/全部筛选移到下一行 */
#my-reading .cm-head {
  flex-direction: column; align-items: flex-start; gap: 8px; margin-bottom: 12px;
}
#my-reading .cm-head .card-title { margin-bottom: 0; }

/* 发表书评功能区（折叠/展开） */
.cm-compose { margin-top: 12px; }
.cm-form { margin: 0 0 4px; }
.cm-form textarea, .cm-reply textarea {
  width: 100%; padding: 9px 12px; font-size: 15px; color: var(--text);
  border: 1px solid var(--border); border-radius: 8px; background: var(--card);
  outline: none; resize: vertical;
}
.cm-form textarea:focus, .cm-reply textarea:focus {
  border-color: var(--primary); box-shadow: 0 0 0 3px rgba(62,187,167,.15);
}
.cm-form textarea::placeholder, .cm-reply textarea::placeholder { color: var(--text-sub); opacity: .7; }
.cm-form-row, .cm-reply-row {
  display: flex; align-items: center; gap: 12px; margin-top: 8px;
}
.cm-form-row .btn, .cm-reply-row .btn { margin-left: 0; }
/* 发表区内的错误提示（AJAX 校验/网络错误就地显示） */
.cm-error {
  margin-top: 8px; padding: 8px 12px; border-radius: 8px; font-size: 13px;
  color: var(--danger, #C4573F); background: #FBEFEB; border: 1px solid #EED2C6;
}

.cm-list { list-style: none; }
.cm-item { display: flex; flex-wrap: wrap; gap: 10px; padding: 14px 0; border-top: 1px solid var(--border); }
.cm-item:first-of-type { border-top: none; }
/* 回复区是 flex 容器 li 的直接子元素，必须独占一行，否则会被排到主评论右侧成两列 */
.cm-item > .cm-replies { flex: 0 0 100%; width: 100%; }
.cm-item.d2 { margin-left: 16px; }
.cm-item.d3 { margin-left: 24px; }
/* 扁平化回复区：深层回复全部平铺一层，超出 1 条折叠 */
/* 一级回复的缩进统一由容器承担（左侧留白 + 竖线），保证首条与折叠内的回复对齐 */
.cm-replies {
  margin-top: 2px;
  margin-left: 8px;
  padding-left: 18px;
  border-left: 2px solid var(--border);
}
.cm-replies > .cm-item:first-of-type { border-top: none; padding-top: 6px; }
/* 折叠按钮与回复左边缘对齐 */
.cm-replies > .cm-fold { padding-left: 0; }
.cm-fold {
  background: none; border: none; padding: 8px 4px; cursor: pointer;
  font-size: 13px; font-weight: 600; color: var(--primary);
}
.cm-fold:hover { color: var(--primary-dark); }
.cm-rtn { color: var(--primary); }
.cm-ava {
  flex: 0 0 36px; width: 36px; height: 36px; border-radius: 50%;
  background: var(--primary-soft); color: var(--primary-dark);
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 600;
}
/* 已注销用户：灰色空头像圈，与正式用户区分 */
.cm-ava.cm-gone { background: #ECEDEF; color: transparent; border: 1px solid var(--border); }
.cm-item.d1 .cm-ava { flex-basis: 30px; width: 30px; height: 30px; font-size: 13px; }
.cm-item.d2 .cm-ava, .cm-item.d3 .cm-ava { flex-basis: 26px; width: 26px; height: 26px; font-size: 12px; }
.cm-main { flex: 1; min-width: 0; }
.cm-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* 用户名不做强调、不用主题色，与评论时间同色（--text-sub） */
.cm-name { font-weight: 400; font-size: 14px; color: var(--text-sub); }
.cm-time { font-size: 12px; margin: 0; }
/* 评论 meta 行右侧的「⋯」更多菜单（编辑 / 删除） */
.cm-more-wrap { position: relative; margin-left: auto; }
.cm-more {
  background: none; border: none; padding: 0 4px; line-height: 1; cursor: pointer;
  font-size: 16px; color: var(--text-sub);
}
.cm-more:hover { color: var(--text); }
.cm-more[aria-expanded="true"] { color: var(--text); }
.cm-menu {
  position: absolute; right: 0; top: 100%; z-index: 20; min-width: 88px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: 0 6px 18px rgba(60, 80, 90, .14); padding: 4px 0; text-align: left;
}
.cm-menu-form { display: block; }
.cm-menu-item {
  display: block; width: 100%; text-align: left;
  background: none; border: none; padding: 7px 14px; cursor: pointer;
  font-size: 13px; color: var(--text); text-decoration: none;
}
.cm-menu-item:hover { background: var(--primary-soft); color: var(--primary-dark); }
.cm-content { font-size: 15px; line-height: 1.7; margin-top: 4px; white-space: pre-wrap; word-break: break-word; }
/* 评论审核状态提示（批次 2）：待审核 / 需要修改 / 已隐藏 */
.cm-review {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  padding: 9px 12px; border-radius: 8px; font-size: 13px; line-height: 1.6;
}
.cm-review-tag {
  flex: 0 0 auto; padding: 1px 8px; border-radius: 999px;
  font-size: 12px; border: 1px solid transparent;
}
/* ---------- 后台「评论处理原因」表格里的两个小输入框 ----------
   ⚠️ 它们在 `<form class="inline">` 里（`.inline{display:inline}`），**不在 .field 内**
      → 拿不到上面那份「标准输入框外观」，之前是**浏览器默认长相**（无框、无圆角、无聚焦环），
      与站里其它输入框完全不像。这里按本站**紧凑输入框**的规格补齐（同 .ci-page / .ci-total）：
      同样的边框、8px 圆角、主色聚焦环，只有内边距/字号小一档以配上同排的 .btn-sm（13px）。 */
.reason-input, .reason-sort {
  padding: 6px 9px; font-size: 13px; color: var(--text);
  border: 1px solid var(--border); border-radius: 8px; background: var(--card);
  outline: none; transition: border-color .15s, box-shadow .15s;
}
.reason-input:focus, .reason-sort:focus {
  border-color: var(--primary); box-shadow: 0 0 0 3px rgba(62, 187, 167, .15);
}

/* 原因单选列表（后台「发回修改」浮窗；批次 3 的前台举报弹窗会复用同一套） */
.reason-list { display: flex; flex-direction: column; gap: 6px; margin: 10px 0 16px; }
.reason-item {
  display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px;
  padding: 9px 12px; border: 1px solid var(--line, #E4E8EB); border-radius: 8px;
}
.reason-item:hover { background: #F7F8F9; }
.reason-item input { flex: 0 0 auto; margin: 0; }
/* 宽度：`.inline` 是 display:inline（不是 flex），所以 `flex` 其实是空转 ——
   之前宽度靠浏览器的默认尺寸。这里给确定值，窄屏靠 max-width 收住。 */
/* 280px 是「新增原因…（最多 100 字）」这个占位文字不被截断所需的最小宽度。 */
.reason-input { flex: 1 1 auto; min-width: 180px; width: 280px; max-width: 100%; }
.reason-sort { width: 76px; }

/* 后台评论管理：被举报 / 被投诉剧透的汇总（批次 3） */
.cm-report-list {
  margin-top: 8px; padding: 6px 10px; border-radius: 6px;
  background: #FBEFEB; border: 1px solid #F0C9BD;
}
.cm-report-head { font-size: 12px; font-weight: 600; color: #A44A34; margin-bottom: 4px; }
.cm-report-row { font-size: 12px; line-height: 1.7; color: #7A4030; word-break: break-word; }
.cm-report-who { font-weight: 600; }

/* 后台评论管理列表 */
.cm-admin-table td { vertical-align: top; }
.cm-admin-body { font-size: 14px; line-height: 1.65; word-break: break-word; }
.cm-admin-quote {
  margin-bottom: 6px; padding: 6px 10px; border-left: 3px solid var(--line, #E4E8EB);
  background: #F7F8F9; color: var(--text-sub); font-size: 13px; border-radius: 0 6px 6px 0;
  word-break: break-word;
}
.cm-admin-meta { margin-top: 6px; }
.cm-st-normal { background: #F4F5F6; color: #5A6268; border: 1px solid #E4E8EB; }
.cm-st-pending { background: #FBF7EC; color: #8A6D2F; border: 1px solid #F0E2C2; }
.cm-st-rework { background: #FBEFEB; color: #A44A34; border: 1px solid #F0C9BD; }
.cm-st-hidden { background: #FBEFEB; color: #C4573F; border: 1px solid #F0C9BD; }

.cm-review-pending { background: #FBF7EC; border: 1px solid #F0E2C2; color: #8A6D2F; }
.cm-review-pending .cm-review-tag { background: #F0E2C2; color: #7A5C1E; }
.cm-review-rework { background: #FBEFEB; border: 1px solid #F0C9BD; color: #A44A34; }
.cm-review-rework .cm-review-tag { background: #F0C9BD; color: #8A3A26; }
.cm-review-hidden { background: #F4F5F6; border: 1px dashed #D8DDE1; color: var(--text-sub); }
.cm-review-hidden .cm-review-tag { background: #E4E8EB; color: #5A6268; }
.cm-edit-btn {
  margin-left: auto; flex: 0 0 auto; appearance: none; cursor: pointer;
  background: transparent; border: 1px solid currentColor; color: inherit;
  padding: 2px 10px; border-radius: 999px; font-size: 12px;
}
.cm-edit-btn:hover { background: rgba(0, 0, 0, .05); }

.cm-deleted { font-size: 14px; font-style: italic; margin-top: 4px; }

.spoiler {
  margin-top: 6px; padding: 8px 12px; border: 1px dashed var(--border);
  border-radius: 8px; background: #FBFCFC;
}
.spoiler summary { cursor: pointer; font-size: 13px; color: var(--primary); user-select: none; }
.spoiler[open] summary { margin-bottom: 8px; color: var(--text-sub); }
.spoiler[open] { border-style: solid; border-color: var(--border); background: var(--card); }

.cm-actions { display: flex; align-items: center; gap: 16px; margin-top: 8px; }
.cm-like {
  display: inline-flex; align-items: center; gap: 5px;
  background: none; border: none; padding: 2px 4px; cursor: pointer; user-select: none;
  font-size: 14px; color: var(--text-sub); transition: color .15s;
}
.cm-like:hover { color: var(--primary); }
.cm-like.on { color: var(--primary); }
/* ---------- 消息中心 ---------- */
.nt-bell { position: relative; display: inline-flex; align-items: center; text-decoration: none; padding: 2px; }
.nt-bell:hover { color: var(--primary); }
/* 铃铛用与评论气泡同一套线条 SVG（currentColor），尺寸/对齐与 .bubble 一致 */
.nt-bell .bell-ic { display: inline-block; width: 16px; height: 16px; vertical-align: middle; }
.nt-badge {
  display: inline-block; min-width: 16px; padding: 0 4px; margin-left: 5px;
  border-radius: 9px; background: var(--danger); color: #fff;
  font-size: 11px; line-height: 16px; text-align: center; vertical-align: middle;
}
.nt-badge.top { position: absolute; top: -6px; right: -8px; margin-left: 0; font-size: 10px; line-height: 14px; min-width: 14px; }
.nt-tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--border); margin-bottom: 6px; }
.nt-tab {
  display: inline-flex; align-items: center; gap: 4px; padding: 8px 14px;
  font-size: 14px; color: var(--text-sub); text-decoration: none;
  border-bottom: 2px solid transparent;
}
.nt-tab:hover { color: var(--text); }
.nt-tab.active { color: var(--primary-dark); font-weight: 500; border-bottom-color: var(--primary); }
.nt-empty { padding: 24px 4px; text-align: center; }
.nt-list { list-style: none; margin: 0; padding: 0; }
.nt-item { border-top: 1px solid var(--border); }
.nt-item:first-child { border-top: none; }
.nt-item.unread { background: var(--primary-soft); }
.nt-link { display: flex; align-items: flex-start; gap: 10px; padding: 12px 4px; text-decoration: none; color: inherit; }
.nt-link:hover { background: rgba(62, 187, 167, .06); }
.nt-ava {
  flex: 0 0 32px; width: 32px; height: 32px; border-radius: 50%;
  background: var(--card); border: 1px solid var(--border); color: var(--text-sub);
  display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 500;
}
.nt-body { flex: 1; min-width: 0; }
.nt-line { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.nt-who { font-size: 14px; color: var(--text-sub); }
.nt-act { font-size: 14px; color: var(--text); }
.nt-book { display: block; font-size: 12px; color: var(--text-sub); margin-top: 2px; }
.nt-quote {
  display: block; margin-top: 4px; font-size: 13px; color: var(--text-sub);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nt-time { display: block; margin-top: 4px; color: var(--text-sub); }
.nt-dot { flex: 0 0 6px; width: 6px; height: 6px; margin-top: 8px; border-radius: 50%; background: var(--primary); }

/* ---------- 通知跳转定位 ---------- */
.focus-bar {
  margin: 0 0 12px; padding: 8px 12px; border-radius: var(--radius);
  background: var(--primary-soft); color: var(--text); font-size: 13px;
}
.focus-bar a { color: var(--primary-dark); text-decoration: none; margin-left: 6px; }
.focus-bar a:hover { text-decoration: underline; }
.cm-target { position: relative; }
.cm-flash { animation: cmFlash 2.4s ease-out 1; border-radius: var(--radius); }
@keyframes cmFlash {
  0%   { background: var(--primary-soft); }
  70%  { background: var(--primary-soft); }
  100% { background: transparent; }
}

.cm-like .ic { font-size: 16px; line-height: 1; }
.cm-like.busy { opacity: .6; pointer-events: none; }
.cm-like:focus { outline: 2px solid var(--primary-soft); outline-offset: 2px; border-radius: 6px; }
.cm-reply-btn {
  background: none; border: none; padding: 2px 4px; cursor: pointer;
  font-size: 13px; color: var(--text-sub);
}
.cm-reply-btn:hover { color: var(--primary); }

.cm-reply {
  margin-top: 10px; padding: 10px 12px;
  background: #F7F9FA; border-radius: 8px;
}

/* ---------- 首页：本期共读卡片（书库级大封面，左图右文） ---------- */
/* 一行两本；只有一本共读书时加 .is-single → 两列退成一列、卡片**占满整行**。
   极窄屏（≤720px）本来就是单列，无需额外规则。 */
.pick-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
/* 只有一本共读书时：两列退成一列，卡片**占满整行**。
   早期版本这里用 max-width: calc(50% - 7px) + 左右 auto 让它「保持两列时的单列宽度并居中」，
   2026-09-17 按要求改为占满 100% —— 若将来又想要半宽居中，把那条 max-width 加回来即可。 */
.pick-list.is-single { grid-template-columns: minmax(0, 1fr); }
.pick-card {
  display: flex; gap: 20px; padding: 16px;
  border: 1px solid var(--border); border-radius: 12px; background: var(--card);
  align-items: stretch;
}
.pick-card:hover { border-color: var(--primary); }
.pick-cover {
  flex: 0 0 200px; width: 200px; height: 300px; border-radius: 8px; overflow: hidden;
  background: var(--primary-soft); display: flex; align-items: center; justify-content: center;
  font-size: 64px; position: relative;
}
.pick-cover img { width: 100%; height: 100%; object-fit: cover; }
.pick-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
/* ⚠️ 上面**故意不写 `justify-content`**（默认 `flex-start` ＝ **顶部对齐**）。
   2026-09-17 之前这里是 `justify-content: center`（纵向居中），用户对着截图指出：
   卡片高度 = max(封面固定 300px, 信息列自然高度)，**信息列较短的卡**（如「已读完」那张、
   没有进度条）被纵向居中后，**标题上方会空出一块**；而信息多的卡撑满高度、看起来就是顶对齐
   —— 同一行两张卡观感不一致。改顶对齐后，两张卡的标题都从封面顶边开始排。
   想回到居中就加回 `justify-content: center`（记得同步改下面 .book-foot 的注释）。 */
/* ⚠️ 列方向 flex 默认 align-items: stretch → 徽章/按钮会被**拉成整行宽**（曾出现「已读完 / 查看 / 加入共读」
   三个都撑满的观感）。这里改成按**内容宽度**排；但进度条是图形、必须占满，故单独让它 stretch。 */
.pick-info { align-items: flex-start; }
.pick-info .pick-prog { align-self: stretch; align-items: flex-start; }
.pick-info .pick-prog .prog-bar,
.pick-info .pick-prog .prog-meta { align-self: stretch; }
.pick-title { font-size: 19px; font-weight: 700; line-height: 1.35; }
.pick-title a { color: var(--text); }
.pick-title a:hover { color: var(--primary); }
.pick-author { font-size: 14px; }
/* 共读卡的**书籍简介**（.pick-desc）：文本与详情页 `.book-desc` 是同一份，只是卡片空间小、
   字号收一档、颜色用次级灰（否则一屏两个大黑块，卡片会被简介压得看不出书名）。
   ⚠️ 两个易踩点：
   ① `.pick-info` 是 `align-items: flex-start` 的**列** flex → 段落只会拿到 shrink-to-fit 宽度，
      必须 `align-self: stretch` 才占满整列（与上面 `.pick-prog` 同一处理，理由相同）。
   ② 只显示**前 50 字** + 「查看全文」链接（**不做展开折叠**，2026-09-17 用户改口径），
      所以高度稳定，卡片不会被简介撑长。
   ⚠️ **不写 `white-space: pre-line`**（＝默认 normal）：共读卡的简介**不换行**，
      段落换行折叠成空格 —— 与详情页 `.book-desc`（保留段落）**故意不同**，别顺手统一。 */
.pick-desc {
  align-self: stretch; font-size: 13px; line-height: 1.75; color: var(--text-sub);
}

/* 「展开全文 / 收起」按钮（详情页）与「查看全文」链接（共读卡）**共用一套外观**：
   无底色、只有主题色文字。两者字体必须显式声明 —— `<button>` 不继承字体，`<a>` 虽继承但要与按钮一致。 */
.desc-fold,
.desc-more {
  background: none; border: none; padding: 0; margin-left: 6px;
  font-family: inherit; font-size: 13px; font-weight: 600; line-height: inherit;
  color: var(--primary); cursor: pointer; vertical-align: baseline;
}
.desc-fold:hover,
.desc-more:hover { color: var(--primary-dark); }
/* 折叠时藏起来的那一半。显式写死：UA 的 [hidden]{display:none} 会被任何 display 规则盖掉
   （本项目 .btn{display:inline-block} 就干过这事） */
.desc-short[hidden], .desc-full[hidden] { display: none; }
/* 后台「待审核注册」列表的**阅读履历**（.bio-cell）：默认只显示前 60 字 + 「展开全文」。
   —— 履历最多 2000 字、是**审核依据**，之前只能看到前 60 字根本没法判断通过与否。
   ⚠️ ① `pre-line` 只加在 .desc-full 上：保留用户写的段落换行，同时避免 <td> 里的 HTML 缩进被渲染成真换行。
      ② 必须写 `:not([hidden])` —— 否则这条的 `display:block` 会盖掉上面的 `[hidden]{display:none}` 导致收不起来
        （本项目又一次踩「自定义 display 盖掉 [hidden]」，同源问题见 .btn / .bh-stat / .desc-short）。
      ③ max-height + overflow：2000 字全展开会把表格撑到几千像素高，限制后改为内部滚动。 */
.bio-cell .desc-full:not([hidden]) {
  display: block; white-space: pre-line; max-height: 320px; overflow-y: auto;
}
.pick-join, .pick-join-form { margin-top: 4px; }
/* 若沿用书卡底栏的 margin-top:auto，会把「喜欢/评论」顶到卡片最底部、
   与上面的「加入共读 / 去打卡」之间留出一大块空白 → 共读卡这里还原成普通间距，整块按 gap 顺排。
   ⚠️ 这条与 .pick-info 是否居中**无关**：改成顶对齐后同样要保留（否则底栏会被推到卡片最底部）。 */
.pick-info .book-foot { margin-top: 0; }
.pick-prog { margin-top: 4px; display: flex; flex-direction: column; gap: 8px; }
.pick-prog .prog-bar { height: 8px; }
.pick-prog .prog-meta { gap: 12px; }

/* ---------- 个人中心：我的共读 / 打卡历史（超小封面） ---------- */
.mr-list { list-style: none; }
.mr-item { padding: 12px 0; border-bottom: 1px solid var(--border); }
.mr-item:last-child { border-bottom: none; }
.mr-row { display: flex; gap: 10px; align-items: center; }
.mr-cover {
  flex: 0 0 36px; width: 36px; height: 54px; border-radius: 5px; overflow: hidden;
  background: var(--primary-soft); display: flex; align-items: center; justify-content: center;
  font-size: 14px;
}
.mr-cover img { width: 100%; height: 100%; object-fit: cover; }
.mr-info { flex: 1; min-width: 0; }
.mr-title { font-size: 14px; font-weight: 600; line-height: 1.4; }
.mr-title a { color: var(--text); }
.mr-title a:hover { color: var(--primary); }
.mr-author { font-size: 13px; }
.mr-meta { font-size: 13px; }
.mr-act { display: flex; align-items: center; gap: 10px; }
.mr-pct { font-size: 14px; font-weight: 600; color: var(--text); }
.mr-prog { margin-top: 10px; }
.mr-prog .prog-bar { height: 6px; }

/* ===== 打卡热力图（我的 → 打卡历史；2026-09-16 加，2026-10-04 色阶改十档）=====
   53 周网格：列 = 一周（左旧右新），行 = 周一到周日（自上而下）。
   色阶只有 --primary 一个变量可用，所以统一用「底色 + opacity」分十档 ⇒ 跟随后台主题色。 */
/* 卡片内的小标题（「我的」页等处）：比 .card-title 低一级。
   与下一个块之间靠 margin 合并保持 18px，不用为每个区块单独调间距。 */
.sub-title { font-size: 14px; font-weight: 600; margin: 18px 0 8px; color: var(--text); }
.hm-wrap { margin-bottom: 18px; }
.hm-scroll { overflow-x: auto; padding-bottom: 4px; }
.hm-inner { display: flex; gap: 6px; align-items: flex-start; }
/* 左侧星期刻度：上方留出月份行的高度（17px），才能和网格第 1 行对齐 */
.hm-days {
  display: grid; grid-template-rows: repeat(7, 11px); gap: 3px; padding-top: 17px;
  font-size: 10px; line-height: 11px; color: var(--text-sub); text-align: right;
}
/* 星期刻度的行号与网格 7 行一一对应：1=周一 … 7=周日，只标 1/3/5（一/三/五，GitHub 惯例）。
   ⚠️ 用**显式 grid-row** 而不是"排 7 个 span 靠位置顶行" —— 后者曾把"一"写进第 2 个 span，
   结果"一"显示在第 2 行，而网格第 1 行才是周一。显式定位后增删 span 都不会错位。 */
.hm-days .hm-d1 { grid-row: 1; }
.hm-days .hm-d3 { grid-row: 3; }
.hm-days .hm-d5 { grid-row: 5; }
.hm-main { flex: 0 0 auto; }
.hm-months {
  display: grid; grid-auto-flow: column; grid-auto-columns: 11px; gap: 3px;
  height: 17px; font-size: 10px; line-height: 11px; color: var(--text-sub);
}
.hm-months span { white-space: nowrap; }
.hm-grid {
  display: grid; grid-auto-flow: column; grid-template-rows: repeat(7, 11px);
  grid-auto-columns: 11px; gap: 3px;
}
.hm-cell { width: 11px; height: 11px; border-radius: 2px; background: #EAEEF1; display: inline-block; }
/* 色阶十档（2026-10-04：每满 1% 深一档，≥10% 封顶最深 —— 用户定）。
   只有 --primary 一个变量可用，统一用「底色 + opacity」⇒ 跟随后台主题色。
   ⚠️ 实际档位比图例细：图例只抽 5 格示意（lv0/1/4/7/10），别按图例反推档位数。 */
.hm-cell.lv1 { background: var(--primary); opacity: .12; }
.hm-cell.lv2 { background: var(--primary); opacity: .22; }
.hm-cell.lv3 { background: var(--primary); opacity: .32; }
.hm-cell.lv4 { background: var(--primary); opacity: .42; }
.hm-cell.lv5 { background: var(--primary); opacity: .51; }
.hm-cell.lv6 { background: var(--primary); opacity: .61; }
.hm-cell.lv7 { background: var(--primary); opacity: .71; }
.hm-cell.lv8 { background: var(--primary); opacity: .81; }
.hm-cell.lv9 { background: var(--primary); opacity: .90; }
.hm-cell.lv10 { background: var(--primary); opacity: 1; }
/* 本周里今天之后的格子：留空，别让右端多出一截假的"没打卡" */
.hm-cell.hm-future { background: transparent; }
.hm-foot {
  display: flex; justify-content: space-between; align-items: center;
  gap: 10px; flex-wrap: wrap; margin-top: 8px;
}
.hm-legend { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; color: var(--text-sub); }

.mci-list { list-style: none; margin-top: 4px; }
.mci-item { padding: 8px 0; border-bottom: 1px solid var(--border); }
.mci-item:last-child { border-bottom: none; }
.mci-pct { font-weight: 700; color: var(--primary-dark); margin-right: 10px; }
.mci-date { font-size: 12px; }
.mci-note {
  margin-top: 4px; padding: 8px 10px; border-radius: 8px;
  background: #F7F9FA; font-size: 14px; white-space: pre-wrap; word-break: break-word;
}

/* 移动端：卡片纵向 */
@media (max-width: 720px) {
  .pick-list { grid-template-columns: 1fr; }
  .rd-head { gap: 10px; }
  .ci-label { flex-basis: 100%; }
  .pick-card { gap: 14px; padding: 12px; }
  .pick-cover { flex-basis: 140px; width: 140px; height: 210px; font-size: 46px; }
  .pick-title { font-size: 17px; }
}

/* ===== 音标（牛津英/美）与发音 ===== */
.ipa-clickable{ cursor:pointer; border-bottom:1px dashed var(--border); }
.ipa-clickable:hover{ color:var(--primary-dark); border-bottom-color:var(--primary); }
.ipa-clickable.playing{ color:var(--primary-dark); opacity:.6; }

/* 全局轻提示（无音频包 / 缺失发音时用） */
.ipa-tip{
  position:fixed; left:50%; bottom:28px; transform:translate(-50%,14px);
  max-width:min(92vw,520px); padding:10px 16px; border-radius:8px;
  background:rgba(47,52,56,.94); color:#fff; font-size:13.5px; line-height:1.55;
  box-shadow:0 6px 22px rgba(0,0,0,.22); z-index:9999;
  opacity:0; pointer-events:none; transition:opacity .22s,transform .22s;
}
.ipa-tip.show{ opacity:1; transform:translate(-50%,0); }

/* 我的设置 · 发音音频包 */
.aud-status{ display:flex; align-items:center; gap:10px; margin-top:12px; font-size:14px; flex-wrap:wrap; }
.aud-dot{ width:9px; height:9px; border-radius:50%; background:#C9CDD1; flex:0 0 auto; }
.aud-dot.on{ background:var(--primary); }
.aud-progress{
  margin-top:10px; padding:9px 12px; border-radius:6px; font-size:13.5px;
  background:var(--primary-tint); color:var(--primary-dark); border:1px solid var(--primary-line);
}
/* 我的设置 · 合并后的「词典设置」单一卡片 */
.set-subtitle{ font-size:15px; font-weight:600; color:var(--text); margin:4px 0 10px; }
.set-divider{ border:none; border-top:1px solid var(--border); margin:22px 0; }
.accent-saved{ font-size:13px; color:var(--primary); }
.accent-saved[hidden]{ display:none; }
/* 音标显示：标签与「美式 / 英式」同行，不换行 */
.field.set-accent-field{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.field.set-accent-field > label{ display:inline-block; margin:0; }
.field.set-accent-field .mb-status-group{ align-items:center; }
/* ---------- 我的设置 · 字号设置（卡片排在「词典设置」下方） ----------
   预览区直接吃 --ep-word / --ep-def / --ep-ex，所以点选后**当页立刻能看出效果**
   （设置页本身没有单词/释义/例句，没有预览就是盲调）。 */
.fs-preview{ margin-top:4px; padding:12px 14px; border:1px solid var(--border); border-radius:var(--radius); background:var(--card); }
.fs-pv{ display:flex; gap:10px; align-items:baseline; margin:7px 0; }
.fs-pv-k{ flex:0 0 34px; font-size:12px; color:var(--text-sub); }
.fs-pv .wtext{ font-weight:600; font-size:var(--ep-word); }
.fs-pv-def{ font-size:var(--ep-def); line-height:1.7; color:var(--text); }
.fs-pv-ex{ font-size:var(--ep-ex); line-height:1.7; color:#2a2f36; }
.fs-pv-ex mark{ background:#ffe58f; color:#1f2329; padding:0 2px; border-radius:3px; font-weight:600; }
/* 设置页「选择文件」按钮：字号对齐本站 .btn(15px)，整体加大 */
.field input[type="file"]{ font-size:15px; color:var(--text); }
.field input[type="file"]::file-selector-button{
  font-family:inherit; font-size:15px; padding:9px 18px; margin-right:12px;
  border:1px solid var(--border); border-radius:8px; background:var(--card); color:var(--text); cursor:pointer;
}
.field input[type="file"]::file-selector-button:hover{ border-color:var(--primary); color:var(--primary); }

/* ---------- 词典（本机导入 .creadict 词典包）--------- */
/* .btn 设了 display:inline-block，会盖过 UA 的 [hidden]{display:none}，
   导致「清除缓存」在尚未导入时也显示。按本项目既有写法补一条作用域规则。 */
.aud-status .btn[hidden]{ display:none; }
.aud-packs{ margin-top:10px; border-top:1px solid var(--border); }
.aud-row{ display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:9px 0; border-bottom:1px solid var(--border); }
.aud-row:last-child{ border-bottom:none; }
.aud-state{ font-size:13.5px; color:var(--text-sub); }
.aud-state.on{ color:var(--text); }
/* 同理：清除按钮在 .aud-row 里，也要压过 .btn 的 display */
.aud-row .btn[hidden]{ display:none; }
.aud-link{ margin-right:14px; }
.aud-dot.ok{ background:var(--primary); }
.aud-dot.err{ background:#C4573F; }
.aud-dot.busy{ background:#D9A441; animation:defPulse 1.1s ease-in-out infinite; }
@keyframes defPulse{ 0%,100%{opacity:1;} 50%{opacity:.35;} }
.def-list{ margin-top:14px; border-top:1px solid var(--border); }
.def-row{ display:flex; align-items:center; justify-content:space-between; gap:12px; padding:11px 2px; border-bottom:1px solid var(--border); }
.def-row:last-child{ border-bottom:none; }
.def-info{ min-width:0; }
.def-name{ font-size:14px; font-weight:600; color:var(--text); word-break:break-all; }
.def-acts{ display:flex; gap:8px; flex:0 0 auto; flex-wrap:wrap; justify-content:flex-end; }

/* 词典正文的「隔离区」：释义直接渲染词典自带的 HTML，这里只保证不把站点排版带歪，
   并给出合理的兜底字号行高。具体长相由下面的 .collins-def / .oxford-def 决定，
   两者都用「词典包头部的 style 字段」来选择（见 book_analysis.js:dictBodyHtml）。 */
.coread-dict-body{ font-size:calc(var(--ep-def,15px) * 1.15); line-height:1.72; color:var(--text); overflow-x:auto; }
.coread-dict-body img{ max-width:100%; height:auto; }
.coread-dict-body table{ max-width:100%; }
/* 某些词典正文的外层是自定义标签 <body-content>，Chromium 对未知元素默认
   display:none，必须显式兜底为 block，否则整个释义区高度为 0、看着一片空白。 */
.coread-dict-body > body-content,
.coread-dict-body body-content,
.coread-dict-body > div:first-of-type{ display:block; }
.def-panel-dict{ max-height:62vh; overflow-y:auto; }

/* ===== 柯林斯 COBUILD 释义样式（源自 epub_vocab_app，作用域改到 .collins-def）===== */
.collins-def{ font-size:calc(var(--ep-def,15px) * 1.1); line-height:1.72; color:var(--text); overflow-x:auto; }
.collins-def .note{ background:#f0f4fa; border:1px solid #d4dce7; border-radius:8px; padding:12px 14px; margin-bottom:14px; line-height:1.7; font-size:.95em; }
.collins-def .note b{ font-weight:600; }
.collins-def .def_cn,.collins-def .chinese-text{ color:var(--text); }
.collins-def .caption{ margin-top:16px; margin-bottom:6px; padding-left:8px; line-height:1.6; font-size:.95em; }
.collins-def .caption .num{ display:inline-block; font-weight:700; font-size:1.1em; min-width:1.3em; text-align:left; color:var(--text); }
.collins-def .caption .st{ font-weight:700; font-size:.85em; color:#555; margin-right:6px; letter-spacing:.02em; }
.collins-def .cn_before,.collins-def .cn_after{ color:#888; font-size:.9em; }
.collins-def .example{ margin-top:4px; }
.collins-def .example ul{ list-style:none; padding:0 0 0 18px; margin:4px 0 0; }
/* 柯林斯/牛津**词条内部**的例句也归「例句」那一档（原来是随释义缩放的字号）。
   注：原值是 .93em/继承（≈14.3px / 14.7px），改成 var(--ep-ex) 后「中」档为 14px，
   差 2%~5%，肉眼不可辨；换来的是「例句」这档设置真正管住所有例句。 */
.collins-def .example li{ position:relative; padding:5px 0 5px 16px; line-height:1.65; font-size:var(--ep-ex); }
.collins-def .example li::before{ content:"\2022"; position:absolute; left:0; color:#aaa; font-size:.9em; }
.collins-def .example li p{ margin:2px 0; }
.collins-def .text_blue{ color:#2979c0; font-weight:600; border-bottom:1px dashed #bde0f0; }
.collins-def .def{ white-space:pre-wrap; line-height:1.75; }
.collins-def .part_list ul{ margin:6px 0; padding-left:20px; }
.collins-def .part_list li{ margin:2px 0; font-size:.92em; color:#555; }
.collins-def h3.close{ font-size:1em; font-weight:700; margin:14px 0 4px; color:#1f2937; }
/* 词典自带的趋势图/图片小节与词频点阵——按需求隐藏 */
.collins-def .collins_en_cn.trend,.collins-def .collins_en_cn.image,
.collins-def .wordfreq,.collins-def .level{ display:none !important; }

/* ===== 牛津高阶双解第10版释义样式（源自 epub_vocab_app，作用域 .oxford-def）===== */
.oxford-def{ color:#333; font-size:calc(var(--ep-def,15px) * 1.05); line-height:1.7;
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  overflow-x:auto; }
.oxford-def .entry{ font-family:inherit; }
.oxford-def h1.headword,.oxford-def h2.h{ font-style:italic; font-size:1.5em; font-weight:700; color:#c70000; display:inline-block; margin:0; }
.oxford-def .pos{ font-style:italic; font-size:.95em; color:#fff; font-weight:600; padding:1px 9px; border-radius:5px; background-color:#c70000; margin-left:.35rem; }
.oxford-def ol.senses_multiple,.oxford-def ol.senses_single{ padding-left:0; margin-left:0; list-style:none; }
.oxford-def .li_sense{ display:flex; width:100%; }
.oxford-def .li_sense_before{ font-weight:600; border-radius:7px; margin-right:.3rem; font-size:.9rem; font-style:italic; display:inline-block; min-width:1rem; }
.oxford-def li.sense{ margin:.5rem 0 0; width:100%; list-style:none; }
.oxford-def .grammar{ color:#9f3b34; font-style:italic; margin-right:.2rem; }
.oxford-def .def{ color:#111; display:inline; }
.oxford-def deft{ margin-left:5px; }
.oxford-def deft chn,.oxford-def chn.simple{ color:#be002f; display:inline; }
.oxford-def chn.traditional{ display:none; }   /* 简体用户：只显示简体中文 */
.oxford-def .gloss{ color:#6b7280; font-style:italic; }
.oxford-def .ndv{ font-style:italic; }
.oxford-def ul.examples{ list-style:none; padding-left:1.1rem; margin:.35rem 0 0; }
.oxford-def ul.examples > li{ position:relative; padding:4px 0; font-size:var(--ep-ex); }
.oxford-def ul.examples > li:before{ content:"\2022"; position:absolute; left:-1rem; color:#333; }
.oxford-def ul.examples .x{ color:#0f766e; }
.oxford-def ul.examples .xt,.oxford-def ul.examples .xt chn{ font-style:normal; }
.oxford-def ul.examples .xt chn{ color:#be002f; }
.oxford-def .shcut{ font-size:1.05em; font-weight:700; margin:.9rem 0 .2rem; color:#1f2937; }
.oxford-def .shcut chn{ color:#be002f; font-weight:400; margin-left:.3rem; }
.oxford-def .xrefs .prefix{ font-weight:700; margin-right:.25rem; }
.oxford-def table.verb_forms_table{ border-collapse:collapse; margin:.5rem 0; font-size:.9em; }
.oxford-def table.verb_forms_table td{ border:1px solid #e5e7eb; padding:3px 9px; }
/* 词典自带的发音小喇叭图标（icomoon 私用区字符），墨迹阅读器上会变方块，隐藏 */
.oxford-def .sound,.oxford-def .phons_br,.oxford-def .phons_n_am,.oxford-def .symbols{ display:none; }

/* ============ 生词本（我的 → 生词本标签） ============ */
.wb-total{ font-weight:400; margin-left:6px; }
.wb-search{ display:flex; gap:8px; align-items:center; margin:10px 0 2px; flex-wrap:wrap; }
.wb-search input[type="text"]{
  flex:1 1 180px; min-width:140px; padding:7px 10px; font-size:14px;
  border:1px solid var(--border); border-radius:8px; background:var(--card); color:var(--text);
}
.wb-search input[type="text"]:focus{ outline:none; border-color:var(--primary); }
.wb-list{ list-style:none; margin:10px 0 0; padding:0; }
.wb-item{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:8px 4px; border-bottom:1px solid var(--border); }
.wb-item:last-child{ border-bottom:0; }
.wb-w{ flex:0 1 auto; min-width:0; }
.wb-w .wtext{ font-weight:600; font-size:var(--ep-word, 15px); cursor:pointer; }
.wb-w .wtext:hover{ color:var(--primary); }
.wb-item .ipa{ color:#9AA3AC; font-weight:400; margin-left:10px; }
.wb-acts{ display:flex; gap:6px; margin-left:auto; }
.wb-pager{ display:flex; align-items:center; gap:10px; justify-content:center; margin-top:14px; }
.wb-toast{ position:fixed; left:50%; bottom:40px; transform:translateX(-50%); background:rgba(0,0,0,.8); color:#fff;
  padding:8px 16px; border-radius:8px; font-size:14px; z-index:9999; display:none; }
.wb-meta{ margin:2px 0 10px; font-size:13px; color:var(--text-sub); }
.wb-body{ max-height:52vh; overflow:auto; }
.wb-src{ margin-top:10px; font-size:13px; color:var(--text-sub); }
.wb-dict-src{ font-size:12px; color:var(--text-sub); margin:10px 0 2px; }

/* 生词本弹层「例句」：在「在读的书」之间切换（最多 4 本） */
.ex-books{ display:flex; flex-wrap:wrap; gap:6px; margin:2px 0 8px; }
.ex-book{
  font-size:12px; padding:3px 10px; border-radius:999px; cursor:pointer;
  border:1px solid var(--border); background:var(--card); color:var(--text-sub);
  max-width:180px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.ex-book.active{ border-color:var(--primary); color:var(--primary); background:var(--primary-soft); }
.ex-pane{ margin-top:2px; }
/* 手机端：书名独占一行，操作按钮靠右，避免挤成一团 */
@media (max-width:560px){
  .wb-item{ gap:8px; }
  .wb-acts{ margin-left:auto; }
}

/* ============ 背单词（生词本勾选 + 背诵页） ============ */
.wb-head-acts{ display:flex; align-items:center; gap:8px; margin-left:auto; flex-wrap:wrap; }
.wb-due{ display:inline-block; min-width:18px; margin-left:5px; padding:0 5px; border-radius:999px;
  background:#fff; color:var(--primary-dark); font-size:11px; font-weight:600; }
.wb-pickall{ display:inline-flex; align-items:center; gap:6px; font-size:13px; color:var(--text-sub); cursor:pointer; margin:0; }
.wb-pick{ width:16px; height:16px; margin:0 2px 0 0; accent-color:var(--primary); flex-shrink:0; }
/* 「已选 N 个」用的是 .muted.sm：.muted 自带 margin-bottom:10px，在 flex 居中里会把文字顶上去 */
.wb-sel{ margin:0; }
/* 显隐：本项目没有全局 .hidden（只有 .def-panel.hidden），
   且 .btn{display:inline-block} 会盖过 UA 的 [hidden]{display:none} —— 两处都得显式声明 */
.wb-head-acts .btn[hidden], .wb-toolbar .btn[hidden]{ display:none; }
.wb-toolbar{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin:6px 0 4px; flex-wrap:wrap; }
.wb-toolbar-left{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.wb-toolbar .btn.primary{ margin-left:auto; }
/* 生词本筛选行（难度 / 状态），位于全选工具条上方 */
.wb-filter-line{ display:flex; align-items:center; gap:10px; margin:2px 0; flex-wrap:wrap; }
.wb-filter-line .wb-flbl{ font-size:13px; color:var(--text-sub); }
.wb-filter-line .tabs{ flex:1 1 auto; min-width:0; padding:0; }
.st-show.hidden, .st-rates.hidden, .st-back.hidden{ display:none; }

/* 背诵状态徽标（生词本列表） */
.wb-study{
  flex:0 0 auto; font-size:11px; line-height:1.6; padding:1px 8px; border-radius:999px;
  border:1px solid var(--border); color:var(--text-sub); background:var(--bg); white-space:nowrap;
}
.wb-study.st-1{ border-color:var(--primary-line); color:var(--primary-dark); background:var(--primary-soft); }
.wb-study.st-2{ border-color:var(--primary); color:#fff; background:var(--primary); }
.wb-study.st-3{ border-color:var(--primary-line); color:var(--primary-dark); background:var(--primary-tint); }
.wb-study.st-4{ border-color:#bfe0d6; color:#2F9C8A; background:#eaf7f3; }

/* 背诵页 */
.study-card .study-stats{ display:flex; gap:14px; flex-wrap:wrap; font-size:13px; color:var(--text-sub); margin-left:auto; }
.study-stats b{ color:var(--text); font-weight:600; }
.study-stats .st-due b{ color:var(--primary-dark); }
.st-loading{ padding:24px 0; text-align:center; color:var(--text-sub); }
.st-prog{ display:flex; align-items:center; gap:10px; margin:14px 0 6px; }
.st-prog-bar{ flex:1; height:6px; border-radius:999px; background:var(--bg); overflow:hidden; }
.st-prog-bar i{ display:block; height:100%; background:var(--primary); }
.st-card{ border:1px solid var(--border); border-radius:12px; padding:22px 18px; text-align:center; background:var(--card); }
.st-word{ font-size:30px; font-weight:700; line-height:1.25; color:var(--text); }
.st-ipa{ margin-top:6px; font-size:15px; color:#9AA3AC; }
.st-meta{ margin-top:8px; font-size:12px; color:var(--text-sub); }
.st-back{ margin-top:16px; padding-top:14px; border-top:1px dashed var(--border); text-align:left; }
.st-show{ display:block; margin:16px auto 0; }
.st-rates{ display:flex; gap:8px; justify-content:center; margin-top:14px; flex-wrap:wrap; }
.st-grade{
  flex:1 1 88px; max-width:130px; padding:10px 4px; cursor:pointer; font-size:14px;
  border:1px solid var(--border); border-radius:10px; background:var(--card); color:var(--text);
}
.st-grade:hover{ border-color:var(--primary); }
.st-grade.st-g0{ color:#C4573F; border-color:#e3c4bb; }
.st-grade.st-g0:hover{ background:#fdf3f0; }
.st-grade.st-g1{ color:#B07A2A; border-color:#e6d3b3; }
.st-grade.st-g1:hover{ background:#fdf8ef; }
.st-grade.st-g2:hover{ background:var(--primary-soft); }
.st-grade.st-g3{ color:var(--primary-dark); border-color:var(--primary-line); }
.st-grade.st-g3:hover{ background:var(--primary-soft); }
.st-tip{ margin-top:12px; text-align:center; font-size:13px; color:var(--primary-dark); }
.st-def{ margin-bottom:10px; }
.st-ex{ margin-top:4px; }

/* 手机端：词号小一点、评分按钮两行 */
@media (max-width:560px){
  .st-word{ font-size:25px; }
  .st-grade{ flex:1 1 calc(50% - 8px); max-width:none; }
  .wb-head-acts{ gap:6px; }
  .wb-toolbar-left{ gap:6px; }

  /* ⚠️ 答案区（释义 / 例句）别再被父块的层层内边距挤窄（2026-09-19）：
     390px 屏上原本 wrap 14 + .card 24 + .st-card 18 = **左右各 56px**，正文只剩约 278px；
     这里把外层两层压薄 ⇒ 左右各约 23px，正文约 **314px**（释义明显宽松）。
     ⚠️ 只压**外层容器**：词典模板自带的例句缩进（`.collins-def .example ul/li`、
        `.oxford-def ul.examples`）**刻意不动** —— 用户选的是影响面最小的方案。
     ⚠️ 只写 padding-left/right，不动上下的 22px（`.st-card` 的上下留白是刻意的手感）。 */
  .card.study-card{ padding-left:12px; padding-right:12px; }
  .st-card{ padding-left:10px; padding-right:10px; }

  /* ⚠️ 答案区（释义 / 例句）与上面那段「按艾宾浩斯遗忘曲线…」说明文字**左对齐**（2026-09-19 用户按手机截图要求）：
     `.st-back` 里的 `.def-tabs` / `.wm-body` 是从**单词弹层**复用的类，自带 `padding: …18px`；
     再叠加 `.st-card` 的 10px 内边距，答案区正文左边被推到 **57px**（说明文字只有 26px）——
     手机上看着就是"缩了一大截、比上面那段话窄很多"。
     这里把这两层抵消掉 ⇒ 正文左边 29px，与说明文字（26px）只差 1px 的卡片描边 + 2px 的 `.ex` 内边距。
     ⚠️ 只在 `.st-back` 作用域内抵消：书籍页的单词弹层（同一个 `.wm-body`）**保持原样不受影响**。
     ⚠️ 词典模板**内部**的例句缩进（`.collins-def .example ul/li`、`.oxford-def ul.examples`）
        仍刻意不动 —— 那是另一件事，用户之前明确选了不动它。 */
  .st-back{ margin-left:-10px; margin-right:-10px; }   /* 抵消 .st-card 的左右内边距 */
  .st-back .def-tabs{ padding-left:0; padding-right:0; }
  .st-back .wm-body{ padding-left:0; padding-right:0; }
}

/* ============================================================
   打赏（「支持本站」）：页脚入口 + ?p=support 页面 + 后台预览
   ============================================================ */

/* 页脚入口：主题色 + 加粗 + 加大的「赏」字（用户 2026-09-17 指定）。
   ⚠️ 它是 <a>，必须显式去掉下划线；字号比页脚正文（13px）大一档才看得出来是个入口。 */
.support-entry {
  display: inline-block;
  margin-right: 7px;
  color: var(--primary);
  font-size: 19px;
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
  vertical-align: -2px;
}
.support-entry:hover { color: var(--primary-dark); }
.support-entry:focus-visible { outline: 2px solid var(--primary-soft); outline-offset: 2px; border-radius: 4px; }

/* 前台页：**背景块的宽度与站内其它页面一致**（用户 2026-09-17 指定）——
   承接 `.wrap` 的 1080px 上限，不再自己收窄。
   ⚠️ 原先这里有一条 `.support-card { max-width: 520px }`（当时想的是「码只有 240px，
      铺满会两侧空」，但结果是**它比上方的面包屑、比站里所有页面都窄**，反而显眼）。
      别再把它加回来；`auth-card`（登录/重置密码）那条 440px 是另一回事，别混。 */
.support-desc { margin-bottom: 20px; font-size: 15px; line-height: 1.9; color: var(--text); }
.support-qr { margin: 0 0 18px; text-align: center; }
/* ⚠️ 固定 240×240 并用 object-fit:contain —— 收款码多是正方形，但用户也可能传一张
   带外框/截图的长图；不锁高度的话 `height:auto` 会把它拉成很长一条。contain 保证
   任何比例都装进这个方框里、不变形。 */
.support-qr img {
  width: 240px; height: 240px; object-fit: contain;
  padding: 8px; border: 1px solid var(--border); border-radius: 10px; background: #fff;
}
.support-tip { margin: 10px 0 0; font-size: 13px; color: var(--text-sub); }
/* ⚠️ 原有一条 `.support-limit { margin-top: 4px; }` 服务「单笔上限 200 元」那行，
   2026-09-17 那行按用户要求删除后，这条规则已无引用 → 一并清掉。再加那行时记得把间距补回来。 */
.support-qr-missing { margin-bottom: 18px; }
/* ⚠️ 这条靠「本块在 app.css 末尾」压掉 `.muted` 的 margin-bottom:10px —— 别把它挪到前面去 */
.support-note {
  margin: 0; padding-top: 14px;
  border-top: 1px solid var(--border);
  font-size: 13px; line-height: 1.8; color: var(--text-sub);
}

/* 后台「打赏设置」里的当前收款码预览 */
.support-qr-preview { margin-bottom: 10px; }
.support-qr-preview img {
  display: block; width: 120px; height: auto; padding: 4px; margin-bottom: 4px;
  border: 1px solid var(--border); border-radius: 8px; background: #fff;
}
