/* ============================================================
   小步学 —— 样式（多邻国那种游戏感）
   想改配色：只改下面 :root 里的颜色变量。
   ============================================================ */

:root {
  --green: #58cc02;        /* 主色（按钮、进度） */
  --green-dark: #46a302;   /* 按钮底部的“厚度” */
  --green-light: #d7ffb8;  /* 答对的浅绿背景 */
  --green-text: #3a7a02;
  --blue: #1cb0f6;
  --blue-light: #ddf4ff;
  --blue-text: #0b6ea8;    /* 压在 --blue-light 上的蓝字（对比度 4.85:1；--blue 自己压上去只有 2.15:1） */
  --red: #ff4b4b;
  --red-light: #ffdfe0;
  --red-text: #c0392b;
  --yellow: #ffc800;
  --gray: #767676;         /* 次要文字。原 #afafaf 压白底只有 2.19:1（WCAG AA 要 4.5:1），
                              2026-09-27 按用户拍板调深到 4.54:1。
                              ⚠️ 科技风是深底，另行覆盖回亮灰 —— 见文件末尾 */
  --gray-light: #f7f7f7;
  --line: #e5e5e5;
  --text: #3c3c3c;
  --card: #ffffff;
  --radius: 16px;

  /* 间距（只用这 6 个值） */
  --sp-4: 4px;  --sp-8: 8px;  --sp-12: 12px;
  --sp-16: 16px; --sp-20: 20px; --sp-24: 24px;
  /* 触摸目标最小值 */
  --tap: 44px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--gray-light);
  color: var(--text);
  font-family: system-ui, -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
  -webkit-tap-highlight-color: transparent;
}

button { font-family: inherit; }

.hidden { display: none !important; }

/* ---------- 整体框架：最宽 480px，像手机屏幕 ---------- */
.app {
  max-width: 480px;
  margin: 0 auto;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--gray-light);
  padding-bottom: 82px;              /* 给底部导航留位置 */
}

/* ---------- 顶栏 ---------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 16px;
  background: var(--gray-light);
}
.brand { font-weight: 800; font-size: 16px; color: var(--green); }
.pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 12px;
  font-size: 15px;
  font-weight: 800;
  border-radius: 999px;
  background: var(--card);
  border: 2px solid var(--line);
}
.pill.fire b { color: #ff9600; }
.pill.bolt b { color: var(--blue-text); }   /* 2026-09-27：--blue 压白底只有 2.44:1，换配套的深蓝 */
/* 2026-09-29：给火苗/闪电补单位（「天」「XP」），压得比数字轻一点，不抢视线 */
.pill small { font-size: 11px; font-weight: 600; opacity: .6; }

/* ---------- 页面通用 ---------- */
.views { padding: 4px 16px 20px; }
.sec-title {
  margin: 22px 0 10px;
  font-size: 15px;
  font-weight: 800;
  color: var(--text);
}
.heat-tip {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--gray);
}
.about {
  margin: 18px 0 0;
  font-size: 12px;
  line-height: 1.7;
  color: var(--gray);
  text-align: center;
}

/* ---------- 吉祥物 + 对话气泡 ---------- */
.hero { display: flex; align-items: center; gap: 12px; margin: 6px 0 14px; }
.mascot {
  width: 56px;
  height: 56px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  font-size: 30px;
  background: var(--green-light);
  border-radius: 50%;
}
.mascot.big { width: 96px; height: 96px; font-size: 52px; margin: 0 auto 10px; }
.bubble {
  position: relative;
  flex: 1;
  padding: 12px 14px;
  font-size: 14px;
  line-height: 1.6;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
}

/* ---------- 今日目标卡（进度环） ---------- */
.goal-card {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 16px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.ring-wrap { position: relative; width: 104px; height: 104px; flex: 0 0 auto; }
.ring { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring-bg { fill: none; stroke: var(--line); stroke-width: 10; }
.ring-fg {
  fill: none;
  stroke: var(--green);
  stroke-width: 10;
  stroke-linecap: round;
  /* 2 × π × 52 ≈ 326.7：进度环的总长度 */
  stroke-dasharray: 326.7;
  stroke-dashoffset: 326.7;
  transition: stroke-dashoffset 0.5s ease;
}
.ring-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.ring-center b { font-size: 26px; line-height: 1; color: var(--green); }
.ring-center small { font-size: 11px; color: var(--gray); font-weight: 700; }
.goal-info { flex: 1; }
.goal-line { font-size: 14px; line-height: 2; color: var(--text); }
.goal-line b { color: var(--green); }
.goal-line.dim { color: var(--gray); font-size: 13px; }

/* ---------- 主要按钮（多邻国那种“有厚度”的按钮） ---------- */
.btn-main {
  width: 100%;
  margin: 16px 0 0;
  padding: 16px;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: #fff;
  background: var(--green);
  border: none;
  border-bottom: 4px solid var(--green-dark);
  border-radius: var(--radius);
  cursor: pointer;
  touch-action: manipulation;
}
.btn-main:active { transform: translateY(2px); border-bottom-width: 2px; }
.btn-main:disabled {
  background: var(--line);
  border-bottom-color: #d5d5d5;
  color: var(--gray);
  cursor: default;
}

/* ---------- 今日任务卡 ---------- */
.tasks { display: flex; flex-direction: column; gap: 10px; }
.task {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
}
.task.done { background: var(--green-light); border-color: #b6e88a; }
.task.empty { opacity: 0.5; cursor: default; }
.task-ico { font-size: 24px; width: 32px; text-align: center; }
.task-body { flex: 1; }
.task-body b { display: block; font-size: 15px; }
.task-body span { font-size: 12px; color: var(--gray); }
.task-go {
  font-size: 13px;
  font-weight: 800;
  color: var(--green);
  white-space: nowrap;
}

/* ---------- 学习页：科目卡 + 单元 ---------- */
.subject-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.subject-card .s-ico { font-size: 30px; }
.subject-card .s-name { font-size: 17px; font-weight: 800; }
.subject-card .s-desc { font-size: 12px; color: var(--gray); }

.units { display: flex; flex-direction: column; gap: 10px; }
.unit {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
}
/* 单元行里的「要点 / 方法」按钮：原来只有 31px 高，手机上不好点。
   设计规范要求触摸目标 ≥44px，这里给它撑到 44 —— 只是把可点区域做大，
   字号和外观不变。 */
.unit .mini-btn {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.unit .u-ico { font-size: 24px; }
.unit .u-body { flex: 1; }
.unit .u-name { font-size: 15px; font-weight: 700; }
.unit .u-meta { font-size: 12px; color: var(--gray); margin-top: 4px; }
.ubar { height: 8px; margin-top: 6px; background: var(--line); border-radius: 999px; overflow: hidden; }
.ubar i { display: block; height: 100%; width: 0; background: var(--green); border-radius: 999px; transition: width 0.4s ease; }

/* ---------- 榜单页：对比条 + 热力图 + 成就 ---------- */
.compare { display: flex; flex-direction: column; gap: 12px; }
.cmp-row { display: flex; align-items: center; gap: 10px; }
.cmp-label { width: 46px; font-size: 13px; color: var(--gray); font-weight: 700; }
.cmp-bar { flex: 1; height: 22px; background: var(--card); border: 2px solid var(--line); border-radius: 999px; overflow: hidden; }
.cmp-bar i { display: block; height: 100%; width: 0; border-radius: 999px; transition: width 0.4s ease; }
.cmp-bar i.now { background: var(--green); }
.cmp-bar i.last { background: var(--blue); }
.cmp-val { width: 58px; text-align: right; font-size: 13px; font-weight: 800; }

.heat {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  padding: 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.heat i { aspect-ratio: 1 / 1; background: #ececec; border-radius: 6px; }
.heat i.l1 { background: #d7ffb8; }
.heat i.l2 { background: #8ee05a; }
.heat i.l3 { background: var(--green); }

.badges { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.badge {
  padding: 12px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  font-size: 13px;
  line-height: 1.5;
}
.badge.locked { opacity: 0.45; }
.badge b { display: block; font-size: 14px; margin-bottom: 2px; }

/* ---------- 我的：数据 + 目标 + 管理 ---------- */
.stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.stat {
  padding: 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
}
.stat b { display: block; font-size: 22px; color: var(--green); }
.stat span { font-size: 12px; color: var(--gray); }

.goals { display: flex; gap: 10px; }
.goal-btn {
  flex: 1;
  padding: 12px 8px;
  font-size: 14px;
  font-weight: 800;
  color: var(--text);
  background: var(--card);
  border: 2px solid var(--line);
  border-bottom-width: 4px;
  border-radius: 14px;
  cursor: pointer;
}
.goal-btn small { display: block; font-size: 11px; font-weight: 600; color: var(--gray); margin-top: 2px; }
/* ⚠️ 2026-09-27 修：选中的那个目标按钮底色是 --accent-light（第 734 行），
   而这里的 --gray 灰字压上去只有 **1.8:1**，比压在白底上（2.19:1）更糟 ——
   也就是「只有选中的那个才看不清」。浅蓝底上的字按惯例用 --accent-text。 */
.goal-btn.active small { color: var(--accent-text); }
.goal-btn.active { border-color: var(--green); background: var(--green-light); color: var(--green-text); }

.manage { display: flex; flex-direction: column; gap: 10px; }
.btn-ghost, .btn-danger {
  width: 100%;
  padding: 14px;
  font-size: 15px;
  font-weight: 700;
  border-radius: 14px;
  cursor: pointer;
  background: var(--card);
  border: 2px solid var(--line);
  border-bottom-width: 4px;
  color: var(--blue);
}
.btn-danger { color: var(--red-text); }     /* 2026-09-27：--red 压白底只有 3.30:1 */
.btn-ghost:active, .btn-danger:active { transform: translateY(2px); border-bottom-width: 2px; }

/* ---------- 底部导航 ---------- */
.tabbar {
  position: fixed;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: 480px;
  display: flex;
  background: var(--card);
  border-top: 2px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
  z-index: 6;
}
.tab {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 0 12px;
  font-size: 11px;
  font-weight: 700;
  color: var(--gray);
  background: none;
  border: none;
  cursor: pointer;
}
.tab-ico { font-size: 20px; filter: grayscale(1); opacity: 0.6; }
/* 底部导航图标 2026-09-27：emoji → 内联 SVG。
   好处是 stroke="currentColor" 会跟着走：未选中 = --gray，选中 = --accent，
   **不用出两版图、也不用滤镜**（原来 emoji 不会跟着选中态变色，
   字变青了图标还是彩的）。上面那条 grayscale 对灰色 stroke 等于空操作，留着无害。 */
.tab-ico svg { width: 22px; height: 22px; display: block; }
.tab.active { color: var(--green); }
.tab.active .tab-ico { filter: none; opacity: 1; }

/* ---------- 全屏浮层（答题 / 结算） ---------- */
.layer {
  position: fixed;
  inset: 0;
  z-index: 20;
  left: 50%;
  right: auto;
  transform: translateX(-50%);
  width: 100%;
  max-width: 480px;
  background: var(--card);
  display: flex;
  flex-direction: column;
}

/* 答题顶部 */
.quiz-top {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
}
.icon-btn {
  width: 34px;
  height: 34px;
  font-size: 16px;
  font-weight: 800;
  color: var(--gray);
  background: none;
  border: none;
  cursor: pointer;
}
.quiz-bar { flex: 1; height: 14px; background: var(--line); border-radius: 999px; overflow: hidden; }
.quiz-bar-fill { height: 100%; width: 0; background: var(--green); border-radius: 999px; transition: width 0.3s ease; }
.quiz-count { font-size: 13px; font-weight: 800; color: var(--gray); }

/* 答题主体 */
.quiz-body { flex: 1; overflow-y: auto; padding: 8px 16px 160px; }
.quiz-tag {
  display: inline-block;
  padding: 4px 10px;
  font-size: 12px;
  font-weight: 800;
  color: var(--blue-text);   /* 2026-09-27：--blue 压 --blue-light 只有 2.15:1 */
  background: var(--blue-light);
  border-radius: 999px;
}
.quiz-q { font-size: 20px; line-height: 1.6; margin: 14px 0 18px; }
.quiz-options { display: flex; flex-direction: column; }
.opt {
  display: block;
  width: 100%;
  margin-bottom: 10px;
  padding: 14px 16px;
  font-size: 16px;
  font-weight: 600;
  text-align: left;
  color: var(--text);
  background: var(--card);
  border: 2px solid var(--line);
  border-bottom-width: 4px;
  border-radius: 14px;
  cursor: pointer;
  touch-action: manipulation;
}
.opt:active { transform: translateY(2px); border-bottom-width: 2px; }
.opt:disabled { cursor: default; }
.opt.correct { border-color: var(--green); background: var(--green-light); color: var(--green-text); }
.opt.wrong { border-color: var(--red); background: var(--red-light); color: var(--red-text); }

/* ---------- 小步讲堂（2026-10-01 新增）----------
   首页那行入口提示 + 讲堂浮层 + 画板元件。
   画板 HTML 是**预渲染**的（lessons.js 里的 boardHtml），类名统一 bd- 前缀。
   ⚠️ 画板**绝对不能**叫 .layer / .hint 这种通用名 ——
      本文件里 .layer 是「全屏浮层」（position:fixed;inset:0），
      画板行要是也叫 .layer，插进来每一行都会变全屏浮层（踩过）。 */
.hero-go {
  display: block;
  width: 100%;
  margin: 0 0 10px;
  padding: 10px 14px;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 800;
  text-align: center;
  color: var(--blue-text);
  background: var(--blue-light);
  border: 2px solid var(--line);
  border-bottom-width: 4px;
  border-radius: 14px;
  cursor: pointer;
  touch-action: manipulation;
}
.hero-go:active { transform: translateY(2px); border-bottom-width: 2px; }

#lesson-layer .lesson-body { flex: 1; overflow-y: auto; padding: 4px 16px 8px; }
#lesson-layer .lesson-foot {
  padding: 12px 16px calc(14px + env(safe-area-inset-bottom));
  border-top: 2px solid var(--line);
}
.lesson-board {
  background: var(--gray-light);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 14px;
  margin: 6px 0 14px;
}
.bd-hint { color: var(--gray); font-size: 12.5px; text-align: center; margin-bottom: 12px; }
.bd-row { display: flex; align-items: center; gap: 10px; margin-bottom: 9px; opacity: .38; transition: opacity .25s; }
.bd-row .bd-nm {
  flex: 0 0 92px;
  text-align: center;
  font-size: 13px;
  font-weight: 800;
  padding: 9px 0;
  border-radius: 10px;
  background: var(--card);
  border: 2px solid var(--line);
  color: var(--gray);
}
.bd-row .bd-ds { font-size: 12.5px; color: var(--gray); }
.bd-row.on { opacity: 1; }
.bd-row.on .bd-nm { background: var(--green-light); border-color: var(--green); color: var(--green-text); }
.bd-row.on .bd-ds { color: var(--text); }
.bd-arrow { text-align: center; color: var(--gray); font-size: 13px; }
/* 拓扑图元件（2026-10-01 加，服务「网络：网络基础」）——
   坐标是 SVG 里算好的，这里只管颜色；优点/缺点那两行本来就是考点，画在图上省得再念一遍 */
.tp-wrap { display: flex; flex-direction: column; gap: 10px; }
.tp-card { border: 2px solid var(--line); border-radius: 12px; padding: 10px 12px; background: var(--card); }
.tp-card.on { border-color: var(--green); }
.tp-name { font-weight: 800; font-size: 14px; margin-bottom: 2px; }
.tp-tag { font-size: 10.5px; margin-left: 6px; padding: 1px 7px; border-radius: 99px;
  background: var(--green-light); color: var(--green-text); }
.tp-svg { width: 100%; height: 118px; display: block; }
.tp-multi .tp-svg { height: 98px; }
.tp-node { fill: var(--card); stroke: var(--blue); stroke-width: 3; }
.tp-line { stroke: var(--blue); stroke-width: 2.5; opacity: .8; }
.tp-center { fill: var(--blue-light); stroke: var(--blue); stroke-width: 3; }
.tp-lab { font-size: 11px; fill: var(--gray); text-anchor: middle; font-weight: 700; }
.tp-lab-c { fill: var(--blue-text); }
.tp-good { font-size: 12.5px; color: var(--green-text); margin-top: 4px; }
.tp-bad { font-size: 12.5px; color: var(--red-text); margin-top: 2px; }
.tp-multi .tp-good, .tp-multi .tp-bad { font-size: 11.5px; }
/* 服务对比表元件（服务「网络：Internet应用」）——
   三行：服务名 / 端口 / 作用。「端口」态把端口列放大、其余压暗（背诵屏）；
   「安全」态换成网络安全五特性。 */
.sv-wrap { display: flex; flex-direction: column; gap: 8px; }
.sv-row { border: 2px solid var(--line); border-radius: 12px; padding: 9px 12px; background: var(--card);
  opacity: .42; transition: opacity .25s; }
.sv-row.on { opacity: 1; border-color: var(--blue); }
.sv-name { font-size: 14px; font-weight: 800; }
.sv-port { font-size: 13px; font-weight: 800; color: var(--blue-text); margin-top: 2px; }
.sv-use { font-size: 12.5px; color: var(--gray); margin-top: 2px; }
.sv-ports .sv-row.on { opacity: 1; }
.sv-ports .sv-port { font-size: 20px; font-weight: 900; color: var(--green-text); }
.sv-ports .sv-name { font-size: 12.5px; opacity: .75; }
.sv-ports .sv-use { font-size: 11.5px; opacity: .6; }
.sv-safe .sv-row .sv-name { color: var(--green-text); }
.sv-safe .sv-row { border-color: var(--green); }
/* 排障流程元件（服务「网络：组建与故障」）——**顺序本身是考点**，所以画成从上到下的流程；
   `反例` 态把顺序倒过来打红叉，专门治那条最爱考的判断题 */
.fx-wrap { display: flex; flex-direction: column; gap: 2px; }
.fx-step { display: flex; gap: 10px; align-items: flex-start; border: 2px solid var(--line); border-radius: 12px;
  padding: 8px 12px; background: var(--card); opacity: .4; }
.fx-step.on { opacity: 1; border-color: var(--blue); }
.fx-step.bad { opacity: 1; border-color: var(--red); background: var(--red-light); }
.fx-step.dim { opacity: .32; }
.fx-n { flex: 0 0 24px; height: 24px; border-radius: 99px; background: var(--blue-light); color: var(--blue-text);
  font-size: 13px; font-weight: 900; display: flex; align-items: center; justify-content: center; }
.fx-step.bad .fx-n { background: var(--red); color: #fff; }
.fx-t { flex: 1; }
.fx-t b { font-size: 14px; display: block; }
.fx-t span { font-size: 12px; color: var(--gray); }
.fx-down { text-align: center; color: var(--gray); font-size: 13px; line-height: 1.1; }
.fx-note { margin-top: 8px; font-size: 13px; color: var(--green-text); text-align: center; font-weight: 800; }
.fx-cmd { border: 2px solid var(--line); border-radius: 12px; padding: 8px 12px; background: var(--card); }
.fx-k { font-family: Consolas, "Courier New", monospace; font-weight: 800; color: var(--blue-text); font-size: 14px; }
.fx-v { font-size: 12.5px; color: var(--gray); margin-top: 2px; }
/* IP 分类范围条（服务「IP地址与子网」） */
.ip-bar { display: flex; gap: 3px; margin-bottom: 10px; }
.ip-seg { flex: 1; border: 2px solid var(--line); border-radius: 10px; padding: 8px 3px; text-align: center;
  background: var(--card); opacity: .45; }
.ip-seg.on { opacity: 1; border-color: var(--green); background: var(--green-light); }
.ip-seg b { display: block; font-size: 15px; font-weight: 900; }
.ip-seg.on b { color: var(--green-text); }
.ip-seg span { font-size: 10.5px; color: var(--gray); }
.ip-note { font-size: 13px; margin-bottom: 6px; }
.ip-tip { font-size: 12px; color: var(--red-text); }
/* 掩码逐位 AND 演算 ——「掩码是 1 的位不动、是 0 的位清零」要能看见：被清零的位变灰 */
.mk-wrap { display: flex; flex-direction: column; gap: 6px; }
.mk-row { border: 2px solid var(--line); border-radius: 10px; padding: 7px 10px; background: var(--card); }
.mk-row.net { border-color: var(--green); background: var(--green-light); }
.mk-lb { font-size: 11.5px; color: var(--gray); }
.mk-dec { font-size: 14px; font-weight: 800; }
.mk-bin { font-family: Consolas, "Courier New", monospace; font-size: 11px; margin-top: 2px; word-break: break-all; }
.mk-bin i { font-style: normal; }
.mk-bin i.keep { color: var(--text); }
.mk-bin i.zero { color: var(--gray); opacity: .5; }
.mk-bin i.one { color: var(--blue-text); font-weight: 800; }
.mk-and { text-align: center; font-size: 11.5px; color: var(--gray); }
.mk-note { margin-top: 8px; font-size: 13px; }
.bd-empty { opacity: .22; }
/* 方法卡里的「竖式」块（2026-10-01）——
   必须等宽字体：竖式唯一的硬要求就是数位对齐，比例字体会把它画歪。
   art 是纯 ASCII（全角中文和半角数字在等宽字体里宽度不同，混着写必然对不齐）。 */
.how-sec { margin: 16px 0 8px; font-size: 14px; font-weight: 800; color: var(--blue-text); }
.how-shu {
  background: var(--gray-light);
  border: 2px solid var(--line);
  border-radius: 12px;
  padding: 12px 14px;
  margin: 0 0 10px;
  font-family: Consolas, "Courier New", monospace;
  font-size: 13.5px;
  line-height: 1.5;
  white-space: pre;
  overflow-x: auto;
  color: var(--text);
}

.lesson-qtip { font-size: 11.5px; color: var(--gray); margin: 2px 0 6px; }
.lesson-fb { margin-top: 12px; padding: 12px 14px; border-radius: var(--radius); font-size: 14px; line-height: 1.7; }
.lesson-fb.ok { background: var(--green-light); color: var(--green-text); border: 2px solid var(--green); }
.lesson-fb.no { background: var(--red-light); color: var(--red-text); border: 2px solid var(--red); }
#lesson-layer .lesson-say { display: flex; align-items: flex-end; gap: 12px; }
/* ⚠️ .btn-main / .btn-ghost 的原始规则都带 width:100%（它们是给竖排用的），
   放在弹性行里会把空间吃光 —— 「下一步」被挤成竖排、「跳过」反而占大半行（踩过）。
   所以这里必须把 width 收回来。 */
#lesson-layer .lesson-btns { display: flex; gap: 10px; margin-top: 12px; align-items: stretch; }
#lesson-layer .lesson-btns .btn-main { flex: 1 1 auto; width: auto; margin: 0; white-space: nowrap; }
#lesson-layer .lesson-btns .btn-ghost { flex: 0 0 auto; width: auto; white-space: nowrap; }
/* 台词里的强调（剧本写 **…** → 生成时渲染成 <b>）：给点分量，别和正文一样重 */
#lesson-say b { color: var(--green-text); }
#lesson-say code { background: var(--gray-light); border-radius: 4px; padding: 1px 5px; font-size: 13px;
  font-family: Consolas, "Courier New", monospace; color: var(--blue-text); }

/* ---------- 讲义浮层（2026-10-01 新增）----------
   正文的 HTML 是**预渲染**好的（notes.js），类名统一 nt- 前缀。
   ⚠️ 和画板同一个坑：别用 .layer / .hint 这种通用名（.layer 是本文件的全屏浮层）。
   颜色一律走变量 → 三种皮肤自动跟。 */
#notes-layer .nt-head { flex: 1; font-size: 15px; font-weight: 800; color: var(--text); }
#notes-layer .notes-body { flex: 1; overflow-y: auto; padding: 4px 18px calc(26px + env(safe-area-inset-bottom)); }
.nt-h { margin: 20px 0 8px; line-height: 1.45; }
.nt-h1 { font-size: 20px; }
.nt-h2 { font-size: 17.5px; color: var(--green-text); }
.nt-h3 { font-size: 16px; }
.nt-h4 { font-size: 14.5px; color: var(--gray); }
.nt-p { font-size: 14.5px; line-height: 1.85; margin: 10px 0; }
.nt-quote {
  background: var(--gray-light);
  border-left: 4px solid var(--blue);
  border-radius: 8px;
  padding: 10px 12px;
  margin: 12px 0;
  font-size: 14px;
  line-height: 1.8;
  color: var(--gray);
}
.nt-list { margin: 10px 0 10px 20px; font-size: 14.5px; line-height: 1.9; }
.nt-code {
  background: #0f1b2c;
  color: #cfe6f7;
  border-radius: 10px;
  padding: 12px 14px;
  margin: 12px 0;
  font-size: 12.5px;
  line-height: 1.7;
  overflow-x: auto;
  white-space: pre;
  font-family: Consolas, "Courier New", monospace;
}
.nt-table { width: 100%; border-collapse: collapse; margin: 12px 0; font-size: 13px; }
.nt-table th { background: var(--green-light); color: var(--green-text); text-align: left; }
.nt-table th, .nt-table td { border: 1px solid var(--line); padding: 8px 10px; line-height: 1.6; vertical-align: top; }
.nt-hr { border: 0; border-top: 1px dashed var(--line); margin: 20px 0; }
.nt-arrow { color: var(--blue-text); font-weight: 800; padding: 0 2px; }
.notes-body code { background: var(--gray-light); border-radius: 4px; padding: 1px 5px; font-size: 13px;
  font-family: Consolas, "Courier New", monospace; color: var(--blue-text); }
/* 学习页单元行里的「📖 讲义 / 🎬 讲一遍」——
   另起一行放在进度条下面。塞在单元名右边会把名字挤断（"计算机网 / 络基础"），试过。 */
.nt-tools { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.nt-tools .mini-btn { margin: 0; font-size: 12.5px; padding: 7px 11px; }
/* 解析页那排「讲一遍 / 看讲义」按钮 */
.sheet-tools { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.sheet-tools .st-btn {
  font-family: inherit;
  font-size: 13px;
  font-weight: 800;
  padding: 9px 12px;
  border-radius: 10px;
  border: 2px solid var(--line);
  border-bottom-width: 4px;
  background: var(--card);
  color: var(--blue-text);
  cursor: pointer;
}
.sheet-tools .st-btn:active { transform: translateY(2px); border-bottom-width: 2px; }

/* 答题后的反馈条 */
.sheet {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 16px 16px calc(16px + env(safe-area-inset-bottom));
  background: var(--green-light);
  border-top: 2px solid var(--line);
  animation: rise 0.2s ease;
}
.sheet.bad { background: var(--red-light); }
.sheet-head { font-size: 17px; font-weight: 800; margin-bottom: 6px; }
.sheet.bad .sheet-head { color: var(--red-text); }
.sheet.good .sheet-head { color: var(--green-text); }
.sheet-explain { font-size: 14px; line-height: 1.7; color: var(--text); }
@keyframes rise { from { transform: translateY(40px); opacity: 0; } to { transform: none; opacity: 1; } }

/* 结算页 */
.finish-inner {
  margin: auto;
  width: 100%;
  padding: 24px;
  text-align: center;
}
.finish-inner h2 { font-size: 22px; margin: 6px 0 4px; }
.finish-xp { font-size: 32px; font-weight: 800; color: var(--green); margin-bottom: 18px; }
.finish-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 16px; }
.finish-grid .fg {
  padding: 12px 6px;
  background: var(--gray-light);
  border: 2px solid var(--line);
  border-radius: 14px;
}
.finish-grid .fg b { display: block; font-size: 20px; color: var(--text); }
.finish-grid .fg span { font-size: 11px; color: var(--gray); }
.finish-streak { font-size: 14px; line-height: 1.7; color: var(--text); }

/* ---------- 数学计算训练入口（首页） ---------- */
.btn-math {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin: 10px 0 0;
  padding: 14px;
  text-align: left;
  background: var(--card);
  border: 2px solid var(--line);
  border-bottom-width: 4px;
  border-radius: var(--radius);
  cursor: pointer;
}
.btn-math:active { transform: translateY(2px); border-bottom-width: 2px; }
.bm-ico { font-size: 24px; }
.bm-text { flex: 1; }
.bm-text b { display: block; font-size: 15px; color: var(--text); }
.bm-text small { font-size: 12px; color: var(--gray); }
.bm-go { font-size: 13px; font-weight: 800; color: var(--blue-text); }   /* 2026-09-27：--blue 压白底 2.44:1 */

/* ---------- 学习页：学段切换（小学 / 初中 / 职高 / 普高） ---------- */
/* ⚠️ 这两排（学段 / 科目）**故意隐藏滚动条**（2026-10-01）：
   全局那条滚动条样式（见文件末尾"全站滚动条"那段）是为了让默认浅灰不那么扎眼，
   但在手机窄屏上，chip 行底下横着一条杠还是很脏。
   —— 隐藏之后靠"选中的项自动滚到中间、两边各露出半个"来暗示能滑：
      app.js 里 renderLearn 会对两排各做一次 scrollIntoView。 */
.stage-tabs { display: flex; gap: 6px; margin-bottom: 8px; overflow-x: auto; padding-bottom: 2px;
  scrollbar-width: none; -ms-overflow-style: none; }
.stage-tabs::-webkit-scrollbar { display: none; height: 0; }
.stage-tab {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 4px; min-height: 44px; padding: 0 9px;
  font-size: 13px; font-weight: 800; font-family: inherit; white-space: nowrap;
  color: var(--gray); background: var(--card);
  border: 2px solid var(--line); border-radius: 999px; cursor: pointer;
}
.stage-tab.active { color: var(--accent-text); border-color: var(--accent); background: var(--accent-light); }
.stage-tab .st-n { font-size: 11px; font-weight: 700; opacity: .7; }
.subj-empty { padding: 16px; font-size: 13px; line-height: 1.8; color: var(--gray); text-align: center;
  background: var(--card); border: 2px dashed var(--line); border-radius: var(--radius); }

/* ---------- 学习页：科目切换 ---------- */
/* 科目多了要能横向滑，别把字挤成竖排。滚动条跟学段那排一样隐藏掉（理由见上面那段） */
.subj-tabs { display: flex; gap: 8px; margin-bottom: 14px; overflow-x: auto; padding-bottom: 2px;
  scrollbar-width: none; -ms-overflow-style: none; }
.subj-tabs::-webkit-scrollbar { display: none; height: 0; }
.subj-tab {
  flex: 0 0 auto;
  padding: 10px 12px;
  font-size: 13px;
  font-weight: 800;
  color: var(--gray);
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
  cursor: pointer;
  white-space: nowrap;
}
.subj-tab.active { color: var(--green-text); border-color: var(--green); background: var(--green-light); }

.train-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  margin-bottom: 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.train-head .s-ico { font-size: 30px; }
.train-head .s-name { font-size: 17px; font-weight: 800; }
.train-head .s-desc { font-size: 12px; line-height: 1.5; color: var(--gray); }

.lv {
  padding: 1px 6px;
  font-size: 11px;
  font-weight: 700;
  color: var(--blue-text);   /* 2026-09-27：--blue 压 --blue-light 只有 2.15:1 */
  background: var(--blue-light);
  border-radius: 6px;
  vertical-align: middle;
}
.mini-btn {
  padding: 8px 12px;
  font-size: 12px;
  font-weight: 800;
  white-space: nowrap;
  color: var(--blue-text);   /* 2026-09-27：--blue 压 --blue-light 只有 2.15:1 */
  background: var(--blue-light);
  border: none;
  border-radius: 10px;
  cursor: pointer;
}

/* ---------- 计时 ---------- */
.timer {
  display: inline-block;
  margin-top: 10px;
  padding: 4px 10px;
  font-size: 13px;
  font-weight: 800;
  color: #ff9600;
  background: #fff4e5;
  border-radius: 999px;
}

/* ---------- 计算输入区 ---------- */
.answer-area { margin-top: 6px; }
.answer-display {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 62px;
  font-size: 30px;
  font-weight: 800;
  letter-spacing: 2px;
  background: var(--card);
  border: 2px solid var(--line);
  border-bottom-width: 4px;
  border-radius: var(--radius);
}
/* ⚠️ 2026-09-27 修：原来是写死的 #c8c8c8 —— 压在浅色皮肤的白色输入框上只有 **1.67:1**，
   比全站通用的 --gray 还淡，学生看不清「在这里输入答案」这句提示。
   （科技风下反而是 11:1，白得发亮 —— 同一个写死色值，两种皮肤一个太淡一个太亮。）
   改用 --gray：和全站其它提示文字一致，浅色 2.19:1 / 科技风 5.7:1。 */
.ans-ph { font-size: 15px; font-weight: 600; letter-spacing: 0; color: var(--gray); }
.keypad { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 14px; }
.key {
  padding: 16px 0;
  font-size: 20px;
  font-weight: 800;
  color: var(--text);
  background: var(--card);
  border: 2px solid var(--line);
  border-bottom-width: 4px;
  border-radius: 12px;
  cursor: pointer;
  touch-action: manipulation;
}
.key:active { transform: translateY(2px); border-bottom-width: 2px; }
/* ⚠️ 2026-09-27 修：`←` `/` `−` 三个功能键原来是 `color: var(--blue)`（#1cb0f6）
   压在 `--blue-light`（#ddf4ff）上 —— 只有 **2.15:1**，连"大号粗体 ≥3:1"都不够。
   换成 --blue-text（#0b6ea8）= 4.85:1。配合 `--xxx-text` 这个全局惯例（--green-text / --red-text 早就有了）。 */
.key.fn { color: var(--blue-text); background: var(--blue-light); border-color: #cbe9fb; }
.key.ok {
  grid-column: span 2;
  color: #fff;
  background: var(--green);
  border-color: var(--green);
  border-bottom-color: var(--green-dark);
}

/* ---------- 我的：计算能力 ---------- */
.calc-stats { display: flex; flex-direction: column; gap: 10px; }
.calc-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
}
.calc-name { width: 128px; font-size: 13px; font-weight: 700; }
.calc-bar { flex: 1; height: 10px; background: var(--line); border-radius: 999px; overflow: hidden; }
.calc-bar i { display: block; height: 100%; background: var(--green); border-radius: 999px; }
.calc-meta { width: 88px; text-align: right; font-size: 12px; font-weight: 700; color: var(--gray); }

/* ---------- 方法卡 ---------- */
.method-inner { margin: auto; width: 100%; padding: 24px; }
/* ⚠️ 2026-10-04 修：方法卡的内容**可能比屏幕高**（例：长除法的四步推演图 ≈ 700px），
   而 `.layer` 是 fixed 全屏、`.method-inner` 又没限高也没 overflow ——
   结果超出屏幕的那半截**既看不见、也滚不到**（用户截图："下滑不了"）。
   现在：外层 flex 列 + inner 限高 → **只让中间那块滚**，
   「知道了」按钮永远留在屏幕上（要是让它跟着滚，"滚到底才点得到"更难受）。 */
#method-layer .method-inner {
  max-height: 100%;
  display: flex;
  flex-direction: column;
}
#method-layer .method-how {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  min-height: 0;      /* ⚠️ flex 子项默认 min-height:auto，不写这条**滚不动**（经典坑） */
}
.m-emoji { font-size: 44px; text-align: center; }
.method-inner h2 { margin: 8px 0 18px; font-size: 20px; text-align: center; }
.method-how {
  padding: 16px;
  background: var(--gray-light);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.how-line { font-size: 14px; line-height: 1.9; color: var(--text); }

/* ---------- 装到手机（PWA） ---------- */
.install-ok {
  padding: 14px;
  font-size: 14px;
  font-weight: 700;
  color: var(--green-text);
  background: var(--green-light);
  border: 2px solid #b6e88a;
  border-radius: var(--radius);
}
.install-steps {
  padding: 14px;
  font-size: 14px;
  line-height: 2;
  color: var(--text);
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.install-steps b { color: var(--blue-text); word-break: break-all; }   /* 2026-09-27：同上，压白底 */

/* ============================================================
   吉祥物：鲸鱼娘（mascot/*.png，8 个表情）
   ------------------------------------------------------------
   这里只管“怎么动”，换哪个表情由 app.js 决定。
   ============================================================ */
.mascot { position: relative; }
.mascot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  animation: mascot-float 3.2s ease-in-out infinite;
}
@keyframes mascot-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-3px); }
}

/* 达成目标时：小鲸鱼轻轻蹦一下 */
.mascot.happy img { animation: mascot-hop 0.6s ease; }
@keyframes mascot-hop {
  0%   { transform: translateY(0) scale(1); }
  40%  { transform: translateY(-6px) scale(1.06); }
  100% { transform: translateY(0) scale(1); }
}

/* 反馈条里的那只小鲸鱼 */
.sheet-row { display: flex; align-items: flex-start; gap: 12px; }
.sheet-mascot { flex: 0 0 auto; width: 76px; height: 76px; object-fit: contain; }
.sheet-text { flex: 1; min-width: 0; }

/* 有人不喜欢动画：尊重系统设置 */
@media (prefers-reduced-motion: reduce) {
  .mascot img, .mascot.happy img { animation: none !important; }
}

/* ============================================================
   主题色：蓝色（跟 App 图标统一）
   ------------------------------------------------------------
   想再换颜色，只改这一块里的 4 个值就行。
   注意：绿色特意保留给“答对了”用 —— 因为绿色 = 对，是大家的习惯，
   如果把答对也改成蓝色，反而会让人看不懂。
   ============================================================ */
:root {
  --accent: #2b7fff;         /* 主色：按钮、进度环、选中状态 */
  --accent-dark: #1a56d6;    /* 按钮底部的“厚度” */
  --accent-light: #dbeafe;   /* 浅蓝底：选中、吉祥物背景 */
  --accent-text: #1d4ed8;    /* 浅底上的深色文字 */
}

.brand { color: var(--accent); }
.mascot { background: var(--accent-light); }
.ring-fg { stroke: var(--accent); }
.ring-center b { color: var(--accent); }
.goal-line b { color: var(--accent); }
.btn-main { background: var(--accent); border-bottom-color: var(--accent-dark); }
.task-go { color: var(--accent); }
.ubar i { background: var(--accent); }
.cmp-bar i.now { background: var(--accent); }
.heat i.l1 { background: #dbeafe; }
.heat i.l2 { background: #93c5fd; }
.heat i.l3 { background: var(--accent); }
.goal-btn.active { border-color: var(--accent); background: var(--accent-light); color: var(--accent-text); }
.subj-tab.active { border-color: var(--accent); background: var(--accent-light); color: var(--accent-text); }
.stat b { color: var(--accent); }
.quiz-bar-fill { background: var(--accent); }
.finish-xp { color: var(--accent); }
.key.ok { background: var(--accent); border-color: var(--accent); border-bottom-color: var(--accent-dark); }
.calc-bar i { background: var(--accent); }
.tab.active { color: var(--accent); }
.timer { color: #ff9600; }

/* ---------- 知识卡（要点）---------- */
.cards-inner {
  margin: auto;
  width: 100%;
  padding: 20px 18px 24px;
  display: flex;
  flex-direction: column;
  max-height: 92vh;
}
.cards-tip { font-size: 12px; color: var(--gray); text-align: center; margin-bottom: 10px; }
.cards-box {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 4px 2px 12px;
  -webkit-overflow-scrolling: touch;
}
.kcard {
  padding: 12px 14px;
  background: var(--gray-light);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
}
.kcard .kq { font-size: 14px; font-weight: 700; line-height: 1.5; }
.kcard .ka {
  display: none;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
  font-size: 13px;
  line-height: 1.7;
  /* ⚠️ 2026-09-26 修：原来写死 `color: #2b2b2b`（深灰）——
     展开的卡片背景是 `var(--blue-light)`，科技风下那是深青 #0a2d36，
     深灰字压上去只有 **1.03:1**，答案整段看不见（用户第二张截图就是这个）。
     改用 `var(--text)`：浅色皮肤 #3c3c3c（和原来的 #2b2b2b 几乎一样），深色皮肤自动变亮。 */
  color: var(--text);
}
.kcard.open { border-color: var(--blue); background: var(--blue-light); }
.kcard.open .ka { display: block; }

/* ---------- 多选题 ---------- */
.opt.picked { border-color: var(--blue); background: var(--blue-light); }
.multi-tip { font-size: 12px; color: var(--gray); text-align: center; margin: 8px 0 2px; }
.multi-confirm { padding: 14px; border: none; border-radius: var(--radius); background: var(--blue); color: #fff; font-weight: 800; font-size: 15px; }

/* ============================================================
   等级系统
   ============================================================ */
/* 首页顶部的等级条 */
.level-strip {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  margin-bottom: 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.lv-badge {
  flex: 0 0 auto;
  padding: 6px 12px;
  font-size: 15px;
  font-weight: 800;
  color: #fff;
  background: var(--accent);
  border-radius: 999px;
  box-shadow: 0 2px 0 var(--accent-dark);
}
.lv-body { flex: 1; min-width: 0; }
.lv-line { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.lv-line b { font-size: 15px; }
.lv-line span { font-size: 12px; color: var(--gray); white-space: nowrap; }
.lv-bar {
  height: 10px;
  margin-top: 8px;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
}
.lv-bar i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--accent);
  transition: width 0.5s ease;
}
.lv-bar.big { height: 14px; margin: 14px 0 16px; }

/* 「我的」页的等级卡 */
.level-card {
  padding: 16px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.lv-head { display: flex; align-items: center; gap: 14px; }
.lv-big {
  flex: 0 0 auto;
  padding: 10px 14px;
  font-size: 22px;
  font-weight: 800;
  color: #fff;
  background: var(--accent);
  border-radius: 14px;
  box-shadow: 0 3px 0 var(--accent-dark);
}
.lv-big-info { flex: 1; min-width: 0; }
.lv-big-info b { display: block; font-size: 17px; }
.lv-big-info span { font-size: 12px; color: var(--gray); }
.lv-table { display: flex; flex-direction: column; gap: 8px; }
.lv-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  font-size: 13px;
  background: var(--gray-light);
  border: 2px solid transparent;
  border-radius: 12px;
}
.lv-row.now { background: var(--accent-light); border-color: var(--accent); }
.lv-row b { font-size: 14px; color: var(--accent-text); }
.lv-row .lv-t { flex: 1; font-weight: 700; }
.lv-row em { font-style: normal; font-size: 12px; color: var(--gray); }
/* ⚠️ 2026-09-27 修：同 `.skin-btn.active small` —— 当前等级那一行底色是 --accent-light，
   --gray 压上去 1.8:1。浅蓝底上改用 --accent-text。 */
.lv-row.now em { color: var(--accent-text); }

/* 结算页的升级提示 */
.finish-levelup {
  margin: 0 0 16px;
  padding: 12px 14px;
  font-size: 16px;
  font-weight: 700;
  color: var(--accent-text);
  background: var(--accent-light);
  border: 2px solid var(--accent);
  border-radius: var(--radius);
  animation: pop 0.5s ease;
}

/* ============================================================
   皮肤 2：科技风（深色 + 青蓝霓虹）
   ------------------------------------------------------------
   它只改 CSS 变量 + 少量覆盖，所以所有页面自动跟着变。
   想再调：改下面这些颜色即可。
   ============================================================ */
body.skin-tech {
  --accent: #00e5ff;
  --accent-dark: #0097b3;
  --accent-light: #0a2d36;
  --accent-text: #7ff3ff;
  --blue: #00e5ff;
  --blue-light: #0a2d36;
  --blue-text: #7ff3ff;
  --gray-light: #06090d;
  --card: #0d141b;
  --line: #1b2c38;
  --text: #d8f4ff;
  --gray: #7e9aa8;
  --green: #21d07a;
  --green-dark: #17a05e;
  --green-light: #0c2b1f;
  --green-text: #7dffc0;
  --red: #ff5c7a;
  --red-light: #2a1220;
  --red-text: #ffa3b5;
  --radius: 10px;
  background: #06090d;
}

/* 网格背景（科技感来源） */
body.skin-tech::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(0, 229, 255, 0.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 229, 255, 0.055) 1px, transparent 1px);
  background-size: 26px 26px;
}
body.skin-tech .app { position: relative; z-index: 1; background: transparent; }
body.skin-tech .topbar { background: transparent; }
body.skin-tech .tabbar { background: #0a1116; }
body.skin-tech .opt,
body.skin-tech .key,
body.skin-tech .option { background: var(--card); color: var(--text); }
body.skin-tech .key.ok,
body.skin-tech .btn-main,
/* ⚠️ 2026-09-26 补：这几个也都是「--accent 亮底 + 写死的白字」。
   科技风的 --accent 是亮青 #00e5ff，白字压上去只有 **1.54:1**（和上面 .btn-main 当初踩的是同一个坑，
   只是当时只补了 .btn-main 和 .key.ok）。
   是 `_dev-自查-深色皮肤对比度.js` 把全站文字量了一遍才发现的 —— 见 协作须知 第三十节。 */
body.skin-tech .multi-confirm,
body.skin-tech .foot-btn.primary,
body.skin-tech .result-filter .mini-btn.active,
body.skin-tech .cfg-opts .mini-btn.active,
/* ⚠️ 2026-09-27 补漏：**「交卷」按钮**也是「--accent 亮底 + 写死白字」，当初那一批漏了它 ——
   科技风下 **1.54:1**，考试时学生看不见「交卷」两个字。
   （是给对比度自查补上「考试页数字键盘」界面之后才扫出来的 —— 见本文件末尾那段注释。） */
body.skin-tech .icon-btn.exam-submit { color: #04141a; }

/* ⚠️ 2026-09-28 补漏（**同一个坑第四次**）：我新加的「继续做题」按钮 + 用户中心的
   「注册/登录」页签选中态，也是「--accent 亮底 + 写死白字」——
   科技风下实测 **1.54:1**（连 2:1 硬闸都没过）。
   为什么之前自查没扫出来：**「继续做题」卡片没数据时不显示**，而对比度自查跑的是空存档
   → 从来没渲染过它。这次是**人眼看截图先发现**、再用脚本量出来的（量的是 1.54:1）。
   教训：新加的"亮底按钮"必须自己加进这个名单，而且**要拿有数据的存档量一遍**。 */
body.skin-tech .rc-go,
body.skin-tech .uc-tab.active { color: #04141a; }

/* ⚠️ 2026-09-27 修（用户发截图抓到的）：上面那批「亮底 + 深字」的按钮里，
   **只有 .key.ok（数字键盘的「确定」）的底色会被抢走**：
      body.skin-tech .key { background: var(--card) }   ← 特异度 (0,2,1)
      .key.ok            { background: var(--accent) }  ← 特异度 (0,2,0) 输掉
   于是底色退回深色的 --card(#0d141b)，可字色仍被上面的规则钉成 #04141a →
   **算出来 1.01:1，字完全看不见**（实测：字 rgb(4,20,26) 压 rgb(13,20,27)）。
   这个键只在「计算题答题态」出现，而当时的对比度自查只走首页/学习页/我的页/排位页/考试页
   —— **从来没走到那个界面**，所以一直没被发现。
   修法：在这里把底色和边框也一起钉住（特异度 0,3,1，压得过 .key）。
   `#keypad`（计算训练）和 `#exam-keypad`（App 内考试页）用的是同一个 .key.ok，一起修好了。 */
body.skin-tech .key.ok {
  background: var(--accent);
  border-color: var(--accent);
  border-bottom-color: var(--accent-dark);
}
body.skin-tech .btn-main {
  box-shadow: 0 0 0 1px rgba(0, 229, 255, 0.45), 0 0 20px rgba(0, 229, 255, 0.22);
}
body.skin-tech .lv-badge,
body.skin-tech .lv-big {
  color: #04141a;
  box-shadow: 0 0 14px rgba(0, 229, 255, 0.35);
}
body.skin-tech .heat i { background: #101c24; }
body.skin-tech .heat i.l1 { background: #0d3a45; }
body.skin-tech .heat i.l2 { background: #12616f; }
body.skin-tech .heat i.l3 { background: var(--accent); }
/* 数字用等宽字体，更像仪表盘 */
body.skin-tech .pill b,
body.skin-tech .lv-badge,
body.skin-tech .lv-big,
body.skin-tech .ring-center b,
body.skin-tech .stat b,
body.skin-tech .quiz-count {
  font-family: ui-monospace, Consolas, "Cascadia Mono", monospace;
  letter-spacing: 0.5px;
}

/* ============================================================
   皮肤 3：伙伴位（把吉祥物挪到右下角漂浮）
   ------------------------------------------------------------
   首页气泡占满整行，小鲸鱼变成固定在右下角（在底部导航上面）的伙伴。
   ============================================================ */
body.skin-companion .hero { display: block; }
body.skin-companion .bubble { min-height: 60px; display: flex; align-items: center; }
body.skin-companion #mascot {
  pointer-events: none;   /* 别挡住下面的按钮 */
  position: fixed;
  right: 14px;
  bottom: 94px;
  width: 76px;
  height: 76px;
  margin: 0;
  background: transparent;
  border-radius: 0;
  z-index: 9;
  filter: drop-shadow(0 8px 16px rgba(0, 0, 0, 0.18));
}
/* 屏幕宽的时候，把它贴在 App 容器的右边缘内侧，别飞到屏幕角落 */
@media (min-width: 520px) {
  body.skin-companion #mascot { right: calc(50% - 240px + 14px); }
}

/* ============================================================
   皮肤选择器（「我的」页）
   ============================================================ */
.skin-picker { display: flex; flex-direction: column; gap: 10px; }
.skin-btn {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 2px 12px;
  align-items: center;
  padding: 12px 14px;
  text-align: left;
  color: var(--text);
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
}
.skin-btn.active { border-color: var(--accent); background: var(--accent-light); }
.skin-btn i {
  grid-row: 1 / span 2;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.08);
}
.skin-btn b { grid-column: 2; font-size: 15px; }
.skin-btn small { grid-column: 2; font-size: 12px; color: var(--gray); }
/* ⚠️ 2026-09-27 修：选中的那张卡底色是 --accent-light（#dbeafe），
   而 --gray 灰字压上去只有 **1.8:1**（压在白卡上是 2.19:1，所以只有"选中"那张看不清）。
   按本项目的既有惯例，**浅蓝底上的字一律用 --accent-text**（见 .lv-row b / .opt.picked / .subj-tab.active）。 */
.skin-btn.active small { color: var(--accent-text); }

/* ============================================================
   排位模式（和 NPC 一起卷）
   ============================================================ */
.league-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px;
  margin-bottom: 12px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.tier-badge {
  flex: 0 0 auto;
  text-align: center;
  padding: 10px 14px;
  background: var(--accent-light);
  border: 2px solid var(--accent);
  border-radius: 14px;
}
.tier-badge .t-emoji { display: block; font-size: 26px; line-height: 1.2; }
.tier-badge b { display: block; font-size: 14px; color: var(--accent-text); }
.tier-badge small { font-size: 11px; color: var(--gray); }
.league-info { flex: 1; min-width: 0; font-size: 14px; line-height: 1.9; }
.league-info b { color: var(--accent); }
.league-info .dim { font-size: 12px; color: var(--gray); }

.ladder { display: flex; flex-direction: column; gap: 8px; }
.ladder-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--card);
  border: 2px solid var(--line);
  border-left-width: 6px;
  border-radius: 12px;
}
.ladder-row.promote { border-left-color: var(--accent); }
.ladder-row.demote { border-left-color: var(--red); }
.ladder-row.me { background: var(--accent-light); border-color: var(--accent); }
.lr-rank { width: 20px; font-size: 14px; font-weight: 800; color: var(--gray); text-align: center; }
.ladder-row.me .lr-rank { color: var(--accent); }
.lr-emoji { font-size: 24px; width: 30px; text-align: center; }
.lr-body { flex: 1; min-width: 0; }
.lr-name { font-size: 14px; font-weight: 700; }
.lr-tag {
  margin-left: 4px;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 600;
  color: var(--gray);
  background: var(--gray-light);
  border-radius: 6px;
}
.lr-say {
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--gray);
  overflow: hidden;
  text-overflow: ellipsis;
}
.lr-xp { font-size: 15px; font-weight: 800; color: var(--accent); text-align: right; }
.lr-xp small { display: block; font-size: 10px; color: var(--gray); font-weight: 600; }
.lr-talk {
  flex: 0 0 auto;
  padding: 6px 8px;
  font-size: 16px;
  line-height: 1;
  background: var(--gray-light);
  border: 2px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
}
.lr-talk:active { transform: translateY(1px); }

/* 结算页的排名提示 */
.finish-rank {
  margin: 0 0 16px;
  padding: 12px 14px;
  font-size: 15px;
  font-weight: 700;
  color: var(--accent-text);
  background: var(--accent-light);
  border: 2px solid var(--accent);
  border-radius: var(--radius);
  animation: pop 0.5s ease;
}

/* ============================================================
   自动备份卡（「我的」页）
   ============================================================ */
.backup-card {
  padding: 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.backup-line { font-size: 13px; line-height: 1.9; }
.backup-line b { color: var(--accent); }
.backup-line.dim { color: var(--gray); font-size: 12px; word-break: break-all; }
.backup-btns { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.backup-warn {
  margin-top: 10px;
  padding: 10px 12px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--accent-text);
  background: var(--accent-light);
  border: 2px solid var(--accent);
  border-radius: 12px;
}

/* ============================================================
   试卷模式 + 评分模式
   ============================================================ */
/* 考试顶栏 */
.exam-timer {
  flex: 1;
  font-size: 17px;
  font-weight: 800;
  font-family: ui-monospace, Consolas, monospace;
  color: var(--accent);
}
.exam-timer.urgent { color: var(--red); animation: pop 0.6s ease infinite alternate; }
.icon-btn.exam-submit {
  width: auto;
  padding: 6px 14px;
  font-size: 14px;
  font-weight: 800;
  color: #fff;
  background: var(--accent);
  border-radius: 999px;
}
.exam-type { margin-top: 8px; font-size: 12px; font-weight: 700; color: var(--gray); }
.opt.picked { border-color: var(--accent); background: var(--accent-light); color: var(--accent-text); }

/* 答题卡 */
.answer-card {
  margin-top: 18px;
  padding: 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.ac-title { font-size: 13px; font-weight: 800; margin-bottom: 10px; }
.ac-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; }
.ac-cell {
  padding: 8px 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  background: var(--gray-light);
  border: 2px solid var(--line);
  border-radius: 8px;
  cursor: pointer;
}
.ac-cell.done { background: var(--accent-light); border-color: var(--accent); color: var(--accent-text); }
.ac-cell.now { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-light); }
.ac-legend { margin-top: 12px; font-size: 12px; color: var(--gray); display: flex; align-items: center; gap: 6px; }
.ac-legend .dot { width: 12px; height: 12px; border-radius: 4px; background: var(--gray-light); border: 2px solid var(--line); display: inline-block; }
.ac-legend .dot.done { background: var(--accent-light); border-color: var(--accent); }
.ac-legend .dot.now { border-color: var(--accent); }

/* 考试底栏 */
.exam-foot {
  display: flex;
  gap: 8px;
  padding: 12px 16px calc(14px + env(safe-area-inset-bottom));
  border-top: 2px solid var(--line);
  background: var(--card);
}
.foot-btn {
  flex: 1;
  padding: 14px 0;
  font-size: 15px;
  font-weight: 800;
  color: var(--text);
  background: var(--gray-light);
  border: 2px solid var(--line);
  border-radius: 12px;
  cursor: pointer;
}
.foot-btn.primary { color: #fff; background: var(--accent); border-color: var(--accent); }
.foot-btn:disabled { opacity: 0.45; cursor: default; }

/* 成绩单 */
.result-inner { width: 100%; height: 100%; overflow-y: auto; padding: 24px 16px calc(24px + env(safe-area-inset-bottom)); }
.result-head { text-align: center; }
.result-head h2 { font-size: 18px; margin: 6px 0 2px; }
.result-score { font-size: 64px; font-weight: 800; line-height: 1.1; color: var(--accent); }
.result-score small { font-size: 20px; color: var(--gray); margin-left: 4px; }
.result-meta { font-size: 13px; color: var(--gray); line-height: 1.8; }
.result-meta b { color: var(--text); }
.unit-scores { display: flex; flex-direction: column; gap: 10px; }
.result-filter { display: flex; gap: 8px; margin-bottom: 10px; }
.result-filter .mini-btn.active { background: var(--accent); color: #fff; }
.review-list { display: flex; flex-direction: column; gap: 10px; }
.rv-item {
  padding: 12px;
  font-size: 13px;
  line-height: 1.7;
  background: var(--card);
  border: 2px solid var(--line);
  border-left-width: 6px;
  border-radius: 12px;
}
.rv-item.ok { border-left-color: var(--green); }
.rv-item.bad { border-left-color: var(--red); }
.rv-head { font-weight: 700; }
.rv-line { margin-top: 6px; }
.rv-line b.ok { color: var(--green-text); }
.rv-line b.bad { color: var(--red-text); }
.rv-explain { margin-top: 8px; padding: 10px; background: var(--gray-light); border-radius: 8px; color: var(--gray); }
.rv-steps { margin-top: 8px; padding: 10px; background: var(--gray-light); border-radius: 8px; }

/* 考试标签页 */
.papers { display: flex; flex-direction: column; gap: 10px; }
.paper {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
}
.exam-config, .exam-date-card, .exam-history {
  padding: 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.cfg-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.cfg-row > span { width: 40px; font-size: 13px; color: var(--gray); }
.cfg-opts { display: flex; flex-wrap: wrap; gap: 6px; }
.cfg-opts .mini-btn.active { background: var(--accent); color: #fff; }
.date-input {
  padding: 12px;
  font-size: 15px;
  font-family: inherit;
  color: var(--text);
  background: var(--gray-light);
  border: 2px solid var(--line);
  border-radius: 12px;
}
.trend { display: flex; align-items: flex-end; gap: 6px; height: 84px; margin-bottom: 10px; }
.trend-bar { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; }
.trend-bar i { display: block; width: 100%; min-height: 4px; background: var(--accent); border-radius: 6px 6px 0 0; }
.trend-bar span { font-size: 10px; color: var(--gray); margin-top: 4px; }
.his-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  font-size: 13px;
  border-top: 1px dashed var(--line);
}
.his-row b { color: var(--accent); width: 56px; }
.his-row span { flex: 1; }
.his-row em { font-style: normal; font-size: 11px; color: var(--gray); }

/* 首页倒计时卡 */
.countdown-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  margin-bottom: 14px;
  background: var(--accent-light);
  border: 2px solid var(--accent);
  border-radius: var(--radius);
}
.cd-days { font-size: 34px; font-weight: 800; color: var(--accent); line-height: 1; }
.cd-days small { font-size: 13px; margin-left: 2px; }
.cd-body { flex: 1; min-width: 0; }
.cd-body b { display: block; font-size: 14px; }
.cd-body span { font-size: 12px; color: var(--gray); }

/* ============================================================
   UI 打磨（v0.6.1）
   ------------------------------------------------------------
   1) 选项加 A/B/C/D 标号 —— 成绩单说“正确答案 D”，你得知道 D 是哪个
   2) 考试页加答题进度条
   3) 答题卡吸到底部，不再留一大片空白
   4) 选项改成“立体按钮”风格，和全站统一
   ============================================================ */

/* 选项：左边一个字母徽章 */
.opt {
  display: flex;
  align-items: center;
  gap: 12px;
  text-align: left;
}
.opt-key {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  font-size: 13px;
  font-weight: 800;
  color: var(--gray);
  background: var(--gray-light);
  border: 2px solid var(--line);
  border-radius: 50%;
}
.opt.picked .opt-key,
.opt.correct .opt-key {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent);
}
.opt.correct .opt-key { background: var(--green); border-color: var(--green); }
.opt.wrong .opt-key { color: #fff; background: var(--red); border-color: var(--red); }

/* 考试页：答题进度条 */
.exam-bar {
  height: 6px;
  margin: 0 16px 4px;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
}
.exam-bar i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
  border-radius: 999px;
  transition: width 0.3s ease;
}

/* 考试页：内容竖排，答题卡吸到底部，中间不留空白 */
#exam-layer .quiz-body { display: flex; flex-direction: column; }
#exam-layer #answer-card { margin-top: auto; }
/* 答题卡更紧凑一点 */
#exam-layer .ac-grid { grid-template-columns: repeat(6, 1fr); gap: 6px; }
#exam-layer .ac-cell { padding: 6px 0; font-size: 12px; }

/* 班级考试卡（考试页） */
.class-card { padding: 14px; background: var(--card); border: 2px solid var(--line); border-radius: var(--radius); }

/* ------------------------------------------------------------
   班级卷交卷后：只显示"已交卷"
   卷子由服务器判分（学生端没有答案），所以放成绩单会把分数显示成 0。
   老师「发布答案给全班」之后，学生去答题页 answer.html 点「查分数」看。
   ------------------------------------------------------------ */
#result-layer.class-mode .result-score,
#result-layer.class-mode .sec-title,
#result-layer.class-mode .unit-scores,
#result-layer.class-mode .result-filter,
#result-layer.class-mode .review-list { display: none; }
#result-layer.class-mode .result-meta { font-size: 15px; line-height: 1.8; }
/* 班级卷还没公布答案，"错题重考"这时候没有意义（学生不知道哪题错了） */
#result-layer.class-mode #btn-result-wrong { display: none; }

/* ------------------------------------------------------------
   题库配图（figs.js 当场生成的 SVG）—— 追加在文件末尾
   5 个渲染点共用同一套样式：练习页 / 考试页 / 成绩单回顾 / 讲解模式 / 查分页
   · 没配图的题：.fig-box 是空的 → :empty 收起来，不留空白
   · 图本体自带 viewBox，宽度跟着容器走，320px 窄屏也不会横向溢出
   ------------------------------------------------------------ */
.fig-box { margin: 6px 0 2px; }
.fig-box:empty { display: none; }
.fig-box svg { display: block; width: 100%; height: auto; margin: 10px auto; }
.fig-box .fig-err,
.fig-err {
  font-size: 12px; line-height: 1.7; text-align: center; color: var(--red-text);
  padding: 10px; border: 2px dashed var(--line); border-radius: 12px;
}
/* 查分页那张图单独给一点外边距（它不在 .fig-box 里，是拼进 HTML 的） */
.sc-item > svg { margin: 8px auto 4px; }

/* ------------------------------------------------------------
   判断题（√ / × 两个大按钮）—— 2026-09-26 追加在文件末尾
   题库里判断题用 options: ['√ 正确','× 错误'] 表示；app.js / answer.js
   把它渲染成两个大按钮，不再显示 A/B —— 和纸卷的观感一致。
   用的是既有颜色变量，换皮肤（body.skin-*）时会跟着走。
   ------------------------------------------------------------ */
.judge-box { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-12); }
.judge-opt {
  flex-direction: column; align-items: center; justify-content: center;
  min-height: 96px; padding: var(--sp-12) var(--sp-8); gap: 2px; text-align: center;
}
.judge-mark { font-size: 40px; line-height: 1.05; font-weight: 800; color: var(--text); }
/* 注意：√ / × 的符号颜色不跟着「对错」变 ——
   否则学生答错时会出现「红色的 × 配绿色边框（正确答案）」这种自相矛盾的画面。
   对错只用边框和底色表达（.correct / .wrong）。 */
.judge-sub { font-size: 12px; color: var(--gray); }
.judge-opt.picked { border-color: var(--blue); background: var(--blue-light); }
.judge-opt.correct { border-color: var(--green); background: var(--green-light); }
.judge-opt.wrong { border-color: var(--red); background: var(--red-light); }

/* 答错时的「诊断三件套」：知识点标签 / 常见错因 / 反例 */
.sheet-extra { margin-top: var(--sp-12); display: flex; flex-direction: column; gap: var(--sp-8); }
.point-chip {
  align-self: flex-start; font-size: 12px; padding: 3px 10px; border-radius: 999px;
  /* ⚠️ 2026-09-26 修：这里原来写的是 `background: var(--blue-light); color: #0b6ea8;` ——
     **文字色写死了**。经典蓝下没问题（浅蓝底 + 深蓝字 4.84:1），可一换**科技风**就翻车：
     `--blue-light` 在那边是深色 #0a2d36，深蓝字压在深青底上只有 **2.64:1**，
     12px 小字基本看不见（用户报的"科技风的知识点不会显示"就是这个）。
     现在改用全站通用的「浅底 + 浅底上的文字」配对（`--accent-light` / `--accent-text`，
     style.css 里 20 多处都是这一对）：经典蓝 5.56:1 · 科技风 11.1:1 · 伙伴位同经典蓝。
     **教训：换皮肤会跟着走的只有 CSS 变量，写死的色值一个都不会跟着走。** */
  background: var(--accent-light); color: var(--accent-text);
  /* 知识点里常带一句"口诀"，会比较长：必须限宽换行，
     否则 flex 的 align-self:flex-start 会让它按内容撑开、把整页顶出横向滚动条 */
  max-width: 100%; box-sizing: border-box; line-height: 1.6;
}
.ce-box {
  font-size: 13px; line-height: 1.75; padding: var(--sp-12); border-radius: var(--radius);
  background: var(--gray-light); border: 1px solid var(--line);
  color: var(--text); text-align: left;
}
.ce-counter { border-left: 4px solid var(--blue); }
.btn-ghost {
  align-self: flex-start; font-size: 13px; padding: 8px 14px; border-radius: var(--radius);
  cursor: pointer; background: transparent; color: var(--blue);
  border: 2px solid var(--blue); font-family: inherit;
}
/* ⚠️ 2026-09-27 修：这个按钮出现在「答错」的反馈条里，那条的底色是 --red-light（#ffdfe0 粉），
   而 --blue（#1cb0f6）压上去只有 **1.97:1** —— 答错之后正想点「再来一道同知识点的题」，却看不清。
   改用 --blue-text（#0b6ea8）→ 4.43:1。边框仍是 --blue，外观基调不变。 */
.btn-ghost { color: var(--blue-text); }
.btn-ghost:active { transform: translateY(1px); }

/* ------------------------------------------------------------
   阅读原文（passage）—— 2026-09-26 追加在文件末尾
   文言文 / 现代文阅读题的长材料，渲染在**题干上方**。
   真题的文言文约 600 字、现代文约 1200 字，塞进题干（加粗大字）没法看，
   所以单独一块：小一号字、行距大一点、限高可滚动 —— 手机上不至于把题目顶到屏幕外。
   颜色全走既有变量，**三种皮肤都跟着变**（写死色值就是上次那个坑）。
   ------------------------------------------------------------ */
.passage-box {
  max-height: 42vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  margin-bottom: var(--sp-12);
  padding: var(--sp-12);
  background: var(--gray-light);
  border: 1px solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
  text-align: left;
}
.passage-title {
  font-size: 13px; font-weight: 700; color: var(--accent-text);
  margin-bottom: 6px;
}
.passage-text {
  font-size: 14px; line-height: 1.85; color: var(--text);
  white-space: normal; word-break: break-word;
}
/* 深色皮肤下 --gray-light 是深色，变量已经处理好了；这里只把边框调亮一点，
   免得深色底上看不出这块是个"材料框" */
body.skin-tech .passage-box { background: var(--card); border-color: var(--line); }

/* 我的 → 薄弱知识点 */
.weak-points { display: flex; flex-direction: column; gap: var(--sp-8); }
.weak-row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8);
  padding: 10px var(--sp-12); border-radius: var(--radius);
  background: var(--gray-light); border: 1px solid var(--line);
}
.weak-name { font-size: 13px; color: var(--text); }
.weak-meta { font-size: 12px; color: var(--gray); white-space: nowrap; }
@media (max-width: 360px) {
  .judge-mark { font-size: 34px; }
  .judge-opt { min-height: 84px; }
  /* ⚠️ 2026-10-11 补：学段页签在 320px 下会溢出一截。
     页签是 `flex: 0 0 auto`（宽度按内容算），三个合计 301px > 容器 288px，
     最后那个会被切掉 13px。（那是**老问题**：幼儿园还在时四个页签合计 392px，
     切得更狠 —— 只是 `_自查-学段与版面.js` 以前量的总是最左边那个 chip，从没量到。
     实测数据：`node _dev-量-学段页签.js`。）
     ⚠️ 2026-10-13 更新：学段从 3 个变成 **4 个**（加了「🏫 普高」），
        只在 360px 以下收内边距已经不够了，所以这一档再**藏掉科目数小徽章**：
          390px：基础内边距 9px  → 内容 350 ≤ 容器 358 ✓
          ≤360px：内边距 6px + 藏徽章 → 内容 262 ≤ 容器 288 ✓
        ☠️ 藏徽章**不影响自检**：`_自查-学段与版面.js` 读的是 textContent，
           `display:none` 的元素照样有 textContent —— 所以"每个学段都有科目"那条
           仍然会真验（不是被藏掉就变瞎）。
        **不动高度**：触摸目标 44px 是设计底线，自查也在卡。 */
  .stage-tab { padding: 0 6px; }
  .stage-tab .st-n { display: none; }
}


/* ---------- 首页：成长任务（学段 + 全科发展 + 具体任务）2026-09-27 新增 ----------
   学段页签复用上面的 .stage-tabs / .stage-tab，任务卡复用 .tasks / .task，
   这里只补「全科发展」那一条没有现成样式的部分。
   颜色一律走 CSS 变量，所以换皮肤（含科技风）会自动跟着变。 */
.g-cover {
  margin: 10px 0 12px;
  padding: 12px 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.g-cover-hd { font-size: 13px; font-weight: 800; color: var(--text); margin-bottom: 9px; }
.g-cover-hd span { font-weight: 400; font-size: 12px; color: var(--gray); margin-left: 8px; }
.g-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.g-chip {
  font-size: 11.5px; font-weight: 700; line-height: 1.5;
  padding: 4px 9px; border-radius: 999px; white-space: nowrap;
  background: var(--gray-light); border: 2px solid var(--line); color: var(--text);
}
.g-chip.on { background: var(--green-light); border-color: #b6e88a; color: var(--green-text); }
.g-note { margin-top: 9px; font-size: 12px; line-height: 1.75; color: var(--gray); }

/* ============================================================
   顶栏品牌图标（2026-09-27 加，同日按皮肤补了科技风一版）
   ------------------------------------------------------------
   源图 `design/logo-p3.png`（浅色皮肤用）/ `design/logo-t1.png`（科技风用），
   都是蓝发鲸鱼娘 —— 和 `mascot/` 里是同一个角色。
   经 `scripts/make-icons.mjs` 放大 1.28× 裁掉四角留白，做成满幅方形。

   为什么必须两版：位图自带底色，**不会跟皮肤变**（第一次只做了一版）。
   实测（`scripts/audit-skin.mjs`）浅色那版在科技风下**平均亮度 183**，
   是整屏最亮的东西 —— 深色界面上像贴了张纸，这就是用户说的
   「科技感变少了」的真正原因。所以科技风单独出一版霓虹发光的。

   科技风那版额外叠一条**流动光带**：青色高光斜着扫过，2.8 秒一轮，
   就是「能量流过」的感觉。纯 transform + mix-blend-mode，走 GPU。

   ⚠️ `.brand` 只在 index.html 用（teacher.html 也引这份 style.css，
      但它没有 .brand / .topbar —— 查过了，不受影响）。
   ============================================================ */
.brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}
.brand-ico {
  position: relative;
  width: 26px;
  height: 26px;
  flex: none;
  display: block;
  border-radius: 8px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .16);
  animation: brand-float 3.6s ease-in-out infinite;
}
.brand-ico img { width: 100%; height: 100%; display: block; border-radius: 8px; }
/* 默认（经典蓝 / 伙伴位）只看浅色那版
   ⚠️ 必须写成 `.brand-ico .bi-tech`（两个类）——
   上面 `.brand-ico img`（一个类+一个元素）特异度更高，
   直接写 `.bi-tech { display:none }` 会被它盖掉，结果两枚图标同时显示。
   （和设计规范第六节那次 `.key.ok` 输给 `body.skin-tech .key` 是同一个病根） */
.brand-ico .bi-tech { display: none; }
.brand-ico .bi-flow { display: none; }
/* 科技风：换霓虹版 + 叠流动光带 */
body.skin-tech .bi-light { display: none; }
body.skin-tech .bi-tech { display: block; }
body.skin-tech .bi-flow {
  display: block;
  position: absolute;
  inset: 0;
  border-radius: 8px;
  overflow: hidden;
  pointer-events: none;
  background: linear-gradient(115deg,
    rgba(255, 255, 255, 0) 38%,
    rgba(150, 250, 255, .50) 47%,
    rgba(255, 255, 255, .90) 50%,
    rgba(150, 250, 255, .50) 53%,
    rgba(255, 255, 255, 0) 62%);
  background-size: 260% 260%;
  mix-blend-mode: screen;
  animation: brand-flow 2.8s linear infinite;
}
@keyframes brand-flow {
  from { background-position: 165% 0; }
  to   { background-position: -65% 0; }
}
/* 轻轻浮沉，幅度只有 3px —— 是「活着」的感觉，不是蹦迪 */
@keyframes brand-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-3px); }
}
/* 系统开了「减少动态效果」就静止（无障碍） */
@media (prefers-reduced-motion: reduce) {
  .brand-ico { animation: none; }
  body.skin-tech .bi-flow { animation: none; }
}

/* ============================================================
   全站滚动条（2026-09-27 补）
   ------------------------------------------------------------
   原来一条滚动条样式都没有，用的是浏览器默认的浅灰 —— 在科技风
   （深色）下特别扎眼：`.stage-tabs`（学段）/ `.subj-tabs`（科目）
   这些 overflow-x:auto 的行，底下会横着一条白杠。
   用中性半透明灰：深浅底上都看得见，又不像品牌色那样抢眼。
   （这里**故意不用品牌变量**：滚动条是"系统配件"，不该跟皮肤色走。）
   ============================================================ */
* { scrollbar-width: thin; scrollbar-color: rgba(136, 146, 160, .45) transparent; }
*::-webkit-scrollbar { width: 6px; height: 6px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: rgba(136, 146, 160, .45); border-radius: 6px; }
*::-webkit-scrollbar-thumb:hover { background: rgba(136, 146, 160, .72); }
*::-webkit-scrollbar-corner { background: transparent; }

/* ============================================================
   深色皮肤下 html 也要跟着变暗（2026-09-27 补）
   ------------------------------------------------------------
   `html, body { background: var(--gray-light) }`（第 34 行）里，
   皮肤变量只覆盖在 `body.skin-tech` 上，而 **html 是 body 的父元素，
   拿不到那个覆盖** → html 一直是浅色的 #f7f7f7。
   平时被深色 body 盖住看不见，但手机上**下拉回弹会闪白边**。
   `:has()` 现代浏览器都支持；不支持的老浏览器维持原样，不会更糟。
   ⚠️ 值只能写死这一次：变量定义在 body 上，html 看不见它。
   ============================================================ */
html:has(body.skin-tech) { background: #06090d; }

/* ============================================================
   科技风下的 emoji 处理（2026-09-27 补）
   ------------------------------------------------------------
   用户：「底部 tab 的 🏠📚📝🏆👤 和卡片里的 🧮🔄🧯 —— 三种皮肤完全一样，
   彩色 emoji 在深色科技风里有点跳」。
   实测（`scripts/survey-emoji-dom.mjs`）真正渲染的 emoji 有 **51 种**，
   其中结构性 15 种；好消息是 emoji 已经包在专用元素里，
   所以**纯 CSS 就能处理，一个字标记都不用改**。

   做法：grayscale → sepia → hue-rotate(140deg) 转青色 → saturate 拉满。
   四个方案的实拍对比在 `.auth/emoji-*.png`，单色青明显最整洁
   （最刺眼的是红 🧯 灭火器和黄 ✨ 星星，压完立刻像一套真图标）。

   ⚠️ 只挑「emoji 独占元素」的三个类。三处**刻意不处理**：
      · `.stage-tab`（🧸 幼儿园）/ `.g-chip`（💻 计算机专业课）——
        emoji 和文字混在同一行，过滤整块会把文字一起染色，要改得先包 span
      · 排位奖牌 🥉🥈🥇 —— **颜色就是段位语义**（铜/银/金），压成青色等于毁掉段位系统
      · 排位海怪 🦈🐙🐚🐬🦀🐢🐟🐳 —— 鲸鱼主题配海洋生物是**有意设计**，保留彩色
   ============================================================ */
body.skin-tech .task-ico,
body.skin-tech .u-ico {
  filter: grayscale(1) brightness(1.75) sepia(1) hue-rotate(140deg) saturate(6);
}
/* ⚠️ `.tab-ico` 2026-09-27 从这里**移出去了** —— 它的 emoji 已换成内联 SVG，
   再套青色滤镜会把 SVG 的 stroke 也染色，选中态的 --accent 就白变了。 */

/* ============================================================
   深色皮肤下 --gray 要回亮（2026-09-27 补）
   ------------------------------------------------------------
   上面把 --gray 从 #afafaf 调到 #767676（治浅底 2.19:1），
   但科技风的底是 #0d141b —— #767676 压上去只有 4.14:1，
   **比原来的 8.57:1 还差**。深底上的次要文字得往亮里走。
   ============================================================ */
body.skin-tech { --gray: #afafaf; }

/* ============================================================
   任务卡图标（2026-09-27：emoji → 内联 SVG）
   ------------------------------------------------------------
   原来 `.task-ico` 里放的是 emoji（🔁🧯✨🎯🔥🎉）。emoji 的字形**颜色由系统
   字体决定，不认 CSS 的 currentColor** —— 换肤跟不上、选中态也改不了，
   在深色科技风里就是一块彩色贴纸（用户报「有点跳」）。
   现在图标是 app.js 里 `taskIco()` 生成的内联 SVG，走 stroke="currentColor"，
   颜色由这一行决定，三种皮肤自动跟。
   ⚠️ `.task-ico` 原来没有背景色 —— 截图里那个"蓝色方块"是 emoji 自己的字形，
      换成 SVG 之后没有方块了，这是预期内的变化。
   ============================================================ */
.task-ico { color: var(--accent); }
.task-ico svg { width: 24px; height: 24px; display: inline-block; vertical-align: middle; }

/* ============================================================
   开屏动画（2026-09-27 加）
   ------------------------------------------------------------
   用户要的：「打开就是一个转场动画，非常 nice 的那种」。
   定下来的方向（我拍板，用户说"我信你"）：
     · 用 A 方案：图标带光晕入场 → 一道光带斜扫而过 → 两圈波纹扩散 → 标题浮上
     · **配色跟着皮肤走**，不做一套固定色：
         浅色皮肤（经典蓝 / 伙伴位）= 品牌蓝光晕 + 浅底
         科技风                        = 青色霓虹 + 深色底 + 网格
       为什么不选红色/整片彩虹：红在 App 里是「答错」的语义色（设计规范：
       "主色可以随皮肤变，答对的绿和答错的红不能动"）；整片彩虹和干净的
       蓝白基调是两套语言，而且每天开十次，第三十次就腻。
       "五彩斑斓"放进**光带**里（科技风那条是多色的），不铺满整屏。
     · 只在**本次会话第一次打开**时播 —— 见 app.js 的 startSplash()
     · 点一下能跳过；系统开了「减少动态效果」直接不显示

   ⚠️ 图标要两份：浅色皮肤用粉蓝那版，科技风用霓虹那版。
      位图不跟皮肤变，这个坑在 v41 已经踩过一次了。
   ============================================================ */
#splash {
  --sp-main: var(--accent);
  --sp-glow: rgba(43, 127, 255, .42);
  --sp-flow: linear-gradient(115deg, transparent 36%,
    rgba(124, 156, 255, .40) 45%, rgba(255, 255, 255, .96) 50%,
    rgba(124, 156, 255, .40) 55%, transparent 64%);
  position: fixed;
  inset: 0;
  z-index: 99;
  margin: 0 auto;
  max-width: 480px;              /* 跟 App 同宽，桌面上不会糊满整屏 */
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 14px;
  background: var(--gray-light);
  cursor: pointer;
  overflow: hidden;
}
html.no-splash #splash { display: none; }
/* 系统开了「减少动态效果」：根本不显示这一层 */
@media (prefers-reduced-motion: reduce) { #splash { display: none !important; } }

/* 科技风：青色霓虹 + 深色底；光带做成多色的（用户要的"五彩斑斓"放这里） */
body.skin-tech #splash {
  --sp-main: #00e5ff;
  --sp-glow: rgba(0, 229, 255, .50);
  --sp-flow: linear-gradient(115deg, transparent 32%,
    #7c5cff 41%, #ff5cae 46%, #ffffff 50%, #58cc02 54%, #00e5ff 59%, transparent 68%);
  background: #06090d;
  background-image: linear-gradient(rgba(0,229,255,.055) 1px, transparent 1px),
                    linear-gradient(90deg, rgba(0,229,255,.055) 1px, transparent 1px);
  background-size: 26px 26px;
}

#splash .sp-glow {
  position: absolute;
  left: 50%; top: 50%;
  width: 360px; height: 360px;
  margin: -212px 0 0 -180px;     /* 往上提一点，对准图标（图标在视觉中心偏上） */
  border-radius: 50%;
  background: radial-gradient(circle, var(--sp-glow), transparent 68%);
  filter: blur(16px);
  opacity: 0;
  pointer-events: none;
}
#splash .sp-mark { position: relative; width: 96px; height: 96px; opacity: 0; }
#splash .sp-mark img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border-radius: 26%;
  display: block;
  z-index: 2;
}
#splash .sp-img-tech { display: none; }
body.skin-tech #splash .sp-img-light { display: none; }
body.skin-tech #splash .sp-img-tech { display: block; }

#splash .sp-flow {
  position: absolute; inset: 0;
  border-radius: 26%;
  overflow: hidden;
  pointer-events: none;
  z-index: 3;
}
#splash .sp-flow i {
  position: absolute; top: -60%; left: -60%;
  width: 220%; height: 220%;
  background: var(--sp-flow);
  opacity: 0;
}
#splash .sp-rip {
  position: absolute; inset: 0;
  border-radius: 28%;
  border: 2px solid var(--sp-main);
  opacity: 0;
  pointer-events: none;
}
#splash .sp-title {
  font-size: 23px; font-weight: 800; letter-spacing: 4px;
  color: var(--sp-main); opacity: 0;
}
#splash .sp-sub {
  font-size: 12px; letter-spacing: 1.5px;
  color: var(--gray); opacity: 0;
  margin-top: -6px;
}

@keyframes sp-mark-in {
  0%   { transform: scale(.55) translateY(12px); opacity: 0; }
  62%  { transform: scale(1.06) translateY(0);   opacity: 1; }
  100% { transform: scale(1);                    opacity: 1; }
}
@keyframes sp-flow { 0% { transform: translate3d(-58%,-58%,0); opacity: 1 }
                     100% { transform: translate3d(58%,58%,0);  opacity: 1 } }
@keyframes sp-rip { 0% { transform: scale(.82); opacity: 0 }
                    12% { opacity: .9 }
                    100% { transform: scale(2.1); opacity: 0 } }
@keyframes sp-up { 0% { transform: translateY(12px); opacity: 0 }
                   100% { transform: translateY(0);  opacity: 1 } }
@keyframes sp-glow { 0% { opacity: 0; transform: scale(.8) }
                     40% { opacity: .95 }
                     100% { opacity: .5; transform: scale(1.15) } }
/* 退场：整层放大淡出（不回缩，像"穿过"它进主界面） */
@keyframes sp-out { to { opacity: 0; transform: scale(1.09); visibility: hidden } }

#splash.playing .sp-mark  { animation: sp-mark-in .62s cubic-bezier(.2,.9,.25,1) both; }
#splash.playing .sp-glow  { animation: sp-glow 1.5s ease-out both; }
#splash.playing .sp-flow i{ animation: sp-flow 1.15s linear .38s both; }
#splash.playing .sp-rip   { animation: sp-rip 1.5s ease-out .5s both; }
#splash.playing .sp-rip2  { animation-delay: .95s; }
#splash.playing .sp-title { animation: sp-up .5s ease-out .52s both; }
#splash.playing .sp-sub   { animation: sp-up .5s ease-out .66s both; }
#splash.leaving           { animation: sp-out .52s cubic-bezier(.4,0,.6,1) forwards; }

/* ============================================================
   首页「继续上次做题」卡片（2026-09-28）
   依据：《调研-刷题App界面与交互.md》第 1 条 ——
        「把『继续上次做题』做成首屏最大最强的卡片，写清科目、章节、题号和相对时间」
   只在"做到一半"时出现；没有未完成的练习时整张不显示（原来的首页布局一点不动）。
   配色沿用项目变量：主色 --accent（跟皮肤走）、次要文字 --gray、卡片 --card。
   标签用 --blue-light + --blue-text 这一对（文件里注明过是 4.85:1 的安全组合）。
   ============================================================ */
.resume-card {
  background: var(--card);
  border: 2px solid var(--accent);
  border-radius: var(--radius);
  padding: var(--sp-16);
  margin-bottom: var(--sp-16);
}
.resume-card.hidden { display: none; }

.rc-head { display: flex; align-items: center; gap: var(--sp-8); margin-bottom: var(--sp-4); }
.rc-tag {
  font-size: 12px; font-weight: 800; color: var(--blue-text);
  background: var(--blue-light); border-radius: 999px; padding: 2px 10px;
}
.rc-when { font-size: 12px; color: var(--gray); margin-left: auto; }

.rc-title { font-size: 20px; font-weight: 800; color: var(--text); line-height: 1.35; }
.rc-sub { font-size: 13px; color: var(--gray); margin-top: var(--sp-4); }
.rc-sub b { color: var(--blue-text); font-size: 15px; font-weight: 800; }

.rc-bar {
  height: 8px; border-radius: 999px; background: var(--gray-light);
  overflow: hidden; margin: var(--sp-8) 0 var(--sp-12);
}
.rc-bar i { display: block; height: 100%; background: var(--accent); border-radius: 999px; }

.rc-btns { display: flex; align-items: center; gap: var(--sp-8); }
.rc-go {
  flex: 1; min-height: var(--tap);
  font: inherit; font-size: 16px; font-weight: 800; color: #fff;
  background: var(--accent); border: 0; border-radius: 12px; cursor: pointer;
}
.rc-drop {
  min-height: var(--tap); padding: 0 var(--sp-12);
  font: inherit; font-size: 14px; color: var(--gray);
  background: transparent; border: 0; cursor: pointer;
}

/* ============================================================
   首页「怎么练」模式卡（2026-09-28）
   依据：《调研-刷题App界面与交互.md》
     · §0 行业的骨架是「双模式」——**练习和考试必须是两个清晰入口，不是一个入口加开关**
     · §1 首页就是**一整排模式卡，每张配一句人话说明**（驾考类的做法：顺序练习/专项练习/章节练习/易错题/错题本）
     · §1 按可用时长分层：时间短就做几道，时间长就刷整套
   四张卡：按单元练 / 错题本 / 模拟考试 / 快速练几道
   ============================================================ */
.mode-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-8); margin-bottom: var(--sp-16); }
.mode-card {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--sp-12) var(--sp-12) var(--sp-12);
  min-height: 92px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: 14px; text-align: left; cursor: pointer; font: inherit;
  color: var(--text);
}
.mode-card:active { background: var(--gray-light); }
.mode-card .mc-top { display: flex; align-items: center; gap: var(--sp-4); }
.mode-card .mc-ico { font-size: 20px; line-height: 1; }
.mode-card .mc-name { font-size: 15px; font-weight: 800; }
.mode-card .mc-tip { font-size: 11.5px; color: var(--gray); line-height: 1.5; margin-top: 4px; }
.mode-card .mc-go { font-size: 11.5px; color: var(--blue-text); font-weight: 700; margin-top: auto; }
/* ⚠️ 2026-10-01 修：这里原来是 `margin: -8px 0 …` —— 负的上边距把这一行
   往上拽了 8px，正好钻进上面 `#btn-daily`（.btn-main，带 4px 立体底边）的盒子里。
   12px 的字行高 15px，被压掉 8px = **一半以上看不见**（实测重叠正好 8.0px）。
   隐蔽点：新生（一题没做过）整排是 hidden 的，**只有做过关的学生才看得见** ——
   所以拿干净浏览器截图永远截不到。改成正常正边距。 */
.mode-row-tip { font-size: 12px; color: var(--gray); margin: var(--sp-8) 0 var(--sp-16); }
@media (max-width: 340px) { .mode-row { grid-template-columns: 1fr; } }

/* ============================================================
   成绩单加强（2026-09-28）
   依据：《调研-刷题App界面与交互.md》§9 第 8、9 条
     · 分数旁挂**红色错题角标**
     · 紧跟一行「比上次提高 N 分」
   配色沿用项目的安全配对：**浅底 + 对应深字**（--red-light/--red-text、--green-light/--green-text），
   不用"亮底 + 白字"那一套（那个坑在科技风下只有 1.5:1，见第五十七节）。
   ============================================================ */
.res-badge-row {
  display: flex; justify-content: center; align-items: center;
  gap: var(--sp-8); margin: var(--sp-8) 0 var(--sp-4);
}
.res-badge {
  display: inline-block; padding: 3px 12px;
  font-size: 13px; font-weight: 800; letter-spacing: 0.3px;
  color: var(--red-text); background: var(--red-light);
  border-radius: 999px;
}
.res-badge.all-right { color: var(--green-text); background: var(--green-light); }

.res-compare {
  font-size: 14px; font-weight: 700; line-height: 1.7;
  color: var(--gray); margin-bottom: var(--sp-8);
}
.res-compare.up { color: var(--green-text); }
.res-compare.down { color: var(--red-text); }

/* ============================================================
   9.100 考点卡上的「🗣 听我讲一遍」按钮（2026-10-01 · 讲堂会话）
   见 app.js 9.100 节：cards-dm.js 给每个考点补的卡带 point，
   卡面多这个按钮，点了直接进同考点的讲堂课。
   只用现有变量（--line / --blue / --radius / --tap），不引新依赖。
   ============================================================ */
.kcard-listen {
  display: block;
  width: 100%;
  min-height: var(--tap, 40px);
  margin-top: 10px;
  padding: 8px 12px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: var(--blue-text, var(--accent, #2b7fff));
  background: var(--blue-light, #eef5ff);
  border: 2px solid var(--blue, var(--accent, #2b7fff));
  border-radius: var(--radius, 12px);
  cursor: pointer;
}
.kcard-listen:active { transform: translateY(1px); }
/* ============================================================
   科目形象（2026-10-02 加）
   ------------------------------------------------------------
   学习页「科目卡」左边那个位置，原来是 30px 的 emoji（🧮💻🎬…），
   现在换成该科目的拟人化角色图（icons/subjects/<id>.png，320×320 约 190 KB）。
   图是 app.js 调 subjectArtHtml() 生成的 <img class="s-art">；
   没有专属图的科目仍然显示 emoji，所以这里只负责把图画好。

   ⚠️ 图本身自带深色科技风底（它是从 1024×1024 的插画压下来的），
      所以**三种皮肤下看起来都一样** —— 这是栅格图的固有代价，
      和品牌图标（v41 那批）是同一个问题。浅色皮肤版的图还没做。
   ============================================================ */
.subject-card .s-ico { font-size: 30px; }      /* emoji 兜底时还是 30px */
.subject-card .s-art {
  width: 72px;
  height: 72px;
  border-radius: 18px;
  display: block;
  object-fit: cover;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
}
/* 有图的时候把卡片撑高一点，别让文字挤在 72px 的旁边显得空 */
.subject-card:has(.s-art) { padding: 12px 16px; }
@media (prefers-reduced-motion: no-preference) {
  .subject-card .s-art { transition: transform .25s ease; }
  .subject-card:active .s-art { transform: scale(.96); }
}

/* ------------------------------------------------------------
   科目**页签**上的迷你形象（2026-10-02 晚加）
   ------------------------------------------------------------
   第一版只把形象挂在了科目卡上，用户基本看不见：科目卡只显示选中的那一门，
   而且默认选中的是内置的「数学 · 计算训练」→ 进来就是计算训练面板，科目卡整块 display:none。
   真正一直露在脸上的是这排页签，所以把它的 emoji 换成角色图。

   尺寸刻意取 24px（原来 emoji 也就 18~20px 上下），换完这排页签的总宽度几乎不变，
   不会把原本能露出来的几个科目挤出屏幕。
   vertical-align: middle 而不是默认的 baseline —— 24px 的图按 baseline 对齐会整个飘到字上面去。
   ------------------------------------------------------------ */
.subj-tab .s-art-tab {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  object-fit: cover;
  vertical-align: middle;
  margin-right: 5px;
  /* 选中态那抹浅绿/浅蓝底上，圆的深色描边会让图看起来"贴上去"了，所以给个极淡的圈 */
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .06);
}
/* 页签里的 13px 粗体和 24px 的圆并排时，行高会被图顶高 → 把按钮高度锁回来，
   免得换图前后整排页签的高度跳一下 */
.subj-tab:has(.s-art-tab) { display: inline-flex; align-items: center; padding-top: 6px; padding-bottom: 6px; }

/* 「数学 · 计算训练」标题头那个位置（原来是个 30px 的 🧮），
   尺寸和科目卡的 72px 对齐，三个面板的头部看起来才是一套 */
.train-head .s-art {
  width: 72px;
  height: 72px;
  border-radius: 18px;
  display: block;
  object-fit: cover;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
}
.train-head:has(.s-art) { padding: 12px 16px; }

/* ------------------------------------------------------------
   答题反馈条左边那个形象（2026-10-02 晚）
   ------------------------------------------------------------
   原来这里永远是小鲸鱼的 success/failure 表情（透明底的小人，76×76 contain）。
   现在做 Python 题时换成**小蟒的 Q 版全身小人**（icons/chibi/py.png，也是透明底），
   尺寸/对齐方式和小鲸鱼保持一致 —— 这一格要的是"站着的小人"，不是圆头像。

   ☠️ 第一版走错的路，记下来别再走：拿科目卡那张 320×320 方形插画裁成圆头像塞进来。
      「不是要个小人吗」—— 圆形头像和站着的小人不是一种东西，
      而且那张插画自带深色底，贴到绿色反馈条上是一块深色圆饼。
      所以：这里只放**透明底的全身小人**；没配小人的科目退回小鲸鱼，
      **不要**退回方形插画。
   ------------------------------------------------------------ */
.sheet-mascot.is-chibi {
  width: 76px;
  height: 76px;
  object-fit: contain;
  border-radius: 0;
  box-shadow: none;
}

/* ============================================================
   个人资料头（2026-10-02 加）：头像 + 名字 + 等级 + 签名
   ------------------------------------------------------------
   用户要求：「（我的页）这个地方加一下头像和等级和名字，和个人签名」。
   头像从 16 个科目角色里挑（icons/subjects/*.png，方图 → 圆形裁）。
   两种皮肤都要能用，所以颜色全部走变量（--card/--line/--text/--gray/--accent）。
   ============================================================ */
.me-head { margin-bottom: 14px; }
.me-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
/* 头像：圆形，右下角一个小「换」字提示可点 */
.me-ava {
  position: relative;
  flex: 0 0 auto;
  width: 68px;
  height: 68px;
  padding: 0;
  border: 2px solid var(--line);
  border-radius: 50%;
  background: var(--accent-light, #eef4ff);
  overflow: hidden;
  cursor: pointer;
}
.me-ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.me-ava-txt {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  font-size: 28px;
  font-weight: 800;
  color: var(--accent-text, var(--accent));
}
.me-ava-edit {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  font-size: 10px;
  line-height: 15px;
  font-weight: 700;
  color: #fff;
  background: rgba(0, 0, 0, .45);
}
.me-info { flex: 1; min-width: 0; }
.me-name { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.me-name b { font-size: 18px; font-weight: 800; color: var(--text); }
.me-lv {
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 800;
  color: var(--accent-text, var(--accent));
  background: var(--accent-light, #eef4ff);
  border-radius: 999px;
  white-space: nowrap;
}
/* 签名做成一个按钮（点了才能改），所以要把按钮的默认样式抹平 */
.me-sign {
  display: block;
  width: 100%;
  margin-top: 5px;
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
  font-size: 13px;
  line-height: 1.5;
  color: var(--gray);
  cursor: pointer;
}
.me-sign-off { color: var(--accent-text, var(--accent)); font-weight: 700; }

/* 选头像 / 改签名的小浮层（和项目里其它 layer 一个套路） */
.me-layer {
  position: fixed;
  inset: 0;
  z-index: 9998;
  display: none;
  align-items: flex-end;
  justify-content: center;
  background: rgba(0, 0, 0, .45);
  padding: 16px;
}
.me-layer.open { display: flex; }
.me-sheet {
  width: 100%;
  max-width: 460px;
  max-height: 84vh;
  overflow: auto;
  padding: 16px;
  background: var(--card);
  border-radius: 16px;
}
.me-sheet-hd { display: flex; align-items: baseline; gap: 8px; margin-bottom: 12px; }
.me-sheet-hd b { font-size: 16px; font-weight: 800; color: var(--text); }
.me-sheet-hd span { font-size: 12px; color: var(--gray); }
.me-face-grid {
  display: grid;
  /* ⚠️ 必须是 minmax(0, 1fr)，不能只写 1fr ——
     `1fr` 的最小尺寸是 auto，而格子里有「数字媒体技术基础」这种长名字，
     列宽会被文字撑到比 1fr 大 → 整张表横向溢出屏幕（真机上右边那一列直接被切掉）。
     配合 .me-face 上的 min-width:0，名字才会老老实实显示省略号。**踩过，改前先看图。** */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 12px;
}
.me-face {
  min-width: 0;
  padding: 6px 4px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
  cursor: pointer;
}
.me-face.on { border-color: var(--accent); background: var(--accent-light, #eef4ff); }
.me-face img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 10px; display: block; }
.me-face-txt {
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1;
  font-size: 26px;
  font-weight: 800;
  color: var(--accent-text, var(--accent));
  background: var(--accent-light, #eef4ff);
  border-radius: 10px;
}
.me-face em {
  display: block;
  margin-top: 4px;
  font-size: 10px;
  font-style: normal;
  line-height: 1.3;
  color: var(--gray);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.me-sign-in {
  width: 100%;
  padding: 11px 12px;
  font-size: 15px;
  color: var(--text);
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
}
.me-sheet-btns { display: flex; gap: 8px; margin-top: 12px; }
.me-sheet-btns .btn-main, .me-sheet-btns .btn-ghost { flex: 1; }

/* ============================================================
   任务闯关 / 新手引导（2026-10-02 加）
   ------------------------------------------------------------
   首页那条「任务闯关 n/12」+ 点开后的任务列表。
   引导不做蒙层：**第一条任务链就是新手引导**，做完自动从首页收起来。
   颜色全走变量，两种皮肤都能用。
   ============================================================ */
.quest-strip {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin-bottom: 12px;
  padding: 12px 14px;
  text-align: left;
  background: var(--card);
  border: 2px solid var(--accent);
  border-radius: var(--radius);
  cursor: pointer;
}
.quest-strip .qs-ico { font-size: 22px; flex: 0 0 auto; }
.quest-strip .qs-body { flex: 1; min-width: 0; }
.quest-strip .qs-body b {
  display: block;
  font-size: 15px;
  font-weight: 800;
  color: var(--text);
}
.quest-strip .qs-body b em {
  font-style: normal;
  font-size: 12px;
  font-weight: 800;
  color: var(--accent-text, var(--accent));
}
.quest-strip .qs-body span {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--gray);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.quest-strip .qs-go {
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 800;
  color: var(--accent-text, var(--accent));
}

.quest-layer {
  position: fixed;
  inset: 0;
  z-index: 9997;
  display: none;
  align-items: flex-end;
  justify-content: center;
  background: rgba(0, 0, 0, .45);
  padding: 16px;
}
.quest-layer.open { display: flex; }
.quest-sheet {
  width: 100%;
  max-width: 460px;
  max-height: 86vh;
  overflow: auto;
  padding: 16px;
  background: var(--card);
  border-radius: 16px;
}
.quest-hd b { font-size: 17px; font-weight: 800; color: var(--text); }
.quest-hd span { display: block; margin-top: 3px; font-size: 12px; color: var(--gray); }
.quest-bar {
  height: 8px;
  margin: 10px 0 14px;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
}
.quest-bar i { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.quest-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.q-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
}
.q-row.done { border-color: var(--green); background: var(--green-light); }
.q-row.cur { border-color: var(--accent); background: var(--accent-light, #eef4ff); }
.q-row.lock { opacity: .55; }
.q-mark { flex: 0 0 auto; font-size: 15px; width: 18px; text-align: center; }
.q-row.done .q-mark { color: var(--green-text, var(--green)); font-weight: 800; }
.q-body { flex: 1; min-width: 0; }
.q-body b {
  display: block;
  font-size: 14px;
  font-weight: 800;
  color: var(--text);
}
.q-body b em {
  margin-left: 6px;
  font-style: normal;
  font-size: 11px;
  font-weight: 800;
  color: var(--accent-text, var(--accent));
}
.q-body span { display: block; margin-top: 2px; font-size: 12px; line-height: 1.45; color: var(--gray); }
.q-go {
  flex: 0 0 auto;
  padding: 8px 12px;
  font-size: 12px;
  font-weight: 800;
  color: #fff;
  background: var(--accent);
  border: 0;
  border-radius: 10px;
  cursor: pointer;
  white-space: nowrap;
}

/* 任务完成的飘字（项目里原来没有轻提示，这里补一个最小的） */
.quest-toast {
  position: fixed;
  left: 50%;
  bottom: 84px;
  z-index: 9999;
  max-width: 88vw;
  padding: 10px 16px;
  font-size: 13px;
  font-weight: 800;
  color: #fff;
  /* ⚠️ 这里**必须是不透明色**，不能用 rgba(20,20,24,.92)：
     深色皮肤对比度自查解析不了 alpha，会把背景当成页面底色（白）来算 ——
     实测报「1.07:1 白字压白底」，一条本来没问题的样式把自查搞红。
     半透明在这里也没有视觉必要。 */
  background: #1c1c22;
  border-radius: 999px;
  transform: translate(-50%, 12px);
  opacity: 0;
  pointer-events: none;
  transition: opacity .22s ease, transform .22s ease;
}
.quest-toast.on { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) {
  .quest-toast { transition: none; }
}

/* ============================================================
   图解卡 .dg-card（2026-10-03 · 数学图解卡）
   ------------------------------------------------------------
   用在哪儿：答错后的解析页（app.js renderSheetExtra）+ 方法卡（openMethod）。
   内容是一段**内联 SVG**（figs-card.js 当场画），不是图片文件 ——
   所以离线能看、换皮肤自动跟着变色、题库也不会变胖。
   颜色一律走 CSS 变量，和全站一致；深色皮肤不用另写规则。
   ============================================================ */
.dg-card {
  margin-top: 12px;
  padding: 10px 12px 12px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
}
.dg-title {
  font-size: 13px;
  font-weight: 800;
  color: var(--accent-text, var(--accent));
  margin-bottom: 6px;
}
.dg-body svg { display: block; width: 100%; height: auto; }
/* 方法卡里的**分步图**（长除法那种 SVG 竖式，2026-10-04 加）——
   一张图 = 一步，所以每张之间留 8px、外面加一层浅底，和纯文字 tips 分开看。 */
.how-fig {
  margin: 8px 0;
  padding: 6px 8px;
  background: var(--card);
  border: 1.5px solid var(--line);
  border-radius: 12px;
}
.how-fig svg { display: block; width: 100%; height: auto; }
.dg-hint {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--line);
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--gray);
}

/* ============================================================
   分式 .mfrac（2026-10-03 · mathtext.js 的显示层）
   ------------------------------------------------------------
   题库里分数写成 `x²/16`（纯文本），渲染时套上这层就变成真正的分式。
   为什么不用 KaTeX：几百 KB、拖首屏、离线还要多缓存一堆字体。
   这里只要"分子 / 横线 / 分母"三件套，CSS 就够。
   · inline-flex 竖排，vertical-align: middle 让它跟行内文字对齐
   · 字号缩到 .94em，避免行高被撑得太夸张（选项按钮里尤其明显）
   · 横线用 border-bottom + currentColor —— 换皮肤自动跟着字色变
   ============================================================ */
.mfrac {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  margin: 0 2px;
  font-size: .94em;
  line-height: 1.12;
}
.mfrac .mf-n { padding: 0 3px 1px; border-bottom: 1.4px solid currentColor; }
.mfrac .mf-d { padding: 1px 3px 0; }
/* 选项里的分式再缩一档：选项按钮本来就只有 44px 高，
   分式是"两行"结构，不缩的话一个选项会被撑到 90px+，
   四个选项就占掉一屏（实测截图确认过）。
   :has() 本项目已经在用（.subject-card:has(.s-art)），所以不算新依赖。 */
.opt .mfrac { font-size: .78em; margin: 0 1px; line-height: 1.05; }
.opt .mfrac .mf-n { padding: 0 2px; }
.opt .mfrac .mf-d { padding: 0 2px; }
.opt:has(.mfrac) { padding-top: 8px; padding-bottom: 8px; }

/* ============================================================
   根号 .msqrt 与上标 .msup（2026-10-11 · mathtext.js 的显示层）
   ------------------------------------------------------------
   原来只排分数，`√(x²+y²)`、`a^(m/n)` 全是原样文字 —— 高中内容里遍地都是。
   这两块和 .mfrac 同一套哲学：纯 CSS、不引 KaTeX、换皮肤自动跟着字色变。

   · 根号：左边一个 √ 号，右边内容加"上划线"（border-top）——
     上划线就是根号的横杠，这样"根号管到哪儿"一眼可见。
     原来那对括号在视觉上被上划线取代，所以渲染时不再画括号。
   · 上标：字号缩到 .72em 并抬高（vertical-align + position:relative）。
     里面如果还有分式（a^(m/n)），分式自己的竖排会把行撑高，
     所以给 .msup 里的 .mfrac 单独压一档字号。
   ============================================================ */
.msqrt {
  display: inline-flex;
  align-items: flex-start;
  margin: 0 1px;
  vertical-align: middle;
}
.msqrt .msq-s { font-size: 1.06em; line-height: 1.15; }
.msqrt .msq-b {
  border-top: 1.3px solid currentColor;   /* 根号的那根横杠 */
  padding: 1px 3px 0 2px;
  margin-top: 2px;
}
.msup {
  font-size: .72em;
  line-height: 0;
  vertical-align: .52em;
  margin: 0 1px;
}
.msup .mfrac { font-size: 1em; margin: 0 1px; }
/* 选项按钮里再压一档（和 .mfrac 同样的理由：44px 高的按钮经不起撑） */
.opt .msqrt .msq-b { padding: 0 2px 0 1px; }
.opt .msup { font-size: .68em; }
.opt:has(.msqrt), .opt:has(.msup) { padding-top: 8px; padding-bottom: 8px; }

/* ============================================================
   PC（电脑）版适配 · 2026-10-05 · PC 版会话
   ------------------------------------------------------------
   一句话目标：**手机打开是手机，电脑打开是电脑。**
   不是把 480px 拉宽，是 PC 上按电脑的方式重排：
   左侧竖向导航 + 1180 版心 + 该宽的地方宽、该两栏的地方两栏。

   ⚠️ 三条硬约束（违反任何一条就是白做）：
     1. **全部写在 @media (min-width: 900px) 里** —— 手机是主战场，
        手机端一个字都不许变。复核：node _dev-复核-手机零回归.js 比 改前
     2. **只追加**，不动本文件上面任何一段（这仓库多个会话并行改 style.css）
     3. **不写死色值**，只用主题变量（--card/--line/--text/--gray/--accent…），
        深色皮肤 + 科技风皮肤自动跟着走（body.skin-tech 覆盖了 --accent* 四个值）

   ⚠️ 有几处**故意用 float 而不是 grid**：
     首页 / 学习页 / 做题页 / 考试页要的是「两列**各自独立**纵向堆叠」。
     CSS Grid 的行是两列**共享**的 —— 右栏放一张高卡片，左栏同一行会被撑高，
     左栏就出现一大段空白（真踩过：首页右栏"今日任务"400px 会把左栏的吉祥物
     那一行撑到 400px，吉祥物下面空 290px）。要两列独立堆叠，纯 CSS 只有两条路：
     加 wrapper（要改 index.html，违反约束 2）或 float + clear（本文件选的）。
     `clear: left` 让左栏各项只在自己那一列往下堆，右栏走普通流 —— 两列互不干扰。

   断点取 900px：1000~1200 之间是过渡，不为它单独做一套（任务书 §三 的口径）。
   平板横屏（≥900）会直接走 PC 布局，这是**有意的**，不给平板再做第三套。
   ============================================================ */
@media (min-width: 900px) {

  :root {
    --pc-nav: 220px;              /* 左侧竖向导航宽度 */
    --pc-w: min(1180px, 92vw);    /* PC 版心：1440 下 = 1180 = 81.9%（判据要求 ≥75%） */
  }

  /* ============================================================
     ① 外壳：版心 + 左侧竖向导航
     ------------------------------------------------------------
     用户 2026-10-05 拍板：PC 上用**左侧竖向导航**（不是"底部导航拉宽"）。
     理由：PC 上竖向空间不值钱、横向才值钱；底部导航在电脑上反直觉。
     .app 变成 [导航 | 主内容] 两列网格，导航跨满两行（占满整个高度）。
     ============================================================ */
  .app {
    max-width: var(--pc-w);
    padding-bottom: 0;                        /* 手机上这 82px 是给底部导航留位的 */
    display: grid;
    grid-template-columns: var(--pc-nav) minmax(0, 1fr);
    grid-template-rows: auto 1fr;
  }
  .app > .topbar { grid-column: 2; grid-row: 1; padding: 12px 32px; }
  .app > .views  { grid-column: 2; grid-row: 2; padding: 8px 32px 40px; min-width: 0; }

  .app > .tabbar {
    grid-column: 1;
    grid-row: 1 / -1;
    /* 原来是 position:fixed —— fixed 会脱离网格，占不到左边那一列。
       sticky 仍然参与布局，所以能占住第 1 列，往下滚时又一直贴着顶。 */
    position: sticky;
    top: 0;
    align-self: start;
    height: 100dvh;
    width: auto;
    max-width: none;
    left: auto;
    bottom: auto;
    transform: none;
    flex-direction: column;
    justify-content: flex-start;
    gap: 4px;
    padding: 16px 12px;
    border-top: 0;
    border-right: 2px solid var(--line);
  }
  .app > .tabbar .tab {
    flex: 0 0 auto;
    flex-direction: row;                      /* 手机上是"图标在上、字在下"，PC 上并排 */
    justify-content: flex-start;
    gap: 12px;
    min-height: var(--tap);
    padding: 12px 14px;
    font-size: 15px;
    border-radius: 12px;
  }
  .app > .tabbar .tab.active { background: var(--accent-light); }
  .app > .tabbar .tab-ico { font-size: 18px; }
  .app > .tabbar .tab-ico svg { width: 22px; height: 22px; }

  /* ============================================================
     ② 全屏浮层：原来也是 480px（.layer 自己的 max-width），
        不放开的话做题页/讲堂/讲义/考试还是手机宽度，双栏根本做不出来。
        .layer 有 transform: translateX(-50%)，所以它同时是
        内部 position:fixed 元素的**包含块** —— 下面考试页的常驻答题卡靠这一点。
     ============================================================ */
  .layer { max-width: var(--pc-w); }

  /* 键位提示（由 pc-keys.js 自己 createElement 造，不进 index.html 的 DOM）。
     ⚠️ 样式**只写在这个媒体查询里**：手机上这个元素根本不会被创建，
        所以"手机端零回归"不靠这条 CSS 兜底，而是 JS 侧同一个 900px 闸门。 */
  .pc-key-hint {
    flex: 0 0 auto;
    font-size: 12px;
    color: var(--gray);
    white-space: nowrap;
  }

  /* ============================================================
     ③ 做题页（★ 任务书里优先级最高）：左原文 / 右题目
     ------------------------------------------------------------
     原来题干 + 选项挤在 480px 里，长题干和阅读原文要滚十几屏。
     PC 上左右分栏：左原文可滚，右题干 + 选项。
     **只在真有原文时才分栏** —— 没原文的题，一栏居中更好看，
     也避免右半屏整片空着（`:has()` 本项目已在用，不算新依赖）。
     ============================================================ */
  #quiz-layer .quiz-body { padding: 24px 32px 150px; }
  #quiz-layer .quiz-body::after { content: ''; display: block; clear: both; }

  #quiz-layer .quiz-body:has(#quiz-passage:not(.hidden)) > #quiz-passage {
    float: left;
    width: calc(50% - var(--sp-12));
    margin-right: var(--sp-24);
    margin-bottom: var(--sp-20);
    max-height: min(72vh, 620px);             /* 手机上 42vh 太矮，PC 上给足 */
  }
  #quiz-layer .quiz-body:has(#quiz-passage:not(.hidden)) > *:not(#quiz-passage) {
    margin-left: calc(50% + var(--sp-12));
  }
  /* 分栏后右栏变窄，题干别再用手机的 20px，否则折行折得很难看 */
  #quiz-layer .quiz-body:has(#quiz-passage:not(.hidden)) > .quiz-q { font-size: 19px; }

  /* 反馈条（解析）在 PC 上别拉满 1180 —— 一行 1180px 的字没人读得下去 */
  #quiz-layer .sheet > * { max-width: 900px; margin-left: auto; margin-right: auto; }

  /* ============================================================
     ④ 讲堂：左「小人 + 对话」右「板书区」
     ------------------------------------------------------------
     浮层本身已经是 flex 竖列（.quiz-top / .lesson-body / .lesson-foot），
     PC 上改成网格：顶部进度条跨两列，左边说话、右边板书。
     ============================================================ */
  #lesson-layer {
    display: grid;
    grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }
  #lesson-layer > .quiz-top    { grid-column: 1 / -1; grid-row: 1; }
  #lesson-layer > .lesson-foot {
    grid-column: 1; grid-row: 2;
    /* ⚠️ 是 flex-start 不是 flex-end：手机上"小人说话"固定在屏幕底部（像视觉小说），
       但 PC 上搬进左栏后，flex-end 会把气泡压到左下角、整个左上角空一大片，
       而右边的板书是从顶部开始的，两边不对齐（第一版实拍确认过）。
       顶对齐后「谁在说 / 板书」两个栏头在一条线上。 */
    display: flex; flex-direction: column; justify-content: flex-start;
    border-top: 0;
    border-right: 2px solid var(--line);
    padding: 16px 20px;
  }
  #lesson-layer > .lesson-body { grid-column: 2; grid-row: 2; padding: 16px 32px; }
  /* 板书区在 PC 上左右更宽，行内文字别跟着拉太长 */
  #lesson-layer .lesson-board { padding: 20px 24px; }

  /* 讲义：正文限宽居中（一行太长反而难读） */
  #notes-layer .notes-body { max-width: 880px; margin: 0 auto; width: 100%; }

  /* 结算 / 方法卡 / 知识卡：都限宽居中，别在 1180 里摊成一整行 */
  .finish-inner, .method-inner, .result-inner, .cards-inner { max-width: 760px; margin-left: auto; margin-right: auto; }

  /* ============================================================
     ⑤ 首页：两栏
        左 = 吉祥物 + 目标环 + 主按钮（视觉焦点）
        右 = 今日任务 + 倒计时 + 计算训练 + 成长 + 公告卡
     ------------------------------------------------------------
     用 :not() 兜住右栏，**不逐个点名** —— 首页会被别的会话往里插新卡片
     （notice.js 就往 #growth 后面插「这一版新加了什么」），
     点名的写法每来一张新卡就要改一次 CSS，漏了就会出现横跨两列的大块。
     ============================================================ */
  #view-home::after { content: ''; display: block; clear: both; }

  #view-home > #hero,
  #view-home > #hero-go,
  #view-home > .goal-card,
  #view-home > #btn-daily {
    float: left;
    clear: left;
    width: calc(52% - var(--sp-12));
    margin-right: var(--sp-24);
    margin-bottom: var(--sp-16);
  }
  /* 等级条和最上面那条状态带横跨整幅 */
  #view-home > .level-strip { margin-left: 0; margin-right: 0; }
  /* 除左栏那四件和等级条之外，一律进右栏。
     ⚠️ `width: auto` 不能省：右栏这几件（#btn-math / #quest-strip / .btn-main…）
        自己写着 `width: 100%`，只给 margin-left 的话是「100% 宽 + 478px 偏移」，
        直接冲出屏幕外（实测横向溢出 316px）。auto 才会去填 margin 之后的剩余宽度。 */
  #view-home > *:not(.level-strip):not(#hero):not(#hero-go):not(.goal-card):not(#btn-daily) {
    margin-left: calc(52% + var(--sp-12));
    width: auto;
    max-width: none;
  }
  /* 今日任务：PC 上 2 列网格（手机上是一列到底） */
  #view-home .tasks { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--sp-12); }
  #view-home .goal-card { padding: var(--sp-20); }

  /* ============================================================
     ⑥ 学习页：左「学段 + 科目」常驻，右「单元网格」
     ------------------------------------------------------------
     手机上语文 11 个单元要滚 1.72 屏（实测），PC 上要一屏看完（判据 2）。
     学段/科目挪进左栏常驻，省得每次滚回顶部去选。
     ============================================================ */
  #view-learn::after { content: ''; display: block; clear: both; }

  #view-learn > .sec-title,
  #view-learn > #stage-tabs,
  #view-learn > #subject-tabs {
    float: left;
    clear: left;
    width: 180px;
    margin-right: var(--sp-24);
  }
  /* 手机上这两排是"横向滑"的（overflow-x:auto）；左栏只有 180px，
     改成换行竖排，否则只能看见第一个学段。 */
  #view-learn > #stage-tabs,
  #view-learn > #subject-tabs { flex-wrap: wrap; overflow-x: visible; align-content: flex-start; }

  /* ⚠️ 科目那一列**必须封顶**：职高那一档挂了 **12 门**科目（实测），
     180px 宽里 wrap 就是一列 12 个胶囊 = **571px**，
     比右边整个单元网格还高 —— 判据 2「一屏内」就是被它顶掉的（927 > 900）。
     封顶 + 自己滚 = PC 侧边导航的惯常做法，学段/科目始终在屏幕左边不用回头找。
     ⚠️ 2026-10-13：普高九科单独成档后，职高仍是 12 门、普高 9 门 —— 都在这个封顶之下。 */
  #view-learn > #subject-tabs { max-height: 42vh; overflow-y: auto; }

  #view-learn > .sec-title:first-child { margin-top: 0; }

  #view-learn > #panel-math,
  #view-learn > #panel-subject { margin-left: 204px; }

  /* 单元网格：PC 上要 **3 列**。判据 2 是"11 个单元在 1440×900 一屏内"，
     2 列 = 6 行会到 1.03 屏（实测差 27px）；3 列 = 4 行直接落到 0.8 屏左右。
     列宽下限 205px 是按「左栏 180 + 间距 24 + 版心内宽 896」倒推的：
     剩余 692px，205×3 + 12×2 = 639 ≤ 692 < 205×4，所以稳定是 3 列。 */
  #view-learn .units { display: grid; grid-template-columns: repeat(auto-fill, minmax(205px, 1fr)); gap: var(--sp-12); }
  #view-learn .unit { align-items: flex-start; }
  #view-learn .unit .u-meta { white-space: normal; }

  /* ============================================================
     ⑦ 考试页：左题目 / 右**常驻**答题卡
     ------------------------------------------------------------
     答题卡用 position:fixed —— 因为 .layer 有 transform，
     它就是这层浮层内部的"视口"，所以 right:32px 是相对**版心右边缘**，
     不用去算 (100vw - 版心)/2。好处：左栏题目滚到底，答题卡一直在。
     左栏用 padding-right 给它让位（fixed 元素不占流）。
     ============================================================ */
  #exam-layer .quiz-body { padding: 20px 32px 24px; padding-right: calc(300px + var(--sp-24) + 32px); }
  #exam-layer .quiz-body::after { content: ''; display: block; clear: both; }
  #exam-layer #answer-card {
    position: fixed;
    top: 76px;                                /* 让开 .quiz-top */
    right: 32px;
    width: 300px;
    max-height: calc(100dvh - 76px - 84px);   /* 再让开底部 .exam-foot */
    overflow-y: auto;
    margin: 0;
  }
  #exam-layer .ac-grid { grid-template-columns: repeat(5, 1fr); }
  /* 考试卷里也有长原文（文言文/现代文），同样左右分栏 */
  #exam-layer .quiz-body:has(#exam-passage:not(.hidden)) > #exam-passage {
    float: left;
    width: 340px;
    margin-right: var(--sp-24);
    margin-bottom: var(--sp-20);
    max-height: min(70vh, 560px);
  }
  #exam-layer .quiz-body:has(#exam-passage:not(.hidden)) > *:not(#exam-passage):not(#answer-card) {
    margin-left: calc(340px + var(--sp-24));
  }
  #exam-layer .exam-foot { padding: 14px 32px; }

  /* ============================================================
     ⑧ 考试 / 成绩 / 排位 / 我的：把"单列到底"改成网格
     ============================================================ */
  .papers { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: var(--sp-12); }
  #exam-history { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: var(--sp-12); }
  #exam-history > * { margin-top: 0 !important; }

  .ladder { display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: var(--sp-8); }
  .compare { display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: var(--sp-12); }
  .badges { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
  .heat { max-width: 620px; }

  .stats { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  .skin-picker { flex-direction: row; flex-wrap: wrap; }
  .skin-picker .skin-btn { flex: 1 1 300px; }
  .goals { flex-wrap: wrap; }
  .goals .goal-btn { flex: 1 1 120px; }
  .calc-stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: var(--sp-8); }
  .weak-points { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: var(--sp-8); }
  .manage { display: flex; flex-wrap: wrap; gap: var(--sp-12); }
  .manage > button { flex: 1 1 220px; width: auto; }

}

/* ============================================================
   科技风 · 动态层（2026-10-05 · PC 版会话）
   ------------------------------------------------------------
   用户口径：「**动态的科技感可以做的吗**」——
   科技风现在是全站默认皮肤（见 index.html 的 #skin-early + skin-default.js），
   这一层给它加上"活着"的感觉。

   ⚠️ **两条硬闸门，缺一个都不许合**：

   1. **全部关在 `@media (prefers-reduced-motion: no-preference)` 里。**
      系统里开了"减少动态效果"的人（前庭功能敏感、晕动症）看到的是**完全静止**的科技风。
      这不是可选项 —— 本文件里早就有三处 `prefers-reduced-motion: reduce` 的降级
      （splash / .bi-flow / .quest-toast），这一层跟着同一条规矩走。
      副作用是好的：**所有截图/量版面脚本都用 `reducedMotion:'reduce'`**，
      所以它们量到的永远是"静止态"，动效不会把验收数字搞成随机的。

   2. **持续动效只给 PC（≥900px），手机只留"一次性"的。**
      理由不是审美，是**性能与电量**：手机是主战场、还多是低端安卓，
      让一个全屏图层 24 小时不停地合成，换来的只是背景在飘 —— 不划算。
      所以：
        · **手机也有**：卡片入场（0.26 秒，一次就完）、进度条流光（答题时才跑）
        · **只在 PC**：网格漂移、霓虹呼吸（都是**持续**动画）
      想改成"手机也飘"，把下面那个 `@media (min-width: 900px)` 挪掉即可，一行的事。

   ⚠️ 动效**一律不许碰布局**：只用 `opacity` / `transform` / `filter` / `background-position`。
      不许动 width/height/margin/padding —— 那会让 `_自查-学段与版面.js` 那类
      "量位置和高度"的自查，在动画中间取到中间值，变成假红。
      （同理：**入场动画不放在 `.fig-box` 上**，`_自查-配图观感.js` 是靠截图看配图的。）

   ⚠️ 颜色只用主题变量 + `transparent`（那是关键字不是色值），
      所以这个皮肤哪天换成紫色霓虹，这一层不用改。
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {

  /* ---------- ① 卡片入场（手机 / PC 都有） ----------
     不用一行 JS：`.hidden` 是 `display:none`，元素从 none 变成有显示时
     **浏览器会自动重放 animation**，所以切页面天然就有入场效果。

     ☠️ 第一版是写在 `> *`（每个直接子元素）上的，**被实测抓出一个真冲突**：
        `body.skin-tech .view:not(.hidden) > *` 特异度 (0,3,1) 比
        `body.skin-tech .btn-main` (0,2,1) **高**，而 `animation` 是简写、
        一个元素只能有一个赢 → 首页那个主按钮（#btn-daily 正好是 #view-home 的直接子元素）
        **上面只剩下入场动画，PC 的霓虹呼吸被整个顶掉**。
        （自查里量出来的：`.btn-main → tech-in 0.26s 1`，期望是 tech-breathe。）
        改成**动画加在 `.view` 容器上**，子元素身上的 animation 就完全自由了。
     顺带两个好处：整页一起淡入比八张卡各动各的更干净；也不用担心某个子元素被漏掉。

     ⚠️ 加 `transform` 会让元素变成 `position:fixed` 后代的包含块 ——
        但这里是 `.view`，而科技风下 `.view` 里没有 fixed 后代
        （唯一一个是伙伴位皮肤的 `#mascot`，而 `applySkin()` 是**互斥** toggle 的，
          科技风和伙伴位不会同时挂上）。动画结束落在 `transform: none`，也不留包含块。 */
  @keyframes tech-in {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
  }
  body.skin-tech .view:not(.hidden) {
    animation: tech-in .26s cubic-bezier(.22, .61, .36, 1) both;
  }

  /* ---------- ② 进度条流光（手机 / PC 都有；只在答题/推进时跑） ----------
     底色不动（还是各元素原来的 --accent / --green），只叠一条**无色的**高光带扫过去。
     高光核心用 --text（科技风下是近白的 #d8f4ff），压在同色系底上才看得见。 */
  @keyframes tech-sweep {
    from { background-position: -60% 0; }
    to   { background-position: 160% 0; }
  }
  body.skin-tech .quiz-bar-fill,
  body.skin-tech .ubar i,
  body.skin-tech .exam-bar i {
    background-image: linear-gradient(90deg,
      transparent 0%, var(--accent) 42%, var(--text) 50%, var(--accent) 58%, transparent 100%);
    background-size: 45% 100%;
    background-repeat: no-repeat;
    animation: tech-sweep 1.6s linear infinite;
  }

  /* ---------- ③ 以下都是**持续**动效，只给 PC ---------- */
  @media (min-width: 900px) {

    /* 网格缓慢漂移 —— "科技感"最直接的来源就是这块会动的栅格。
       位移量**正好一个格子（26px）**，所以循环点看不出来，是无缝的。
       ⚠️ 原规则是 `inset: 0`，往左上飘会露边 → 这里放到 `-26px`，
          一个格子的余量，飘到哪都盖满屏。 */
    @keyframes tech-grid-drift {
      from { transform: translate3d(0, 0, 0); }
      to   { transform: translate3d(-26px, -26px, 0); }
    }
    body.skin-tech::before {
      inset: -26px;
      animation: tech-grid-drift 6s linear infinite;
    }

    /* 霓虹呼吸：用 filter: brightness()，**不新增任何颜色** ——
       亮色描边和光晕本来就画好了，这里只是让它们一起明暗一下。 */
    @keyframes tech-breathe {
      50% { filter: brightness(1.16); }
    }
    body.skin-tech .btn-main,
    body.skin-tech .lv-badge,
    body.skin-tech .ring-center b {
      animation: tech-breathe 3.2s ease-in-out infinite;
    }

    /* 左侧导航：选中的那一条滑进来（PC 独有的侧栏才有这个动作） */
    @keyframes tech-nav-in {
      from { opacity: .35; transform: translateX(-6px); }
      to   { opacity: 1; transform: none; }
    }
    body.skin-tech .app > .tabbar .tab.active {
      animation: tech-nav-in .22s ease-out both;
    }
  }
}

/* ============================================================
   科技风 · 未来感升级（2026-10-05 · PC 版会话）
   ------------------------------------------------------------
   用户看完第一版动态科技风后的原话：「**没有未来感**」。这个批评是对的 ——
   原来那套本质上只是"深色 + 淡青"，几何还是**圆角卡片**，
   那是**夜间模式**，不是未来。

   「未来感」真正的来源是**几何和层次**，不是颜色：
     ① HUD 网格 + 扫描线 + 暗角（把平面变成"屏幕"）
     ② **切角面板**（圆角=友好，切角=仪表盘）—— 这一条改动最大、也最一眼看得出来
     ③ 霓虹描边 + 内发光（面板像"发光的玻璃"，不是"贴上去的纸"）
     ④ 标题 / 数字带辉光

   ⚠️ 这一层**在截图里就看得见** —— 不像动效那样只能现场看。
      上一轮我只加了动效，用户截了张图说"没有变化"，这个教训记住了：
      **能进截图的改变才是用户判断得了的改变。**

   @mobile-ok: 科技风**本来就是全站默认皮肤**，改它的样子 = 改全站的样子，
   这不是"PC 改动泄漏到手机"，是用户明确要的方向。三条保证：
     · **不碰布局**：只用 border/box-shadow/clip-path/text-shadow/background，
       不碰 width/height/margin/padding/font-size → 量版面的自查不会变
     · **不写死色值**：新增的半透明霓虹一律从 `--accent` 用 color-mix() 现算
       （旧浏览器走 @supports 兜底，兜底值就是科技风自己那套青色的等价写法）
     · **持续动画另有关闭闸门**：这一层只有一小段落在 reduce 闸门里
   ============================================================ */

/* ---------- ① 派生色令牌：全部从 --accent 现算，皮肤换色时整套跟着走 ----------
   兜底先给"科技风青色"的字面量（和上面 1178 行那个网格是同一套口径），
   再在支持 color-mix 的浏览器上升级成真正的变量派生。 */
body.skin-tech {
  --tech-edge: rgba(0, 229, 255, 0.42);   /* 面板描边 */
  --tech-fill: rgba(0, 229, 255, 0.07);   /* 面板渐变高光 */
  --tech-scan: rgba(0, 229, 255, 0.035);  /* CRT 扫描线 */
  --tech-major: rgba(0, 229, 255, 0.13);  /* 主网格（26px 细网格之外那一层粗的） */
  --tech-vig: rgba(0, 0, 0, 0.5);         /* 四角暗角，做出"屏幕"的纵深 */
  --tech-glow: rgba(0, 229, 255, 0.55);   /* 辉光 */
}
@supports (color: color-mix(in srgb, red, blue)) {
  body.skin-tech {
    --tech-edge: color-mix(in srgb, var(--accent) 42%, transparent);
    --tech-fill: color-mix(in srgb, var(--accent) 7%, transparent);
    --tech-scan: color-mix(in srgb, var(--accent) 4%, transparent);
    --tech-major: color-mix(in srgb, var(--accent) 13%, transparent);
    --tech-vig: color-mix(in srgb, #000 50%, transparent);
    --tech-glow: color-mix(in srgb, var(--accent) 55%, transparent);
  }
}

/* ---------- ② HUD 底层：主网格 + 扫描线 + 暗角 ----------
   为什么用 `::after` 而不是改上面那个 `::before`：
     `::before` 是**细网格（26px）而且 PC 上一直在漂移**。
     我要是把粗网格也画进 `::before`，两层不同步就会出现摩尔纹。
     所以粗网格（130px = 5×26，和细网格对齐）单独放一层，静止不动 ——
     看上去就是"固定的坐标框 + 缓缓流动的细格"。
   z-index: 0 在 `body.skin-tech .app`（z-index: 1）之下，不挡任何内容。 */
body.skin-tech::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    radial-gradient(130% 100% at 50% 0%, transparent 42%, var(--tech-vig) 100%),
    repeating-linear-gradient(0deg, var(--tech-scan) 0 1px, transparent 1px 3px),
    linear-gradient(var(--tech-major) 1px, transparent 1px),
    linear-gradient(90deg, var(--tech-major) 1px, transparent 1px);
  background-size: 100% 100%, 100% 3px, 130px 130px, 130px 130px;
}

/* ---------- ③ 切角 HUD 面板 ----------
   ☠️ 关键取舍：`clip-path` 会把**外发光和 border 一起切掉**，
      所以描边不能用 border，要用 `box-shadow: inset 0 0 0 1px`（在内部，切不到）。
      这也是为什么下面要把 `border-color` 置透明 —— 不然会剩半截边框在切口上。
   ⚠️ `clip-path` 只影响绘制，**不改任何尺寸** → 量版面的自查读到的矩形完全不变。 */
body.skin-tech .unit,
body.skin-tech .paper,
body.skin-tech .task,
body.skin-tech .goal-card,
body.skin-tech .class-card,
body.skin-tech .stat,
body.skin-tech .badge,
body.skin-tech .skin-btn,
body.skin-tech .subject-card,
body.skin-tech .train-head,
body.skin-tech .exam-config,
body.skin-tech .exam-date-card,
body.skin-tech .exam-history,
body.skin-tech .me-head,
body.skin-tech .level-strip,
body.skin-tech .answer-card,
body.skin-tech .ladder-row,
body.skin-tech .quest-strip,
body.skin-tech .btn-math,
body.skin-tech .countdown-card,
body.skin-tech .weak-row,
body.skin-tech .cmp-row,
body.skin-tech .backup-card,
body.skin-tech .pub-box {
  border-color: transparent;
  border-radius: 0;
  /* 左上 + 右下各切一刀 —— 最省的 HUD 记号，一眼就和"圆角卡片"区分开 */
  clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px,
                     100% 100%, 14px 100%, 0 calc(100% - 14px));
  box-shadow: inset 0 0 0 1px var(--tech-edge),
              inset 0 1px 0 0 var(--tech-fill);
  background-image: linear-gradient(155deg, var(--tech-fill) 0%, transparent 46%);
}

/* ---------- ④ 左上角那块"数据角标" ----------
   只有首页/学习页这种**大面板**才加，小卡片加满会显得脏。
   用 inset 的 border-left/top 画一个 L 形亮角，不占位置、不影响布局。 */
body.skin-tech .level-strip,
body.skin-tech .subject-card,
body.skin-tech .train-head {
  border-image: none;
  box-shadow: inset 0 0 0 1px var(--tech-edge),
              inset 0 1px 0 0 var(--tech-fill),
              inset 3px 3px 0 -2px var(--accent);
}

/* ---------- ⑤ 霓虹文字：只给标题和数字，正文一律不加（加了难读） ---------- */
body.skin-tech .sec-title,
body.skin-tech .quiz-q,
body.skin-tech .ring-center b,
body.skin-tech .pill b,
body.skin-tech .stat b,
body.skin-tech .lv-badge,
body.skin-tech .finish-xp {
  text-shadow: 0 0 16px var(--tech-glow);
}

/* ---------- ⑥ 主按钮：更强的霓虹 + 保留"可按"的厚度感（所以**不切角**） ---------- */
body.skin-tech .btn-main {
  box-shadow: 0 0 0 1px var(--accent),
              0 0 22px var(--tech-glow),
              inset 0 1px 0 0 var(--tech-fill);
}

/* ---------- ⑦ 空状态 / 虚线框也统一成 HUD 口径 ---------- */
body.skin-tech .subj-empty {
  border-style: solid;
  border-color: var(--tech-edge);
  border-radius: 0;
}

/* ---------- ⑦b 小控件：切**小**角（8px） ----------
   面板切 14px、小控件切 8px —— 尺寸分两档，不然 44px 高的按钮被切掉一半会很丑。
   ⚠️ `clip-path` 会裁剪**点击区域**（切掉的那两块点不到），
      所以这里刻意只切 8px：44px 的按钮上等于两个角各让出 8px，
      **正中一大片照样点得到**，Playwright 点元素中心也不受影响。 */
body.skin-tech .opt,
body.skin-tech .judge-opt,
body.skin-tech .ac-cell,
body.skin-tech .foot-btn,
body.skin-tech .mini-btn,
body.skin-tech .goal-btn,
body.skin-tech .stage-tab,
body.skin-tech .subj-tab,
body.skin-tech .key,
body.skin-tech .hero-go,
body.skin-tech .qs-go {
  border-radius: 0;
  clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px,
                     100% 100%, 8px 100%, 0 calc(100% - 8px));
  box-shadow: inset 0 0 0 1px var(--tech-edge);
}

/* ---------- ⑦c 顶栏 / 答题头：一条发光的基线，把"标题栏"变成"仪表条" ----------
   ⚠️ 用 `inset` 的 box-shadow 画线，**不能用 border-bottom** ——
      border 会让顶栏高 1px，整个页面跟着下移 1px，量版面就全变了（踩过这个思路）。 */
body.skin-tech .topbar,
body.skin-tech #quiz-layer .quiz-top,
body.skin-tech #exam-layer .quiz-top,
body.skin-tech #lesson-layer .quiz-top {
  box-shadow: inset 0 -1px 0 0 var(--tech-edge);
}

/* ---------- ⑧ 以下只在 PC（悬停辉光 + 侧栏发光条） ----------
   @mobile-ok: 这一块套了 `min-width:900px`，**手机根本不进入** ——
   它本来就是 PC 专属的增补，和上面那层全站皮肤不是一回事。 */
@media (min-width: 900px) {
  /* 鼠标划过时整块面板亮起来 —— PC 才有的"仪表盘"反馈 */
  body.skin-tech .unit:hover,
  body.skin-tech .paper:hover,
  body.skin-tech .task:hover,
  body.skin-tech .skin-btn:hover {
    box-shadow: inset 0 0 0 1px var(--accent),
                inset 0 0 34px -12px var(--accent);
  }
  /* 左侧导航：选中项亮一条发光的竖杠 */
  body.skin-tech .app > .tabbar .tab.active {
    background: linear-gradient(90deg, var(--tech-fill), transparent 72%);
    box-shadow: inset 3px 0 0 0 var(--accent),
                inset 0 0 26px -10px var(--accent);
  }
  /* 顶栏两个状态胶囊也带一点辉光 */
  body.skin-tech .pill {
    box-shadow: inset 0 0 0 1px var(--tech-edge);
  }
}

/* ---------- ⑨ 一段慢速"呼吸"，让 HUD 不是死的 ----------
   @mobile-ok: 和动态层同一条规矩 —— 关在 reduce 闸门里，只碰 opacity。 */
@media (prefers-reduced-motion: no-preference) {
  @keyframes tech-hud-breathe {
    50% { opacity: .62; }
  }
  body.skin-tech::after {
    animation: tech-hud-breathe 5.5s ease-in-out infinite;
  }
  @media (min-width: 900px) {
    /* PC 上再给一条**缓慢下扫的扫描带** —— 未来感最强的那个动作。
       画在 `html::after` 上（`body` 的两个伪元素已经用完了），
       z-index: 0 同样在 .app 之下，不挡内容。 */
    @keyframes tech-scanline {
      from { transform: translate3d(0, -18vh, 0); }
      to   { transform: translate3d(0, 118vh, 0); }
    }
    html:has(body.skin-tech)::after {
      content: '';
      position: fixed;
      left: 0;
      right: 0;
      top: 0;
      height: 18vh;
      z-index: 0;
      pointer-events: none;
      background: linear-gradient(180deg,
        transparent 0%, var(--tech-fill) 45%, var(--tech-edge) 50%, var(--tech-fill) 55%, transparent 100%);
      animation: tech-scanline 7.5s linear infinite;
    }
  }
}

/* ============================================================
   ⑩ 科目卡右侧的 Q 版小人（2026-10-05 加，用户要求）
   ------------------------------------------------------------
   用户原话：「这个范围放小人」（指科目卡那块）→ 选定方案 B：
   左边保留原来的半身像 + 文字，**右边空位放一个 Q 版小人**做装饰。

   ⚠️ **只在 PC 显示**，而且写成「**默认隐藏、PC 才显示**」——
      不是"PC 加样式"。原因：小人源图是 256²，如果只在 `min-width:900px` 里给尺寸，
      那么手机上这条不生效 → 图按 **256px 原尺寸**渲染 → **卡片被撑破、右侧溢出 73px**
      （2026-10-05 实测踩到）。反过来写，最坏情况只是"看不见"。
   ⚠️ PC 上卡片内高约 100px，72px 是"不越界又看得清"的尺寸；88px 会顶到上下边框（模拟过）。
   ⚠️ 用 `margin-left:auto` 推到最右，**不改 .subject-card 的 flex 布局**，左侧不受影响。
   ============================================================ */
.subject-card .s-chibi { display: none; }

@media (min-width: 900px) {
  .subject-card .s-chibi {
    display: flex;
    margin-left: auto;
    flex: none;
    align-items: flex-end;
    pointer-events: none;      /* 纯装饰，别抢卡片的点击 */
  }
  .subject-card .s-chibi img {
    width: 72px;
    height: 72px;
    display: block;
    object-fit: contain;       /* 全身小人 —— 用 contain，别裁 */
  }
  /* PC 上鼠标划过卡片时，小人轻轻抬一下（只碰 transform，不触发重排） */
  @media (prefers-reduced-motion: no-preference) {
    .subject-card .s-chibi img { transition: transform .25s ease; }
    .subject-card:hover .s-chibi img { transform: translateY(-3px); }
  }
}

/* ============================================================
   第 4 套皮肤：**海洋风**（`body.skin-ocean`）（2026-10-05 · PC 版会话）
   ------------------------------------------------------------
   用户口径：「**科技风和海洋不一样，是多个的别合一起**」。

   ⚠️ 这是在**纠正我上一版的错**：上一版我把海洋配色**覆盖写在 `body.skin-tech` 上**，
      等于**把科技风改没了**（学生只能看到海洋，青色那套 HUD 消失）。
      本节的写法是：**科技风一个字没动**（它还是 v139 那套青色），
      海洋风挂在**自己的类** `body.skin-ocean` 上。

   ⚠️ 海洋风**同时挂两个类**：`body.skin-tech` + `body.skin-ocean`
      （由 `skin-ocean.js` 负责）。所以：
        · **几何**（切角面板、霓虹描边、细网格漂移、下扫扫描带）→ 直接复用上面那套，
          这一节**一行都不用重写**；
        · **这一节只写差异**：配色 + 底层图案 + 气泡。
      好处是几何只有一份，两套皮肤不会各自漂移；代价是改几何时两套一起变 —— 这是想要的。

   品牌落点（为什么海洋风该长这样）：
     吉祥物是小鲸鱼 · 等级叫「小水花 → 小浪花 → 会游泳的鲸」·
     引导人口头禅「先游一小步」· 她手里那只旧救生圈 —— **这个 App 本来就是海里的**。
     所以海里最直白的三样东西直接拿来用：**深度、生物荧光、声呐**。

   @mobile-ok: 海洋风是**第 4 套可选皮肤**，和科技风同级；它本来就该在手机和 PC 上
   都能选、都能看。三条保证同前面几节：不碰布局 / 颜色 color-mix 现算 + @supports 兜底 /
   持续动画另有关闭闸门。
   ============================================================ */

/* ---------- ① 深海配色 ---------- */
body.skin-ocean {
  --accent: #22e6c8;          /* 生物荧光青绿：深海里"自己发光"的那一类颜色 */
  --accent-dark: #12a894;
  --accent-light: #06302c;
  --accent-text: #8dffee;
  --blue: #35b6ff;            /* 次色：海水蓝 */
  --blue-light: #06283c;
  --blue-text: #9bdcff;
  --gray-light: #04090f;      /* 页面底色：无光层 */
  --card: #07161e;            /* 卡片：微光层的"水色面板" */
  --line: #10303c;
  --text: #d6f7ff;
  --gray: #7fa3b3;            /* 偏水色（科技风那套 --gray 发灰紫） */
  --green: #2fd98a;
  --green-light: #072b21;
  --green-text: #86ffc4;
  /* 深度渐变：顶上"有光层"偏青，往下进微光层、无光层 ——
     海洋最省也最直观的一条语言（科技风那边是纯色平底 + 网格）。 */
  background: linear-gradient(180deg, #06202b 0%, #04101a 34%, #02080e 66%, #010407 100%);
  background-attachment: fixed;
}
/* `html` 底色也要跟着：body 之外的过卷区域显示的是它 */
html:has(body.skin-ocean) { background: #010407; }

/* 派生令牌（覆盖共用几何用的那几个变量 —— 几何照旧，只是换成海的颜色） */
body.skin-ocean {
  --tech-edge: rgba(34, 230, 200, 0.42);
  --tech-fill: rgba(34, 230, 200, 0.07);
  --tech-scan: rgba(53, 182, 255, 0.05);
  --tech-major: rgba(34, 230, 200, 0.10);
  --tech-ring: rgba(53, 182, 255, 0.16);   /* 声呐环用海水蓝，和青绿拉开层次 */
  --tech-vig: rgba(0, 8, 14, 0.62);
  --tech-glow: rgba(34, 230, 200, 0.55);
}
@supports (color: color-mix(in srgb, red, blue)) {
  body.skin-ocean {
    --tech-edge: color-mix(in srgb, var(--accent) 42%, transparent);
    --tech-fill: color-mix(in srgb, var(--accent) 7%, transparent);
    --tech-scan: color-mix(in srgb, var(--blue) 5%, transparent);
    --tech-major: color-mix(in srgb, var(--accent) 10%, transparent);
    --tech-ring: color-mix(in srgb, var(--blue) 16%, transparent);
    --tech-vig: color-mix(in srgb, #00080e 62%, transparent);
    --tech-glow: color-mix(in srgb, var(--accent) 55%, transparent);
  }
}

/* ---------- ② 底层图案：把"电路板"换成"水下" ----------
   和科技风共用 `::after` 这一层，但**图层整个换掉**：
     声呐同心环 / 水面焦散  →  细网格 + 扫描线  →  暗角
   `background-image` 是**从上层到下层**（第一个在最上面）。
   声呐环用 `repeating-radial-gradient` 从顶部中间扩散 —— 静止时就是一圈圈同心线，
   **静态截图上就看得见**（动效进不了截图，这条能进）。 */
body.skin-ocean::after {
  background-image:
    repeating-radial-gradient(circle at 50% 4%,
      var(--tech-ring) 0 1px, transparent 1px 92px),
    radial-gradient(58% 30% at 20% 0%, var(--tech-fill) 0%, transparent 72%),
    radial-gradient(48% 24% at 80% 2%, var(--tech-fill) 0%, transparent 72%),
    linear-gradient(var(--tech-major) 1px, transparent 1px),
    linear-gradient(90deg, var(--tech-major) 1px, transparent 1px),
    repeating-linear-gradient(0deg, var(--tech-scan) 0 1px, transparent 1px 3px),
    radial-gradient(130% 100% at 50% 0%, transparent 38%, var(--tech-vig) 100%);
  background-size: 100% 100%, 100% 100%, 100% 100%, 130px 130px, 130px 130px, 100% 3px, 100% 100%;
  background-repeat: no-repeat, no-repeat, no-repeat, repeat, repeat, repeat, no-repeat;
}

/* ---------- ③ 气泡上升（只在 PC） ----------
   `html::before`（科技风那边这个位置是空的，科技风的扫描带在 `html::after`）。
   三层不同疏密的圆点一起向上飘，22 秒一轮 —— **慢，才像水里**（快了像下雪）。 */
@media (min-width: 900px) {
  @keyframes sea-bubbles {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(0, -280px, 0); }
  }
  html:has(body.skin-ocean)::before {
    content: '';
    position: fixed;
    inset: -300px 0 0 0;          /* 往上多留一屏，气泡飘出顶部时不会露边 */
    z-index: 0;
    pointer-events: none;
    background-image:
      radial-gradient(circle, var(--tech-edge) 0 1.6px, transparent 1.6px),
      radial-gradient(circle, var(--tech-fill) 0 2.4px, transparent 2.4px),
      radial-gradient(circle, var(--tech-edge) 0 1px, transparent 1px);
    background-size: 180px 280px, 240px 360px, 130px 210px;
    background-position: 20px 40px, 90px 160px, 55px 100px;
    animation: sea-bubbles 22s linear infinite;
  }
}

/* ---------- ④ 两套皮肤各自的"脸面"差别（一眼分得出，不用去比色值） ----------
   科技风 = **网格 + 切角 + 扫描线**（电路板/仪表盘）
   海洋风 = **深度渐变 + 声呐环 + 焦散 + 气泡**（水下）
   几何（切角）两套共用 —— 见文件头说明。 */

/* ============================================================
   第 5 套皮肤：**典藏金**（`body.skin-gold`）（2026-10-05 · PC 版会话）
   ------------------------------------------------------------
   用户口径：「**然后做一个金色风格**」。

   为什么金色**特别适合这个 App**（不是随便挑的一个颜色）：
     · 等级叫「小水花 → 小浪花 → **会游泳的鲸**」，一路往上爬 —— 金色就是"往上"的颜色
     · 「**排位**」那一页有段位徽章、晋级/降级；「成就」那一页有一排徽章
     · XP / 连击 / 目标环本来就在讲"积累"，金色是**积累的视觉语言**
     所以金色不做成"土豪金"，做**黑金**：深到接近黑的金褐底 + 鎏金描边 ——
     那是**奖章 / 典藏**的语汇，正好对上段位和成就。

   ⚠️ 与海洋风同一条规矩：**同时挂 `skin-tech` + `skin-gold`**（由 `skins-extra.js`
      的声明表里那个 `共用HUD: true` 决定），所以切角/描边/网格漂移那套几何**直接复用**，
      这一节**只写差异**：黑金配色 + 底层图案（斜向细纹 = 鎏金拉丝 + 暖色顶光）。

   ⚠️ 金色最容易踩的是**对比度**：`--accent` 是亮金，压在它上面的字必须用**深色**。
      共用几何里 `body.skin-tech .btn-main` 等已经统一定成 `#04141a` 深字
      （见上面那段"亮底 + 深字"的注释），所以这里不用重复写。
      改完必须跑 `node _dev-自查-深色皮肤对比度.js`。

   @mobile-ok: 典藏金是**第 5 套可选皮肤**，和科技风同级，本来就该手机 PC 都能选。
   ============================================================ */

/* ---------- ① 黑金配色 ---------- */
body.skin-gold {
  --accent: #f0c040;          /* 鎏金 */
  --accent-dark: #a8791a;     /* 按钮底部的"厚度" */
  --accent-light: #2b2210;    /* 浅底：选中态 */
  --accent-text: #ffdf8a;     /* 压在上面的亮字 */
  --blue: #d9a441;            /* 次色：也走金褐，别在金色皮肤里插一个冷蓝 */
  --blue-light: #2a1f0c;
  --blue-text: #ffd98a;
  --gray-light: #0a0806;      /* 页面底色：暖黑（不是纯黑，纯黑配金会发脏） */
  --card: #16130c;            /* 卡片：深金褐 */
  --line: #3a2f18;
  --text: #fff4dc;            /* 正文：暖白（用冷白配金色会显脏） */
  --gray: #a89a7c;            /* 次要文字也带暖调 */
  --green: #63c98a;           /* 对错色保持可辨：绿色留给"答对"，别也染成金 */
  --green-light: #12261a;
  --green-text: #9affc0;
  --red: #ff6b6b;
  --red-light: #2a1212;
  --red-text: #ffb0b0;
  /* 背景：上方一抹暖光（像展厅顶灯），往下压到近黑 —— 给出"典藏"的纵深 */
  background: linear-gradient(180deg, #1c1508 0%, #100c06 38%, #080603 68%, #050402 100%);
  background-attachment: fixed;
}
html:has(body.skin-gold) { background: #050402; }

/* 派生令牌（共用几何用的那几个变量换成金色系） */
body.skin-gold {
  --tech-edge: rgba(240, 192, 64, 0.42);
  --tech-fill: rgba(240, 192, 64, 0.06);
  --tech-scan: rgba(240, 192, 64, 0.035);
  --tech-major: rgba(240, 192, 64, 0.09);
  --tech-ring: rgba(240, 192, 64, 0.12);
  --tech-vig: rgba(5, 4, 2, 0.66);
  --tech-glow: rgba(240, 192, 64, 0.5);
}
@supports (color: color-mix(in srgb, red, blue)) {
  body.skin-gold {
    --tech-edge: color-mix(in srgb, var(--accent) 42%, transparent);
    --tech-fill: color-mix(in srgb, var(--accent) 6%, transparent);
    --tech-scan: color-mix(in srgb, var(--accent) 3.5%, transparent);
    --tech-major: color-mix(in srgb, var(--accent) 9%, transparent);
    --tech-ring: color-mix(in srgb, var(--accent) 12%, transparent);
    --tech-vig: color-mix(in srgb, #050402 66%, transparent);
    --tech-glow: color-mix(in srgb, var(--accent) 50%, transparent);
  }
}

/* ---------- ② 底层图案：**鎏金拉丝 + 顶光** ----------
   和另外两套共用 `::after` 这一层，但图层整个换掉：
     斜向细纹（拉丝金）→ 顶部暖光 → 细网格（保留一格，几何别丢）→ 暗角
   斜纹取 135°，间距 7px —— 太密会变摩尔纹，太疏看不出是"拉丝"。 */
body.skin-gold::after {
  background-image:
    repeating-linear-gradient(135deg,
      var(--tech-scan) 0 1px, transparent 1px 7px),
    radial-gradient(70% 34% at 50% 0%, var(--tech-fill) 0%, transparent 70%),
    linear-gradient(var(--tech-major) 1px, transparent 1px),
    linear-gradient(90deg, var(--tech-major) 1px, transparent 1px),
    radial-gradient(135% 100% at 50% 0%, transparent 34%, var(--tech-vig) 100%);
  background-size: 100% 100%, 100% 100%, 130px 130px, 130px 130px, 100% 100%;
  background-repeat: repeat, no-repeat, repeat, repeat, no-repeat;
}

/* ---------- ③ 金色专属的一处小讲究：发光更"实"一点 ----------
   金的反射比青色/荧光"重"，同样的透明度会显得单薄。
   只调共用几何里那两条最显眼的（主按钮、等级徽章），别整套重写。 */
body.skin-gold .btn-main {
  box-shadow: 0 0 0 1px var(--accent),
              0 0 26px var(--tech-glow),
              inset 0 1px 0 0 rgba(255, 255, 255, 0.18);
}
body.skin-gold .lv-badge,
body.skin-gold .sec-title {
  text-shadow: 0 0 18px var(--tech-glow), 0 1px 0 rgba(0, 0, 0, 0.5);
}

/* ---------- ④ 顺手治一个**既有的**可读性问题：`.timer`（计算训练的计时器） ----------
   `.timer`（第 816~825 行，早于本次会话）**两个色值都是写死的**：
     `color: #ff9600` + `background: #fff4e5`（米色药丸 + 橙字）
   浅色皮肤下没问题，但**深色皮肤下它还是一颗米色药丸** ——
   字怎么配都看不清：原来是橙压米色 **2.01:1**，
   我第一次只换字色（换成亮青）反而更糟，**1.09:1**（亮青压米色）。

   ⚠️ 教训：**只改字色不改底色，是在错的前提上做优化**。
      正确做法是**底色和字色一起换成主题变量** —— 这也正是设计规范里
      "写死的色值不跟皮肤走"那条规矩说的东西。
      实测（改完）：科技风 11:1 / 海洋风 10:1 / 典藏金 12:1。

   这是把 `_dev-自查-深色皮肤对比度.js` 从"写死 3 套皮肤"改成"从 SKINS 现读"之后
   才浮出来的 —— 之前科技风也有这条，只是被"另有 33 处不达标但不影响阅读"盖住了。

   ⚠️ 只覆盖 `.timer` 这一个选择器，不动上面那两行（那是别人的段落）。
      `.timer.urgent`（红色告急态）用的是 `var(--red)`，本来就是变量，不受影响。 */
body.skin-tech .timer,
body.skin-ocean .timer,
body.skin-gold .timer {
  color: var(--accent-text);
  background: var(--accent-light);
}

/* ============================================================
   第 6 套皮肤：**秋日枫叶**（`body.skin-autumn`）（2026-10-05 · PC 版会话）
   ------------------------------------------------------------
   用户口径：「**对了天气感怎么样和枫叶的配合**」。

   这个提议正好补上一个**结构性缺口**：
   在此之前 5 套皮肤里**只有「经典蓝」一套是浅色**，其余四套全是深色
   （科技风 / 海洋风 / 典藏金 / 伙伴位都压在深底上）。
   秋日是**暖浅色**，一下把色谱补全了。

   「天气感」的落点不是加一层滤镜，是**三件具体的东西**：
     ① **暖阳**：顶上偏金的光，往下散成米白（一天里"下午三点"的那种光）
     ② **飘落的枫叶**：4 片，各自不同大小/速度/横飘/自转
     ③ **纸感底**：暖米白而不是纯白（纯白配暖色会显脏）

   ⚠️ 这套**不共用 HUD 几何**（声明表里 `共用HUD: false`）：
      霓虹切角 + 发光描边是"深色科技"的语汇，配暖浅色纸感会很怪。
      不共用 → body 上只挂 `skin-autumn` → **走 App 原来的圆角几何**，
      所以这一节**不用重写任何组件样式**，只换颜色 + 加气氛。

   ⚠️ 枫叶为什么**手机上也有**（和"持续动效只给 PC"那条不一样）：
      那条的理由是"**全屏图层** 24 小时不停合成不划算"（网格漂移、扫描带）。
      枫叶是**4 个小元素、只动 transform**（GPU 合成，不触发重排重绘），
      而且**枫叶就是这套皮肤的全部意思** —— 手机上不给就等于白做。
      仍然关在 `prefers-reduced-motion` 闸门里。

   @mobile-ok: 第 6 套可选皮肤（秋日枫叶），和其余几套同级，本来就该手机 PC 都能选。
   ============================================================ */

/* ---------- ① 暖阳 + 纸感配色 ---------- */
body.skin-autumn {
  /* ☠️ 2026-10-05 修：主题色原来是**枫红 `#c1440e`（h18）**，而答错色 `#d1453b` 是 **h4** ——
     **色相差只有 14°、亮度差只有 12**。后果是**同一列选项上**：
       · 「选中」的边框 = --accent 枫红
       · 「答错」的边框 = --red   红
     两个几乎同色，学生会看错。是 `_dev-查-红撞红.js` 量出来的
     （现在这条已经做成 `_dev-自查-皮肤选择器.js` 的【F】红撞红守卫）。

     修法是**把主题色推到琥珀金 `#a8761a`（h39）**，和答错红拉开到 **35°**：
       · **枫红留给叶子** —— 这套皮肤的主角本来就是飘落的枫叶（`--maple-a/b/c/d` 一个字没动），
         UI 主题色换成琥珀金反而更"秋天"（银杏、暖阳、落叶都是这个色系）
       · 答错红**不动** —— "红 = 错"是硬习惯（style.css 第 962 行那条注释），不能为了配色去改它 */
  --accent: #96690f;          /* 琥珀金（压深一档）。和答错红 h4 差 35°，不会再撞；
                                 压深的原因见下面那段"白字压琥珀只有 4.4:1" */
  --accent-dark: #6d4a08;
  --accent-light: #f7ead2;    /* 浅底：选中态 */
  --accent-text: #6f4a08;     /* 压在浅底上的深字 */
  --blue: #2f7d8c;            /* 次色：秋日晴空的青灰（别用艳蓝，会跳出季节） */
  --blue-light: #dcecef;
  --blue-text: #1d5a66;
  --gray-light: #fdf7ee;      /* 页面底：暖米白（纸感。纯白配暖色显脏） */
  --card: #fffcf6;            /* 卡片：比页面再亮一档 */
  --line: #ecdcc6;
  --text: #3a2f26;            /* 正文：暖褐，不是纯黑（纯黑在暖底上发硬） */
  --gray: #8a7a68;
  --green: #4f9d5d;           /* 对错色保持可辨：绿留给"答对" */
  --green-light: #e2f0e0;
  --green-text: #2f6b39;
  --red: #d1453b;
  --red-light: #fbe3e0;
  --red-text: #a32b23;
  /* 暖阳 + 纸感：**并进 body 自己的背景**，不用单独的图层 ——
     单独一个全屏 fixed 图层会盖在卡片上（z-index 只能 0 或更高，
     负 z-index 会被 body 背景挡住），把整个界面洗白。
     放进背景就天然在所有内容之下，还能跟着 `background-attachment: fixed` 定住。 */
  background:
    radial-gradient(62% 34% at 50% -4%, rgba(255, 206, 116, 0.52) 0%, transparent 70%),
    radial-gradient(38% 22% at 14% 1%, rgba(255, 228, 176, 0.40) 0%, transparent 72%),
    linear-gradient(180deg, #fbe7c4 0%, #fdf3e2 26%, #fdf7ee 58%, #fbf1e4 100%);
  background-attachment: fixed;
}
html:has(body.skin-autumn) { background: #fdf7ee; }

/* 枫叶的形状与颜色。
   ⚠️ 形状走 `mask-image`（data URI 里**没有颜色**），颜色走 `background: var(--maple-?)`
      —— 这样叶子颜色仍然跟着皮肤变量走，不是写死在 SVG 里。
      直接往 SVG 里写 `fill='%23c1440e'` 就绕开了主题变量，皮肤换色时叶子不跟。
   ⚠️ 素材来源：`design/maple/`（生图 → 阈值化 → **potrace** 矢量化，
      4 种姿态：标准 / 细长 / 宽扁 / 侧翻）。**不是我手画的那个五角星了。**
   ⚠️ 素材原版 viewBox 是 200×200、**叶子占满 92%** —— 这个比例**不能直接平铺**：
      铺开时「叶子大小 = 0.92 × mask-size、间距 = mask-size」，
      想要 60px 的叶子就得 65px 的间距 → 叶子会挤成一片糊。
      所以下面存的是**叶场版**：把 path 包进 `<g transform='translate(350,350) scale(0.5)'>`
      并把 viewBox 放到 800×800 → 叶子降到 **11.5%**，
      于是「**叶子大小 = 0.115 × mask-size，间距 = mask-size**」，两个量才分得开。
      前景大叶也用同一条 URI（`mask-repeat: no-repeat` + mask-size 放大到 叶子尺寸÷0.115），
      **一份 URI 两用**，40KB 只花一次。 */
body.skin-autumn {
  /* ===== 枫叶剪影（素材来自 design/maple/，由 potrace 矢量化） =====
     ⚠️ 这里存的是**叶场版**：viewBox 800×800、叶子缩到 0.5（占 11.5%），
        所以铺开时「**叶子大小 = 0.115 × mask-size，间距 = mask-size**」——
        两个量才能分开调。素材原版是 200×200、叶子占 92%，
        直接平铺会得到"276px 巨叶 + 300px 间距"的挤成一团。
     ⚠️ 前景大叶也用同一条 URI：`mask-repeat: no-repeat` + 把 mask-size 放大到
        叶子尺寸 ÷ 0.115 即可（例：要 60px 的叶子就写 520px）。
        一份 URI 两用 —— 40KB 只花一次。
     ⚠️ 颜色仍走 background: var(--maple-a/b/c/d)，URI 里没有颜色，跟着皮肤变。 */
    --maple-标准: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20800%20800%27%3E%3Cg%20transform%3D%27translate(350%2C350)%20scale(0.5)%27%3E%3Cpath%20d%3D%27M%2099.9%208.8%20C%2099.1%2011.7%2C%2098.0%2015.2%2C%2097.2%2017.0%20C%2095.5%2021.0%2C%2092.6%2027.0%2C%2091.8%2028.0%20C%2090.7%2029.5%2C%2089.7%2029.6%2C%2088.4%2028.6%20L%2087.8%2028.0%2087.7%2028.5%20C%2087.7%2028.8%2C%2087.5%2029.7%2C%2087.4%2030.6%20C%2086.2%2039.5%2C%2084.5%2044.0%2C%2081.7%2045.3%20C%2080.7%2045.8%2C%2079.4%2045.8%2C%2078.0%2045.4%20C%2076.6%2045.0%2C%2073.5%2043.4%2C%2071.4%2042.0%20C%2070.4%2041.4%2C%2069.6%2041.0%2C%2069.6%2041.0%20C%2069.6%2041.0%2C%2070.0%2042.4%2C%2070.5%2044.1%20C%2071.7%2047.7%2C%2072.2%2049.5%2C%2072.7%2052.5%20C%2073.6%2057.6%2C%2073.5%2060.1%2C%2072.3%2061.2%20L%2071.7%2061.7%2073.2%2064.7%20C%2077.2%2072.6%2C%2079.7%2081.7%2C%2079.7%2088.1%20C%2079.7%2090.4%2C%2079.6%2090.9%2C%2079.2%2091.7%20C%2079.0%2092.2%2C%2078.7%2092.7%2C%2078.6%2092.7%20C%2078.2%2092.7%2C%2076.9%2091.9%2C%2075.8%2091.0%20C%2072.3%2088.3%2C%2069.1%2084.9%2C%2064.8%2079.5%20C%2063.3%2077.6%2C%2061.5%2075.5%2C%2060.8%2074.8%20C%2059.2%2073.1%2C%2058.1%2071.6%2C%2055.9%2068.3%20L%2054.0%2065.5%2053.8%2067.4%20C%2053.5%2069.7%2C%2053.2%2070.6%2C%2052.7%2071.7%20C%2051.0%2074.6%2C%2047.8%2073.8%2C%2042.7%2069.4%20C%2041.9%2068.7%2C%2041.2%2068.2%2C%2041.2%2068.2%20C%2041.2%2068.3%2C%2041.0%2068.6%2C%2040.8%2069.0%20C%2040.4%2070.0%2C%2039.7%2070.3%2C%2038.1%2070.1%20C%2035.4%2069.8%2C%2028.6%2066.9%2C%2021.7%2063.1%20C%2020.4%2062.3%2C%2019.3%2061.8%2C%2019.3%2061.8%20C%2019.3%2061.9%2C%2019.8%2062.8%2C%2020.5%2063.9%20C%2023.3%2068.4%2C%2025.2%2072.3%2C%2026.0%2075.2%20C%2026.6%2077.2%2C%2026.5%2077.8%2C%2025.9%2078.4%20C%2025.6%2078.7%2C%2025.4%2079.0%2C%2025.4%2079.1%20C%2025.4%2079.2%2C%2025.8%2079.7%2C%2026.3%2080.3%20C%2027.6%2082.0%2C%2028.5%2084.1%2C%2028.6%2085.9%20C%2028.7%2087.3%2C%2028.6%2087.5%2C%2028.1%2088.2%20C%2027.6%2089.0%2C%2025.6%2090.2%2C%2024.9%2090.2%20C%2024.7%2090.2%2C%2024.6%2090.3%2C%2024.6%2090.4%20C%2024.6%2090.5%2C%2025.6%2091.5%2C%2026.9%2092.7%20C%2029.3%2095.1%2C%2030.6%2096.8%2C%2031.9%2099.3%20C%2032.8%20101.1%2C%2033.0%20102.2%2C%2032.6%20103.4%20C%2031.8%20105.4%2C%2028.3%20107.3%2C%2022.7%20108.7%20C%2021.8%20108.9%2C%2021.0%20109.2%2C%2020.8%20109.2%20C%2020.6%20109.3%2C%2021.8%20109.8%2C%2023.3%20110.3%20C%2026.5%20111.4%2C%2028.9%20112.5%2C%2032.5%20114.6%20C%2038.2%20117.9%2C%2039.7%20119.1%2C%2039.7%20120.3%20C%2039.7%20120.6%2C%2040.0%20120.8%2C%2041.2%20121.1%20C%2044.6%20122.1%2C%2050.8%20125.1%2C%2053.0%20126.7%20C%2054.5%20127.8%2C%2054.8%20128.4%2C%2054.5%20129.2%20C%2053.9%20131.2%2C%2050.1%20133.8%2C%2046.1%20135.1%20C%2045.1%20135.4%2C%2044.3%20135.7%2C%2044.3%20135.7%20C%2044.3%20135.7%2C%2044.4%20136.1%2C%2044.5%20136.4%20C%2044.8%20137.3%2C%2044.7%20137.9%2C%2043.8%20138.9%20C%2042.6%20140.3%2C%2032.9%20148.2%2C%2029.6%20150.5%20C%2028.6%20151.1%2C%2027.8%20151.7%2C%2027.8%20151.7%20C%2027.8%20151.7%2C%2030.4%20151.7%2C%2033.5%20151.7%20C%2038.6%20151.7%2C%2039.4%20151.8%2C%2041.1%20152.2%20C%2045.0%20153.1%2C%2046.5%20154.0%2C%2046.5%20155.6%20L%2046.5%20156.4%2048.3%20156.0%20C%2050.4%20155.6%2C%2054.0%20155.5%2C%2055.5%20155.9%20C%2057.7%20156.3%2C%2058.8%20157.8%2C%2058.4%20159.8%20C%2058.2%20160.3%2C%2058.2%20160.8%2C%2058.2%20160.8%20C%2058.3%20160.9%2C%2059.3%20160.6%2C%2060.6%20160.3%20C%2065.0%20159.1%2C%2066.5%20158.8%2C%2069.3%20158.8%20C%2072.3%20158.7%2C%2073.0%20159.0%2C%2073.7%20160.5%20C%2074.5%20161.9%2C%2074.2%20164.1%2C%2072.8%20167.9%20C%2072.6%20168.7%2C%2072.4%20169.3%2C%2072.5%20169.3%20C%2072.5%20169.3%2C%2073.7%20168.5%2C%2075.1%20167.5%20C%2076.5%20166.6%2C%2078.6%20165.2%2C%2079.7%20164.5%20C%2082.7%20162.6%2C%2084.1%20161.6%2C%2087.5%20158.8%20C%2093.1%20154.3%2C%2095.6%20152.9%2C%2096.8%20153.5%20C%2097.5%20153.8%2C%2097.6%20154.5%2C%2097.8%20161.5%20C%2097.9%20168.5%2C%2097.6%20174.4%2C%2096.5%20184.0%20C%2095.9%20189.4%2C%2095.9%20190.5%2C%2096.4%20191.1%20C%2097.1%20191.8%2C%2098.1%20192.0%2C%20100.2%20191.9%20C%20102.3%20191.8%2C%20103.0%20191.5%2C%20103.3%20190.3%20C%20103.4%20189.9%2C%20103.3%20187.6%2C%20102.8%20183.0%20C%20101.6%20172.5%2C%20101.3%20164.8%2C%20101.6%20158.8%20C%20101.9%20154.3%2C%20102.0%20153.9%2C%20102.6%20153.5%20C%20103.6%20152.9%2C%20105.7%20153.9%2C%20110.3%20157.4%20C%20111.8%20158.5%2C%20113.6%20159.9%2C%20114.4%20160.6%20C%20115.2%20161.3%2C%20116.9%20162.5%2C%20118.2%20163.3%20C%20119.5%20164.0%2C%20121.9%20165.7%2C%20123.6%20167.0%20C%20125.4%20168.3%2C%20126.8%20169.3%2C%20126.8%20169.2%20C%20126.9%20169.2%2C%20126.7%20168.6%2C%20126.5%20168.0%20C%20124.9%20163.4%2C%20125.0%20160.3%2C%20126.6%20159.3%20C%20127.6%20158.6%2C%20129.5%20158.4%2C%20131.6%20158.6%20C%20133.7%20158.9%2C%20136.9%20159.6%2C%20139.2%20160.4%20C%20140.1%20160.6%2C%20140.9%20160.9%2C%20141.0%20160.9%20C%20141.1%20160.9%2C%20141.1%20160.4%2C%20141.0%20159.6%20C%20140.8%20157.4%2C%20141.6%20156.4%2C%20144.2%20155.7%20C%20145.7%20155.3%2C%20149.1%20155.4%2C%20151.1%20155.9%20C%20152.8%20156.4%2C%20153.1%20156.3%2C%20152.9%20155.8%20C%20152.9%20155.6%2C%20153.0%20155.0%2C%20153.2%20154.5%20C%20153.5%20153.8%2C%20153.8%20153.6%2C%20154.8%20153.1%20C%20157.8%20151.6%2C%20161.5%20151.1%2C%20167.4%20151.3%20L%20171.6%20151.4%20170.9%20150.9%20C%20169.2%20149.5%2C%20162.3%20144.1%2C%20159.3%20141.9%20C%20157.5%20140.4%2C%20155.7%20139.0%2C%20155.3%20138.6%20C%20154.7%20137.8%2C%20154.6%20136.6%2C%20155.0%20136.1%20C%20155.1%20135.9%2C%20155.2%20135.7%2C%20155.2%20135.7%20C%20155.1%20135.7%2C%20154.3%20135.4%2C%20153.4%20135.1%20C%20150.8%20134.3%2C%20148.3%20133.0%2C%20146.7%20131.6%20C%20143.9%20129.0%2C%20144.2%20128.0%2C%20148.5%20125.4%20C%20151.3%20123.8%2C%20156.7%20121.2%2C%20158.3%20120.8%20C%20159.4%20120.5%2C%20159.6%20120.4%2C%20159.7%20119.9%20C%20159.9%20119.0%2C%20160.7%20118.3%2C%20165.1%20115.4%20C%20169.8%20112.3%2C%20172.2%20111.1%2C%20175.7%20109.9%20C%20177.1%20109.4%2C%20178.3%20109.0%2C%20178.5%20109.0%20C%20178.6%20108.9%2C%20177.8%20108.6%2C%20176.6%20108.3%20C%20169.9%20106.5%2C%20167.2%20105.1%2C%20166.7%20103.0%20C%20166.1%20100.8%2C%20167.9%2097.7%2C%20172.5%2092.8%20C%20173.9%2091.3%2C%20174.8%2090.2%2C%20174.6%2090.2%20C%20172.3%2089.4%2C%20171.2%2088.6%2C%20170.8%2087.3%20C%20170.6%2086.5%2C%20170.6%2086.2%2C%20170.9%2085.1%20C%20171.3%2083.4%2C%20172.2%2081.6%2C%20173.4%2080.2%20L%20174.2%2079.1%20173.6%2078.5%20C%20173.0%2077.9%2C%20173.0%2077.9%2C%20173.1%2076.7%20C%20173.4%2073.8%2C%20176.4%2067.3%2C%20179.5%2062.7%20C%20180.4%2061.3%2C%20180.7%2061.2%2C%20175.9%2064.2%20C%20169.7%2067.9%2C%20167.1%2069.2%2C%20163.9%2070.0%20C%20161.3%2070.7%2C%20160.0%2070.4%2C%20159.4%2069.0%20C%20159.3%2068.7%2C%20159.1%2068.4%2C%20159.1%2068.4%20C%20159.0%2068.4%2C%20158.3%2069.0%2C%20157.4%2069.7%20C%20154.7%2071.9%2C%20152.8%2073.0%2C%20151.0%2073.4%20C%20148.2%2074.0%2C%20146.5%2071.8%2C%20146.2%2067.3%20C%20146.2%2066.4%2C%20146.1%2065.6%2C%20146.0%2065.6%20C%20145.9%2065.6%2C%20145.6%2066.0%2C%20145.3%2066.4%20C%20143.9%2068.7%2C%20141.3%2072.2%2C%20139.3%2074.3%20C%20138.2%2075.6%2C%20136.5%2077.6%2C%20135.6%2078.6%20C%20130.0%2085.5%2C%20123.8%2091.5%2C%20121.5%2092.5%20C%20120.9%2092.7%2C%20120.8%2092.7%2C%20120.5%2092.3%20C%20119.3%2090.8%2C%20119.6%2084.7%2C%20121.2%2078.2%20C%20122.4%2073.4%2C%20124.6%2067.7%2C%20126.7%2063.6%20L%20127.7%2061.7%20127.1%2061.2%20C%20126.3%2060.6%2C%20126.0%2059.2%2C%20126.2%2056.6%20C%20126.4%2052.7%2C%20127.2%2049.4%2C%20129.5%2042.2%20L%20129.9%2040.9%20129.3%2041.3%20C%20128.9%2041.5%2C%20127.6%2042.3%2C%20126.4%2043.0%20C%20121.1%2046.2%2C%20118.5%2046.5%2C%20116.2%2044.1%20C%20114.1%2041.9%2C%20113.3%2039.0%2C%20111.8%2028.8%20L%20111.6%2028.1%20110.8%2028.7%20C%20109.8%2029.4%2C%20109.1%2029.4%2C%20108.2%2028.6%20C%20107.2%2027.8%2C%20106.7%2026.7%2C%20104.4%2020.9%20C%20102.3%2015.8%2C%20101.8%2014.2%2C%20100.8%2010.6%20C%20100.5%209.3%2C%20100.2%208.2%2C%20100.2%208.1%20C%20100.1%208.0%2C%20100.0%208.3%2C%2099.9%208.8%27%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
    --maple-细长: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20800%20800%27%3E%3Cg%20transform%3D%27translate(350%2C350)%20scale(0.5)%27%3E%3Cpath%20d%3D%27M%20106.4%208.9%20C%20106.2%209.4%2C%20105.6%2011.0%2C%20105.1%2012.6%20C%20103.3%2018.8%2C%20100.9%2025.5%2C%20100.5%2025.5%20C%20100.1%2025.5%2C%2099.7%2027.0%2C%2099.3%2029.3%20C%2099.0%2031.3%2C%2097.5%2036.0%2C%2097.0%2036.6%20C%2096.4%2037.2%2C%2095.8%2037.1%2C%2095.1%2036.2%20C%2094.7%2035.8%2C%2094.4%2035.5%2C%2094.3%2035.6%20C%2094.2%2035.7%2C%2094.1%2036.9%2C%2094.0%2038.4%20C%2093.6%2044.7%2C%2093.5%2045.8%2C%2093.1%2045.8%20C%2092.6%2045.8%2C%2092.5%2046.4%2C%2092.5%2049.5%20C%2092.4%2053.5%2C%2091.7%2055.5%2C%2090.3%2055.8%20C%2089.6%2056.0%2C%2087.8%2055.4%2C%2086.3%2054.6%20C%2085.6%2054.3%2C%2085.0%2054.0%2C%2084.8%2054.0%20C%2084.3%2054.0%2C%2082.3%2052.6%2C%2081.1%2051.4%20L%2080.1%2050.3%2080.1%2051.0%20C%2080.1%2051.4%2C%2080.4%2053.3%2C%2080.9%2055.1%20C%2081.5%2057.5%2C%2081.8%2059.0%2C%2081.8%2060.3%20C%2081.8%2061.6%2C%2082.0%2062.8%2C%2082.4%2063.9%20C%2082.9%2065.6%2C%2083.0%2066.4%2C%2083.0%2067.2%20C%2082.9%2067.5%2C%2082.7%2067.6%2C%2082.0%2067.6%20C%2080.8%2067.6%2C%2080.8%2067.9%2C%2081.8%2069.6%20C%2083.4%2072.2%2C%2084.8%2075.3%2C%2085.0%2076.6%20C%2085.1%2077.4%2C%2085.6%2078.9%2C%2086.4%2080.6%20C%2088.7%2085.6%2C%2089.9%2089.6%2C%2091.2%2096.2%20C%2092.3%20101.4%2C%2092.6%20104.0%2C%2092.7%20107.1%20C%2092.7%20109.7%2C%2092.7%20110.0%2C%2092.3%20110.5%20C%2091.7%20111.2%2C%2091.0%20111.2%2C%2089.5%20110.5%20C%2088.1%20109.7%2C%2086.9%20108.6%2C%2083.0%20104.2%20C%2081.1%20102.0%2C%2079.0%2099.7%2C%2078.4%2099.0%20C%2077.0%2097.4%2C%2076.0%2095.8%2C%2074.0%2092.1%20C%2073.1%2090.4%2C%2072.3%2089.0%2C%2072.1%2088.8%20C%2071.9%2088.6%2C%2071.7%2088.8%2C%2071.1%2090.0%20C%2070.7%2090.8%2C%2070.2%2091.5%2C%2070.0%2091.7%20C%2068.6%2092.4%2C%2065.4%2091.0%2C%2062.7%2088.6%20C%2061.8%2087.8%2C%2060.2%2086.3%2C%2059.2%2085.4%20C%2057.1%2083.5%2C%2056.3%2082.9%2C%2056.0%2083.1%20C%2055.9%2083.2%2C%2055.8%2083.5%2C%2055.7%2083.9%20C%2055.6%2084.5%2C%2055.5%2084.7%2C%2055.2%2084.7%20C%2054.3%2084.7%2C%2049.0%2081.9%2C%2046.8%2080.3%20C%2044.0%2078.3%2C%2030.7%2072.1%2C%2030.2%2072.6%20C%2030.1%2072.7%2C%2031.5%2074.3%2C%2033.1%2076.3%20C%2037.9%2081.8%2C%2038.3%2082.3%2C%2039.6%2085.0%20C%2040.9%2087.6%2C%2041.1%2088.4%2C%2040.4%2088.4%20C%2039.7%2088.4%2C%2039.9%2089.0%2C%2041.1%2090.4%20C%2041.7%2091.2%2C%2042.4%2092.0%2C%2042.5%2092.3%20C%2045.2%2097.2%2C%2045.4%2098.2%2C%2043.2%2098.2%20C%2041.7%2098.2%2C%2041.8%2098.5%2C%2044.2%20100.8%20C%2045.5%20102.1%2C%2046.6%20103.2%2C%2046.6%20103.3%20C%2046.6%20103.4%2C%2047.1%20104.2%2C%2047.7%20105.0%20C%2049.8%20107.7%2C%2050.1%20109.1%2C%2049.0%20110.0%20C%2048.7%20110.3%2C%2047.8%20110.8%2C%2047.0%20111.1%20C%2045.9%20111.5%2C%2045.2%20111.6%2C%2043.1%20111.7%20C%2041.0%20111.8%2C%2040.6%20111.9%2C%2040.8%20112.1%20C%2041.0%20112.3%2C%2042.2%20113.0%2C%2043.6%20113.7%20C%2046.5%20115.2%2C%2049.2%20117.2%2C%2049.4%20117.8%20C%2049.4%20118.0%2C%2050.5%20118.8%2C%2051.8%20119.7%20C%2053.0%20120.5%2C%2054.2%20121.4%2C%2054.4%20121.6%20C%2054.8%20122.0%2C%2054.8%20122.0%2C%2054.2%20122.4%20C%2053.5%20122.7%2C%2053.5%20122.7%2C%2053.8%20123.1%20C%2054.3%20123.6%2C%2059.1%20126.0%2C%2062.7%20127.6%20C%2066.4%20129.2%2C%2068.7%20130.6%2C%2071.5%20132.6%20C%2074.8%20135.1%2C%2075.7%20136.2%2C%2075.0%20137.2%20C%2074.3%20138.3%2C%2071.3%20140.0%2C%2068.7%20140.8%20C%2066.8%20141.3%2C%2064.2%20142.6%2C%2064.2%20142.9%20C%2064.2%20143.0%2C%2064.3%20143.3%2C%2064.5%20143.4%20C%2064.7%20143.6%2C%2064.0%20144.2%2C%2062.1%20145.1%20C%2061.5%20145.4%2C%2060.5%20146.0%2C%2059.8%20146.4%20C%2059.2%20146.8%2C%2057.3%20147.6%2C%2055.7%20148.3%20C%2054.1%20148.9%2C%2052.2%20149.7%2C%2051.5%20150.2%20L%2050.2%20150.9%2053.2%20151.1%20C%2056.3%20151.2%2C%2059.5%20151.7%2C%2060.2%20152.2%20C%2060.4%20152.3%2C%2061.3%20152.6%2C%2062.0%20152.8%20C%2064.0%20153.2%2C%2064.8%20153.6%2C%2064.8%20154.1%20C%2064.8%20154.3%2C%2064.8%20154.6%2C%2064.6%20154.6%20C%2064.5%20154.7%2C%2064.4%20155.0%2C%2064.4%20155.2%20C%2064.4%20155.5%2C%2064.6%20155.6%2C%2067.4%20155.5%20C%2069.9%20155.5%2C%2070.4%20155.5%2C%2071.1%20155.9%20C%2071.8%20156.2%2C%2071.9%20156.4%2C%2072.0%20156.9%20C%2072.0%20157.3%2C%2071.9%20157.9%2C%2071.7%20158.2%20C%2071.6%20158.6%2C%2071.4%20158.9%2C%2071.4%20159.0%20C%2071.4%20159.2%2C%2072.9%20159.1%2C%2074.8%20158.7%20C%2080.6%20157.5%2C%2082.1%20157.4%2C%2083.4%20158.1%20C%2084.2%20158.5%2C%2084.3%20158.7%2C%2084.3%20159.5%20C%2084.4%20160.5%2C%2084.0%20162.5%2C%2083.0%20165.5%20C%2082.6%20166.8%2C%2082.3%20168.0%2C%2082.3%20168.3%20C%2082.3%20168.8%2C%2082.4%20168.7%2C%2083.5%20167.7%20C%2084.9%20166.3%2C%2090.2%20162.8%2C%2090.8%20162.8%20C%2091.2%20162.8%2C%2092.0%20162.3%2C%2093.3%20161.2%20C%2093.7%20160.8%2C%2094.4%20160.4%2C%2094.8%20160.3%20C%2095.5%20160.1%2C%2095.6%20160.1%2C%2095.9%20160.5%20C%2096.1%20160.8%2C%2096.3%20161.2%2C%2096.3%20161.5%20C%2096.3%20162.0%2C%2096.3%20162.0%2C%2096.9%20161.6%20C%2097.2%20161.4%2C%2098.1%20160.7%2C%2099.0%20160.0%20C%2099.8%20159.3%2C%20101.0%20158.5%2C%20101.6%20158.1%20C%20102.2%20157.8%2C%20103.4%20156.9%2C%20104.4%20156.2%20C%20106.8%20154.2%2C%20107.4%20153.8%2C%20107.9%20153.6%20C%20108.3%20153.5%2C%20108.4%20153.6%2C%20108.5%20154.2%20C%20110.0%20161.1%2C%20111.9%20168.5%2C%20114.1%20175.3%20C%20118.8%20190.1%2C%20119.3%20191.4%2C%20120.3%20191.7%20C%20121.6%20192.0%2C%20124.9%20190.4%2C%20124.9%20189.4%20C%20124.9%20189.2%2C%20124.2%20187.9%2C%20123.3%20186.6%20C%20120.7%20182.6%2C%20118.8%20178.4%2C%20116.4%20170.9%20C%20114.0%20163.7%2C%20112.4%20157.7%2C%20112.2%20155.1%20L%20112.1%20153.7%20112.8%20154.0%20C%20113.1%20154.2%2C%20114.6%20155.2%2C%20116.0%20156.1%20C%20118.8%20158.1%2C%20119.7%20158.6%2C%20120.1%20158.2%20C%20120.3%20158.0%2C%20120.9%20158.2%2C%20122.4%20159.0%20C%20123.5%20159.6%2C%20124.6%20160.1%2C%20124.8%20160.1%20C%20124.9%20160.1%2C%20126.4%20160.8%2C%20127.9%20161.6%20C%20130.4%20163.0%2C%20131.8%20163.6%2C%20131.8%20163.3%20C%20131.8%20163.3%2C%20131.5%20162.5%2C%20131.0%20161.7%20C%20130.6%20160.8%2C%20130.2%20159.9%2C%20130.2%20159.8%20C%20130.2%20159.6%2C%20130.0%20158.8%2C%20129.7%20157.9%20C%20129.1%20156.2%2C%20129.1%20155.4%2C%20129.8%20154.9%20C%20130.4%20154.5%2C%20133.1%20154.0%2C%20134.1%20154.2%20C%20135.5%20154.5%2C%20144.1%20154.7%2C%20144.3%20154.5%20C%20144.4%20154.4%2C%20144.1%20153.9%2C%20143.8%20153.4%20C%20143.3%20152.7%2C%20143.2%20152.2%2C%20143.3%20151.9%20C%20143.5%20150.6%2C%20147.1%20148.4%2C%20149.9%20147.8%20C%20152.7%20147.2%2C%20153.7%20146.6%2C%20153.0%20146.2%20C%20152.6%20145.9%2C%20152.9%20145.7%2C%20155.4%20144.4%20C%20158.3%20142.9%2C%20159.7%20142.4%2C%20162.9%20141.8%20C%20166.2%20141.2%2C%20166.2%20141.2%2C%20166.1%20141.0%20C%20166.0%20140.9%2C%20165.7%20140.7%2C%20165.3%20140.7%20C%20163.9%20140.4%2C%20156.5%20137.9%2C%20156.5%20137.7%20C%20156.5%20137.5%2C%20155.7%20137.2%2C%20153.4%20136.6%20C%20151.4%20136.1%2C%20149.7%20135.4%2C%20149.7%20135.1%20C%20149.7%20135.0%2C%20149.9%20134.7%2C%20150.0%20134.5%20C%20150.2%20134.3%2C%20150.3%20134.0%2C%20150.3%20134.0%20C%20150.4%20133.7%2C%20148.3%20133.5%2C%20143.2%20133.5%20C%20138.7%20133.5%2C%20137.8%20133.4%2C%20137.1%20133.1%20C%20136.2%20132.7%2C%20136.0%20132.4%2C%20136.5%20131.3%20C%20137.1%20129.8%2C%20138.2%20128.2%2C%20140.2%20126.2%20C%20141.2%20125.1%2C%20142.3%20123.8%2C%20142.6%20123.4%20C%20143.4%20122.0%2C%20146.1%20119.5%2C%20148.4%20117.8%20C%20151.1%20115.7%2C%20155.3%20112.2%2C%20155.3%20112.0%20C%20155.3%20111.9%2C%20155.0%20111.7%2C%20154.8%20111.6%20L%20154.2%20111.4%20154.7%20110.8%20C%20154.9%20110.4%2C%20155.7%20109.6%2C%20156.5%20108.9%20C%20157.3%20108.2%2C%20158.1%20107.3%2C%20158.2%20107.0%20C%20158.4%20106.6%2C%20159.3%20105.6%2C%20160.3%20104.7%20C%20163.2%20102.1%2C%20164.9%20100.4%2C%20164.9%20100.4%20C%20164.8%20100.3%2C%20164.2%20100.4%2C%20163.4%20100.6%20C%20161.7%20101.0%2C%20160.3%20100.9%2C%20158.8%20100.3%20C%20157.7%2099.8%2C%20157.4%2099.4%2C%20157.5%2098.2%20C%20157.6%2097.4%2C%20158.9%2094.6%2C%20159.8%2093.2%20C%20160.1%2092.8%2C%20160.6%2092.0%2C%20160.9%2091.6%20C%20161.7%2090.5%2C%20161.6%2090.2%2C%20160.6%2090.2%20C%20159.9%2090.2%2C%20159.8%2090.2%2C%20159.8%2089.7%20C%20159.8%2089.0%2C%20161.0%2086.1%2C%20162.4%2083.5%20C%20163.5%2081.3%2C%20163.7%2080.8%2C%20163.2%2080.8%20C%20163.0%2080.8%2C%20162.9%2080.6%2C%20162.9%2080.3%20C%20162.9%2079.8%2C%20164.0%2076.4%2C%20164.6%2075.2%20C%20165.1%2074.2%2C%20168.1%2069.0%2C%20169.3%2067.2%20C%20169.6%2066.6%2C%20169.9%2066.1%2C%20169.8%2066.0%20C%20169.4%2065.7%2C%20165.5%2068.2%2C%20161.3%2071.5%20C%20160.3%2072.2%2C%20159.3%2073.0%2C%20158.9%2073.3%20C%20158.5%2073.5%2C%20157.3%2074.5%2C%20156.2%2075.5%20C%20155.1%2076.4%2C%20153.6%2077.7%2C%20152.8%2078.2%20C%20151.4%2079.1%2C%20151.3%2079.2%2C%20151.0%2078.8%20C%20150.9%2078.6%2C%20150.8%2078.3%2C%20150.8%2078.0%20C%20150.8%2077.2%2C%20150.0%2077.8%2C%20148.6%2079.7%20C%20146.8%2082.1%2C%20144.1%2085.2%2C%20142.7%2086.4%20C%20141.4%2087.6%2C%20139.7%2088.6%2C%20138.9%2088.6%20C%20138.3%2088.6%2C%20137.9%2087.9%2C%20137.7%2086.8%20C%20137.6%2086.1%2C%20137.5%2085.9%2C%20137.2%2085.9%20C%20136.8%2086.0%2C%20134.9%2088.6%2C%20133.0%2091.8%20C%20127.6%20100.8%2C%20122.7%20106.4%2C%20120.2%20106.4%20C%20119.8%20106.5%2C%20119.6%20106.2%2C%20119.3%20105.5%20C%20118.4%20103.6%2C%20118.5%2098.5%2C%20119.5%2092.6%20C%20120.0%2089.7%2C%20121.4%2084.1%2C%20122.6%2080.4%20C%20123.4%2077.7%2C%20123.6%2076.6%2C%20123.2%2076.6%20C%20122.8%2076.6%2C%20124.0%2073.1%2C%20125.2%2070.3%20C%20125.6%2069.4%2C%20125.9%2068.4%2C%20125.9%2068.1%20C%20125.9%2067.7%2C%20125.8%2067.6%2C%20125.2%2067.7%20L%20124.6%2067.9%20124.7%2066.7%20C%20124.8%2066.0%2C%20125.1%2064.6%2C%20125.4%2063.5%20C%20125.7%2062.3%2C%20125.9%2061.4%2C%20125.8%2061.0%20C%20125.7%2060.5%2C%20126.0%2059.2%2C%20126.7%2056.7%20C%20127.3%2054.8%2C%20127.7%2053.0%2C%20127.7%2052.9%20C%20127.7%2052.7%2C%20126.9%2053.4%2C%20125.8%2054.4%20C%20124.7%2055.5%2C%20123.7%2056.3%2C%20123.6%2056.3%20C%20123.4%2056.3%2C%20122.6%2056.8%2C%20121.7%2057.4%20C%20120.5%2058.2%2C%20119.7%2058.6%2C%20119.1%2058.7%20C%20118.4%2058.8%2C%20118.3%2058.8%2C%20117.9%2058.1%20C%20117.1%2056.9%2C%20117.0%2055.1%2C%20117.4%2051.5%20C%20117.7%2048.8%2C%20117.7%2048.2%2C%20117.4%2047.7%20C%20117.1%2047.0%2C%20117.0%2044.0%2C%20117.3%2041.0%20C%20117.4%2039.7%2C%20117.5%2038.5%2C%20117.4%2038.5%20C%20117.3%2038.4%2C%20116.9%2038.7%2C%20116.4%2039.1%20C%20114.9%2040.5%2C%20114.0%2040.5%2C%20113.4%2039.3%20C%20112.8%2038.2%2C%20112.5%2036.4%2C%20112.5%2033.7%20C%20112.5%2031.6%2C%20112.5%2031.4%2C%20112.2%2031.5%20C%20111.4%2031.8%2C%20111.2%2031.7%2C%20110.9%2030.8%20C%20110.8%2030.3%2C%20110.6%2028.9%2C%20110.5%2027.8%20C%20110.3%2025.4%2C%20110.2%2025.1%2C%20109.7%2025.5%20C%20109.5%2025.7%2C%20109.4%2025.7%2C%20109.3%2025.4%20C%20109.0%2024.4%2C%20108.1%2018.4%2C%20107.8%2014.4%20C%20107.4%2010.1%2C%20107.1%208.0%2C%20106.9%208.0%20C%20106.8%208.0%2C%20106.6%208.4%2C%20106.4%208.9%27%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
    --maple-宽扁: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20800%20800%27%3E%3Cg%20transform%3D%27translate(350%2C350)%20scale(0.5)%27%3E%3Cpath%20d%3D%27M%20100.4%208.8%20C%20100.2%209.2%2C%2099.7%2010.6%2C%2099.3%2012.0%20C%2098.4%2014.5%2C%2095.4%2020.9%2C%2094.2%2022.5%20C%2093.8%2023.0%2C%2093.4%2023.4%2C%2093.3%2023.3%20C%2093.1%2023.2%2C%2092.9%2023.1%2C%2092.7%2023.1%20C%2092.3%2022.9%2C%2091.9%2023.6%2C%2090.8%2026.8%20C%2089.9%2029.8%2C%2088.9%2031.5%2C%2088.2%2032.0%20C%2087.9%2032.1%2C%2087.4%2032.1%2C%2086.9%2032.1%20C%2086.2%2031.9%2C%2086.1%2031.9%2C%2085.5%2032.9%20C%2084.0%2035.5%2C%2083.5%2036.2%2C%2083.0%2036.5%20C%2082.5%2036.9%2C%2082.3%2036.9%2C%2081.2%2036.7%20C%2079.1%2036.3%2C%2077.8%2035.7%2C%2076.6%2034.6%20C%2076.0%2034.0%2C%2075.5%2033.6%2C%2075.4%2033.7%20C%2075.2%2033.9%2C%2075.2%2036.7%2C%2075.5%2041.3%20C%2075.6%2043.7%2C%2075.7%2045.2%2C%2075.5%2045.5%20C%2075.2%2046.0%2C%2075.3%2047.1%2C%2075.7%2049.7%20C%2076.1%2052.7%2C%2076.0%2055.6%2C%2075.4%2056.4%20C%2074.9%2057.2%2C%2074.0%2057.3%2C%2072.9%2056.7%20C%2071.5%2056.0%2C%2071.5%2056.5%2C%2072.8%2059.7%20C%2074.3%2063.2%2C%2076.9%2072.1%2C%2077.8%2076.7%20C%2078.3%2079.4%2C%2078.3%2083.7%2C%2077.8%2085.1%20C%2077.0%2087.4%2C%2076.1%2087.8%2C%2074.0%2086.8%20C%2071.5%2085.6%2C%2069.7%2083.7%2C%2066.4%2078.4%20C%2064.1%2074.8%2C%2062.7%2072.9%2C%2060.5%2070.3%20C%2059.8%2069.4%2C%2058.2%2067.3%2C%2057.1%2065.7%20C%2055.2%2063.0%2C%2053.8%2061.3%2C%2053.5%2061.3%20C%2053.4%2061.3%2C%2053.2%2061.8%2C%2053.1%2062.5%20C%2052.8%2064.5%2C%2051.7%2065.6%2C%2050.2%2065.6%20C%2049.2%2065.6%2C%2047.2%2064.5%2C%2044.3%2062.3%20C%2042.8%2061.1%2C%2041.4%2060.2%2C%2041.0%2060.1%20C%2040.7%2060.0%2C%2039.9%2059.4%2C%2039.1%2058.7%20C%2037.7%2057.4%2C%2037.0%2057.1%2C%2036.5%2057.5%20C%2036.1%2057.9%2C%2032.1%2055.8%2C%2029.8%2054.0%20C%2027.3%2052.0%2C%2024.4%2050.0%2C%2024.0%2050.0%20C%2023.6%2050.0%2C%2023.6%2050.4%2C%2024.8%2052.9%20C%2026.0%2055.9%2C%2026.5%2057.6%2C%2027.1%2061.6%20C%2027.6%2065.3%2C%2027.6%2066.3%2C%2026.9%2066.4%20C%2026.7%2066.5%2C%2026.4%2066.7%2C%2026.4%2066.9%20C%2026.2%2067.4%2C%2026.7%2069.4%2C%2027.4%2071.3%20C%2028.0%2072.7%2C%2028.3%2073.7%2C%2028.6%2075.2%20C%2028.6%2075.4%2C%2028.5%2075.8%2C%2028.3%2076.1%20C%2028.1%2076.4%2C%2027.9%2077.1%2C%2027.8%2078.1%20C%2027.7%2080.3%2C%2027.2%2081.1%2C%2026.0%2081.6%20C%2025.0%2082.0%2C%2023.5%2082.1%2C%2021.6%2081.8%20C%2020.8%2081.7%2C%2020.4%2081.7%2C%2020.4%2081.8%20C%2020.4%2082.0%2C%2021.0%2082.8%2C%2021.7%2083.8%20C%2022.4%2084.7%2C%2023.6%2086.5%2C%2024.3%2087.7%20C%2025.1%2088.8%2C%2026.1%2090.3%2C%2026.7%2090.9%20C%2027.5%2091.8%2C%2027.7%2092.1%2C%2027.5%2092.3%20C%2027.1%2092.7%2C%2027.2%2093.0%2C%2028.3%2094.1%20C%2030.3%2096.2%2C%2035.0%20102.2%2C%2035.2%20102.9%20C%2035.3%20103.3%2C%2035.4%20103.9%2C%2035.3%20104.3%20C%2035.0%20105.2%2C%2033.5%20106.5%2C%2031.2%20107.7%20C%2030.0%20108.3%2C%2029.0%20108.8%2C%2028.9%20108.9%20C%2028.5%20109.5%2C%2025.1%20110.7%2C%2022.5%20111.3%20C%2021.3%20111.5%2C%2020.3%20111.8%2C%2020.3%20111.9%20C%2020.2%20112.1%2C%2021.1%20112.6%2C%2022.2%20113.1%20C%2023.3%20113.6%2C%2025.5%20114.7%2C%2026.9%20115.6%20C%2028.4%20116.5%2C%2030.2%20117.6%2C%2030.9%20117.9%20C%2031.7%20118.3%2C%2032.0%20118.6%2C%2032.0%20118.8%20C%2031.8%20119.3%2C%2032.5%20119.6%2C%2034.9%20120.2%20C%2037.9%20121.0%2C%2038.6%20121.3%2C%2042.2%20123.8%20C%2044.0%20125.0%2C%2046.8%20126.7%2C%2048.4%20127.6%20C%2051.9%20129.6%2C%2053.5%20130.9%2C%2054.0%20131.9%20C%2054.3%20132.7%2C%2054.3%20132.8%2C%2054.0%20133.4%20C%2053.8%20133.7%2C%2053.3%20134.3%2C%2052.8%20134.7%20C%2051.6%20135.8%2C%2047.8%20137.9%2C%2046.0%20138.7%20C%2045.1%20139.1%2C%2044.2%20139.5%2C%2043.8%20139.7%20L%2043.2%20140.0%2043.8%20140.5%20C%2044.6%20141.1%2C%2044.6%20141.1%2C%2041.1%20143.7%20C%2039.6%20144.8%2C%2038.2%20145.9%2C%2038.1%20146.0%20C%2038.0%20146.2%2C%2037.1%20146.9%2C%2036.0%20147.6%20C%2034.9%20148.3%2C%2032.8%20149.6%2C%2031.2%20150.6%20C%2029.7%20151.6%2C%2027.6%20152.8%2C%2026.5%20153.3%20C%2025.4%20153.7%2C%2024.6%20154.2%2C%2024.6%20154.3%20C%2024.6%20154.5%2C%2025.1%20154.5%2C%2029.3%20154.9%20C%2032.2%20155.2%2C%2038.1%20156.4%2C%2039.5%20157.0%20C%2040.0%20157.2%2C%2040.8%20157.4%2C%2041.6%20157.4%20C%2042.9%20157.4%2C%2044.2%20157.7%2C%2044.4%20158.0%20C%2044.5%20158.2%2C%2044.5%20158.4%2C%2044.3%20158.5%20C%2044.0%20159.0%2C%2044.5%20159.1%2C%2046.9%20159.1%20C%2050.0%20159.1%2C%2052.9%20160.0%2C%2053.8%20161.2%20C%2054.2%20161.8%2C%2054.2%20163.1%2C%2053.7%20164.1%20C%2053.5%20164.5%2C%2053.3%20164.9%2C%2053.3%20165.0%20C%2053.3%20165.2%2C%2054.6%20165.1%2C%2055.8%20164.8%20C%2056.4%20164.6%2C%2057.8%20164.1%2C%2058.8%20163.7%20C%2061.5%20162.6%2C%2064.1%20162.0%2C%2066.7%20161.8%20C%2070.4%20161.6%2C%2071.3%20162.1%2C%2071.1%20164.1%20C%2071.0%20164.6%2C%2071.0%20165.1%2C%2071.1%20165.2%20C%2071.3%20165.3%2C%2072.3%20164.8%2C%2074.2%20163.5%20C%2075.1%20162.8%2C%2076.3%20162.1%2C%2077.0%20161.8%20C%2078.7%20161.1%2C%2080.2%20160.0%2C%2082.9%20157.8%20C%2085.4%20155.6%2C%2088.1%20153.6%2C%2089.1%20153.1%20L%2089.7%20152.8%2089.6%20155.0%20C%2089.4%20158.5%2C%2088.7%20162.2%2C%2086.9%20169.3%20C%2085.0%20176.5%2C%2083.3%20181.6%2C%2081.3%20185.8%20C%2079.8%20189.1%2C%2079.7%20189.7%2C%2080.8%20190.6%20C%2081.8%20191.4%2C%2083.4%20192.0%2C%2084.8%20192.0%20C%2085.8%20192.0%2C%2086.1%20191.9%2C%2086.6%20191.4%20C%2087.2%20190.8%2C%2087.4%20190.0%2C%2087.9%20186.4%20C%2088.6%20181.4%2C%2090.2%20174.4%2C%2093.4%20162.5%20C%2095.0%20156.6%2C%2095.7%20154.3%2C%2095.9%20154.3%20C%2096.2%20154.3%2C%2098.2%20156.0%2C%2099.1%20157.1%20C%2099.6%20157.7%2C%20100.6%20158.8%2C%20101.2%20159.7%20C%20103.2%20162.2%2C%20105.0%20164.1%2C%20106.5%20165.4%20C%20107.3%20166.0%2C%20108.0%20166.6%2C%20108.1%20166.6%20C%20108.2%20166.6%2C%20108.6%20166.8%2C%20109.0%20167.2%20C%20109.4%20167.5%2C%20110.0%20167.8%2C%20110.3%20167.9%20C%20111.1%20168.2%2C%20114.6%20170.6%2C%20116.4%20172.2%20C%20118.4%20174.0%2C%20118.7%20174.0%2C%20118.5%20172.5%20C%20118.4%20170.9%2C%20118.8%20169.3%2C%20119.6%20168.7%20C%20120.1%20168.2%2C%20120.3%20168.2%2C%20121.3%20168.3%20C%20122.7%20168.4%2C%20124.5%20169.0%2C%20126.8%20170.0%20C%20128.7%20170.8%2C%20128.8%20170.9%2C%20128.8%20170.3%20C%20128.8%20169.7%2C%20129.5%20169.8%2C%20131.6%20170.5%20C%20133.2%20171.2%2C%20133.4%20171.2%2C%20137.3%20171.2%20C%20140.9%20171.3%2C%20141.7%20171.3%2C%20143.9%20171.8%20C%20145.2%20172.2%2C%20147.5%20172.8%2C%20148.9%20173.3%20C%20152.6%20174.5%2C%20153.1%20174.7%2C%20153.2%20174.5%20C%20153.3%20174.4%2C%20152.5%20173.4%2C%20151.5%20172.2%20C%20149.5%20170.1%2C%20146.1%20165.2%2C%20146.1%20164.5%20C%20146.1%20164.3%2C%20145.4%20163.1%2C%20144.5%20161.9%20C%20142.9%20159.6%2C%20142.3%20158.5%2C%20142.0%20157.7%20C%20141.9%20157.3%2C%20142.0%20157.1%2C%20142.5%20156.9%20L%20143.2%20156.5%20142.5%20155.8%20C%20142.1%20155.4%2C%20141.2%20154.6%2C%20140.5%20154.0%20C%20139.1%20152.9%2C%20137.1%20150.6%2C%20136.5%20149.3%20C%20135.4%20147.1%2C%20135.5%20145.3%2C%20136.9%20143.9%20C%20137.9%20142.9%2C%20141.0%20141.4%2C%20143.1%20140.8%20C%20145.2%20140.3%2C%20150.7%20140.3%2C%20153.1%20140.8%20C%20154.5%20141.2%2C%20155.0%20141.2%2C%20155.9%20141.0%20C%20156.5%20140.9%2C%20157.7%20140.7%2C%20158.6%20140.5%20C%20160.5%20140.3%2C%20162.9%20139.6%2C%20166.0%20138.4%20C%20167.2%20137.9%2C%20169.1%20137.2%2C%20170.2%20137.0%20C%20171.4%20136.7%2C%20172.1%20136.5%2C%20172.0%20136.3%20C%20172.0%20136.2%2C%20171.4%20135.8%2C%20170.8%20135.5%20C%20167.4%20133.7%2C%20163.1%20130.4%2C%20163.2%20129.6%20C%20163.2%20129.4%2C%20162.6%20128.8%2C%20161.8%20128.1%20C%20159.8%20126.6%2C%20158.0%20124.9%2C%20157.5%20124.1%20C%20156.9%20123.1%2C%20157.0%20122.1%2C%20157.7%20120.9%20C%20158.5%20119.4%2C%20162.7%20114.9%2C%20163.9%20114.2%20C%20166.1%20112.8%2C%20166.4%20112.5%2C%20166.3%20112.0%20C%20166.2%20111.5%2C%20166.4%20111.3%2C%20167.6%20110.5%20C%20168.3%20110.0%2C%20169.7%20108.7%2C%20170.6%20107.6%20C%20171.6%20106.6%2C%20173.2%20104.8%2C%20174.3%20103.8%20C%20175.4%20102.7%2C%20176.2%20101.7%2C%20176.2%20101.6%20C%20176.2%20101.4%2C%20175.7%20101.3%2C%20174.1%20101.3%20C%20172.2%20101.3%2C%20171.8%20101.3%2C%20170.8%20100.8%20C%20169.1%20100.0%2C%20168.9%2099.5%2C%20168.9%2097.2%20C%20168.9%2095.4%2C%20168.8%2095.3%2C%20168.3%2094.7%20C%20168.0%2094.4%2C%20167.7%2093.9%2C%20167.7%2093.7%20C%20167.7%2092.7%2C%20169.0%2090.1%2C%20171.4%2086.3%20C%20172.7%2084.3%2C%20172.9%2083.6%2C%20172.3%2083.4%20C%20171.6%2083.2%2C%20171.8%2082.3%2C%20173.2%2079.2%20C%20173.4%2078.8%2C%20173.7%2077.8%2C%20173.8%2077.0%20C%20174.5%2073.9%2C%20176.3%2070.5%2C%20178.7%2067.5%20C%20179.3%2066.8%2C%20179.8%2066.1%2C%20179.8%2066.0%20C%20179.8%2065.4%2C%20177.3%2066.3%2C%20173.4%2068.1%20C%20170.7%2069.5%2C%20168.2%2070.4%2C%20166.2%2070.7%20C%20165.5%2070.9%2C%20165.4%2070.8%2C%20165.3%2070.4%20C%20165.1%2069.9%2C%20164.8%2070.0%2C%20162.7%2071.3%20C%20161.8%2071.9%2C%20161.0%2072.3%2C%20160.8%2072.2%20C%20160.6%2072.2%2C%20159.3%2072.8%2C%20157.9%2073.6%20C%20153.2%2076.3%2C%20151.7%2076.8%2C%20150.4%2076.0%20C%20149.7%2075.5%2C%20149.1%2074.3%2C%20149.1%2073.2%20C%20149.1%2072.7%2C%20149.0%2072.3%2C%20148.9%2072.3%20C%20148.3%2072.3%2C%20146.5%2073.9%2C%20141.7%2078.7%20C%20137.0%2083.5%2C%20136.2%2084.2%2C%20130.9%2088.2%20C%20127.7%2090.6%2C%20124.8%2092.7%2C%20124.4%2093.0%20C%20122.4%2093.9%2C%20120.6%2091.9%2C%20120.1%2088.3%20C%20119.3%2082.2%2C%20120.7%2076.1%2C%20125.3%2065.9%20C%20127.3%2061.5%2C%20127.9%2060.1%2C%20128.1%2059.3%20C%20128.2%2058.7%2C%20128.2%2058.7%2C%20127.6%2058.8%20C%20126.5%2059.1%2C%20126.4%2058.6%2C%20127.1%2056.5%20C%20127.5%2055.3%2C%20127.9%2053.7%2C%20128.0%2052.5%20C%20128.1%2051.4%2C%20128.4%2049.4%2C%20128.7%2048.0%20C%20129.2%2045.4%2C%20129.3%2044.3%2C%20129.0%2043.8%20C%20128.9%2043.6%2C%20128.6%2043.7%2C%20127.7%2044.4%20C%20127.1%2044.9%2C%20126.1%2045.5%2C%20125.5%2045.7%20C%20124.3%2046.1%2C%20120.3%2046.8%2C%20120.0%2046.6%20C%20119.9%2046.5%2C%20119.7%2046.1%2C%20119.4%2045.6%20C%20119.0%2044.9%2C%20119.0%2044.8%2C%20117.9%2044.8%20C%20116.5%2044.8%2C%20115.8%2044.4%2C%20114.9%2043.0%20C%20113.8%2041.3%2C%20113.4%2039.2%2C%20113.3%2035.1%20C%20113.2%2031.2%2C%20113.1%2029.9%2C%20112.8%2029.7%20C%20112.7%2029.7%2C%20112.3%2029.8%2C%20112.0%2030.0%20C%20111.5%2030.3%2C%20111.5%2030.3%2C%20111.1%2029.8%20C%20110.7%2029.4%2C%20109.3%2026.3%2C%20108.2%2023.5%20C%20107.7%2022.4%2C%20107.6%2022.3%2C%20107.1%2022.3%20C%20106.6%2022.4%2C%20106.5%2022.2%2C%20105.4%2020.0%20C%20104.3%2017.7%2C%20103.7%2016.1%2C%20102.7%2012.4%20C%20102.1%2010.4%2C%20101.2%208.0%2C%20100.9%208.0%20C%20100.9%208.0%2C%20100.6%208.4%2C%20100.4%208.8%27%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
    --maple-侧翻: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20800%20800%27%3E%3Cg%20transform%3D%27translate(350%2C350)%20scale(0.5)%27%3E%3Cpath%20d%3D%27M%20120.4%2010.1%20C%20119.6%2011.3%2C%20118.7%2012.6%2C%20118.3%2013.0%20C%20118.0%2013.4%2C%20117.3%2014.6%2C%20116.8%2015.8%20C%20115.7%2018.0%2C%20114.4%2019.6%2C%20114.1%2019.1%20C%20114.0%2018.9%2C%20113.6%2019.5%2C%20112.8%2020.7%20C%20111.8%2022.4%2C%20108.3%2026.8%2C%20107.5%2027.5%20C%20107.2%2027.7%2C%20107.1%2027.7%2C%20106.6%2027.1%20C%20106.1%2026.5%2C%20106.1%2026.5%2C%20105.7%2026.9%20C%20105.1%2027.7%2C%20103.8%2029.9%2C%20102.2%2032.9%20C%20100.4%2036.3%2C%2099.6%2037.4%2C%2099.1%2037.4%20C%2098.8%2037.4%2C%2098.0%2038.2%2C%2097.2%2039.2%20C%2095.7%2041.0%2C%2094.2%2042.4%2C%2093.4%2042.6%20C%2093.1%2042.7%2C%2092.6%2042.7%2C%2092.3%2042.5%20C%2091.5%2042.3%2C%2088.3%2039.0%2C%2088.0%2038.3%20C%2087.9%2037.8%2C%2085.7%2035.3%2C%2085.4%2035.3%20C%2085.1%2035.3%2C%2084.9%2037.4%2C%2084.8%2040.6%20C%2084.8%2042.8%2C%2084.6%2043.9%2C%2084.3%2045.0%20C%2083.9%2046.2%2C%2083.8%2046.8%2C%2083.9%2049.9%20C%2084.1%2054.0%2C%2083.9%2054.8%2C%2083.0%2054.8%20C%2082.4%2054.8%2C%2082.4%2054.9%2C%2082.4%2056.0%20C%2082.4%2056.7%2C%2082.6%2058.4%2C%2082.8%2059.8%20C%2083.1%2062.3%2C%2083.1%2062.5%2C%2082.7%2064.6%20C%2082.4%2066.3%2C%2082.3%2067.7%2C%2082.4%2071.9%20C%2082.4%2077.5%2C%2082.3%2078.5%2C%2081.2%2080.7%20C%2080.4%2082.2%2C%2077.6%2086.1%2C%2077.3%2086.1%20C%2076.6%2086.1%2C%2071.8%2076.0%2C%2070.4%2071.7%20C%2070.2%2071.0%2C%2069.8%2070.2%2C%2069.5%2069.9%20C%2069.2%2069.6%2C%2068.9%2069.0%2C%2068.9%2068.5%20C%2068.7%2067.6%2C%2066.9%2063.8%2C%2066.7%2063.9%20C%2066.6%2063.9%2C%2066.1%2064.6%2C%2065.6%2065.4%20C%2065.0%2066.4%2C%2064.4%2067.1%2C%2063.9%2067.4%20L%2063.1%2067.8%2062.0%2067.0%20C%2060.7%2066.1%2C%2058.6%2063.4%2C%2057.5%2061.4%20C%2056.7%2059.9%2C%2054.5%2056.5%2C%2054.1%2056.3%20C%2053.9%2056.2%2C%2053.6%2056.3%2C%2053.4%2056.6%20C%2052.7%2057.5%2C%2052.4%2057.4%2C%2050.4%2055.7%20C%2046.3%2052.3%2C%2042.9%2048.8%2C%2041.4%2046.6%20C%2040.3%2045.1%2C%2038.7%2043.4%2C%2036.0%2041.2%20L%2035.3%2040.6%2035.4%2042.9%20C%2035.5%2044.2%2C%2035.8%2046.0%2C%2036.0%2047.0%20C%2036.6%2049.4%2C%2037.1%2054.5%2C%2036.9%2056.4%20C%2036.8%2057.6%2C%2036.7%2058.0%2C%2036.3%2058.3%20L%2035.7%2058.7%2036.1%2061.3%20C%2036.7%2065.1%2C%2036.6%2067.6%2C%2036.0%2068.8%20C%2035.5%2069.7%2C%2035.5%2069.9%2C%2035.8%2072.0%20C%2036.1%2074.9%2C%2036.1%2076.3%2C%2035.6%2077.5%20C%2035.0%2079.0%2C%2034.2%2079.2%2C%2030.7%2078.9%20C%2029.2%2078.8%2C%2027.6%2078.6%2C%2027.2%2078.5%20C%2026.7%2078.5%2C%2026.3%2078.5%2C%2026.3%2078.6%20C%2026.3%2078.7%2C%2026.7%2079.4%2C%2027.1%2080.2%20C%2027.6%2081.0%2C%2028.4%2082.3%2C%2029.0%2083.2%20C%2029.5%2084.1%2C%2030.2%2085.0%2C%2030.5%2085.3%20C%2030.7%2085.5%2C%2030.9%2085.9%2C%2030.9%2086.1%20C%2030.9%2086.3%2C%2031.9%2087.9%2C%2033.0%2089.6%20C%2034.4%2091.7%2C%2035.1%2092.9%2C%2035.1%2093.4%20C%2035.1%2093.8%2C%2035.8%2094.9%2C%2037.6%2097.4%20C%2042.6%20104.2%2C%2043.3%20105.5%2C%2043.6%20109.0%20L%2043.7%20110.7%2042.7%20110.7%20C%2041.3%20110.7%2C%2039.5%20110.2%2C%2035.9%20108.8%20C%2032.2%20107.4%2C%2031.8%20107.4%2C%2031.7%20108.0%20C%2031.6%20108.3%2C%2031.4%20108.7%2C%2031.2%20108.9%20C%2030.7%20109.3%2C%2030.5%20109.3%2C%2027.7%20109.1%20C%2021.1%20108.4%2C%2020.6%20108.3%2C%2017.3%20107.3%20C%2015.4%20106.7%2C%2013.9%20106.3%2C%2013.8%20106.4%20C%2013.6%20106.6%2C%2017.0%20111.1%2C%2019.5%20113.7%20C%2020.5%20114.8%2C%2022.1%20116.8%2C%2023.1%20118.1%20C%2024.0%20119.4%2C%2025.4%20121.3%2C%2026.1%20122.3%20C%2027.5%20124.2%2C%2027.6%20124.7%2C%2027.2%20125.5%20C%2027.0%20125.8%2C%2027.2%20126.1%2C%2028.4%20127.2%20C%2029.1%20127.9%2C%2030.5%20128.9%2C%2031.4%20129.5%20C%2033.2%20130.7%2C%2039.7%20137.1%2C%2040.6%20138.6%20C%2041.1%20139.4%2C%2041.1%20139.5%2C%2040.7%20140.2%20C%2040.4%20140.9%2C%2037.6%20143.8%2C%2036.6%20144.4%20C%2036.3%20144.6%2C%2036.0%20144.9%2C%2036.0%20145.0%20C%2036.0%20145.3%2C%2038.6%20146.8%2C%2039.8%20147.0%20C%2040.4%20147.2%2C%2041.0%20147.5%2C%2041.2%20147.8%20C%2041.4%20148.0%2C%2042.5%20148.5%2C%2043.8%20148.9%20C%2046.0%20149.7%2C%2046.1%20149.7%2C%2046.1%20150.4%20L%2046.1%20151.1%2049.4%20152.0%20C%2052.8%20152.8%2C%2055.8%20154.1%2C%2056.4%20154.8%20C%2056.7%20155.2%2C%2056.7%20155.3%2C%2056.1%20156.5%20L%2055.3%20157.9%2056.4%20158.0%20C%2058.3%20158.3%2C%2063.9%20158.2%2C%2066.0%20157.8%20C%2067.2%20157.6%2C%2069.4%20157.5%2C%2070.9%20157.5%20C%2072.5%20157.5%2C%2074.3%20157.4%2C%2075.1%20157.2%20C%2075.8%20157.1%2C%2076.4%20157.0%2C%2076.5%20157.1%20C%2076.7%20157.2%2C%2071.3%20167.4%2C%2069.8%20169.8%20C%2066.9%20174.1%2C%2065.5%20175.8%2C%2059.9%20181.3%20C%2056.4%20184.8%2C%2054.3%20187.0%2C%2054.2%20187.4%20C%2054.1%20187.9%2C%2054.2%20188.3%2C%2055.0%20189.4%20C%2056.0%20190.9%2C%2057.6%20192.0%2C%2059.0%20192.0%20C%2060.0%20192.0%2C%2060.7%20191.3%2C%2062.3%20188.5%20C%2062.9%20187.4%2C%2064.3%20185.2%2C%2065.3%20183.5%20C%2067.9%20179.6%2C%2072.2%20172.8%2C%2074.2%20169.5%20C%2077.4%20164.3%2C%2080.6%20159.2%2C%2080.9%20158.7%20C%2081.2%20158.4%2C%2081.3%20158.4%2C%2081.4%20158.6%20C%2081.5%20158.8%2C%2082.2%20160.3%2C%2083.0%20162.0%20C%2084.8%20165.4%2C%2088.9%20171.8%2C%2090.6%20173.6%20L%2091.7%20174.9%2092.2%20174.2%20C%2092.7%20173.3%2C%2092.8%20173.3%2C%2095.2%20175.0%20C%2097.2%20176.4%2C%2099.6%20178.7%2C%20101.5%20180.9%20C%20102.3%20182.0%2C%20102.7%20182.2%2C%20102.9%20182.0%20C%20103.1%20181.8%2C%20103.6%20182.2%2C%20105.1%20183.5%20C%20106.2%20184.4%2C%20107.5%20185.5%2C%20108.0%20185.9%20C%20108.6%20186.2%2C%20109.6%20187.0%2C%20110.2%20187.5%20C%20111.8%20188.7%2C%20113.7%20189.8%2C%20113.7%20189.5%20C%20113.7%20189.4%2C%20113.4%20188.3%2C%20113.1%20187.0%20C%20112.4%20184.3%2C%20112.1%20179.2%2C%20112.6%20177.9%20C%20112.8%20177.1%2C%20113.0%20177.0%2C%20114.0%20176.9%20C%20115.5%20176.6%2C%20118.5%20176.8%2C%20121.5%20177.4%20C%20125.4%20178.1%2C%20129.5%20178.8%2C%20130.1%20178.8%20C%20130.7%20178.8%2C%20130.7%20178.7%2C%20130.6%20177.9%20C%20130.6%20177.4%2C%20130.6%20176.9%2C%20130.6%20176.9%20C%20130.7%20176.9%2C%20131.4%20176.8%2C%20132.3%20176.6%20C%20134.8%20176.0%2C%20143.0%20175.7%2C%20150.0%20175.7%20C%20153.5%20175.8%2C%20156.3%20175.8%2C%20156.3%20175.7%20C%20156.3%20175.5%2C%20153.2%20173.1%2C%20151.4%20172.0%20C%20148.7%20170.2%2C%20147.7%20169.3%2C%20147.8%20168.8%20C%20147.9%20168.6%2C%20147.4%20168.0%2C%20145.9%20166.9%20C%20143.6%20165.2%2C%20141.7%20163.2%2C%20141.1%20161.9%20C%20140.7%20161.3%2C%20140.7%20161.2%2C%20141.1%20160.6%20C%20141.5%20160.0%2C%20141.5%20160.0%2C%20140.0%20159.0%20C%20139.2%20158.5%2C%20138.2%20157.8%2C%20137.6%20157.5%20C%20135.7%20156.3%2C%20133.5%20154.4%2C%20132.7%20153.2%20C%20132.3%20152.6%2C%20132.0%20151.9%2C%20132.0%20151.7%20C%20132.0%20150.9%2C%20136.3%20148.6%2C%20141.6%20146.8%20C%20143.5%20146.1%2C%20145.7%20145.3%2C%20146.5%20145.0%20C%20147.2%20144.7%2C%20148.8%20144.2%2C%20149.9%20143.9%20C%20152.6%20143.2%2C%20153.8%20142.8%2C%20153.8%20142.3%20C%20153.8%20141.8%2C%20154.2%20141.6%2C%20157.4%20140.5%20C%20160.4%20139.5%2C%20161.2%20139.1%2C%20161.8%20138.5%20C%20162.0%20138.3%2C%20163.5%20137.8%2C%20165.1%20137.3%20C%20166.7%20136.9%2C%20168.6%20136.3%2C%20169.2%20135.9%20L%20170.5%20135.3%20169.0%20134.5%20C%20168.2%20134.1%2C%20167.1%20133.4%2C%20166.5%20133.0%20C%20165.9%20132.6%2C%20164.9%20132.0%2C%20164.4%20131.7%20C%20163.8%20131.4%2C%20163.1%20130.7%2C%20162.8%20130.2%20L%20162.3%20129.3%20163.0%20127.8%20C%20164.4%20125.0%2C%20167.8%20121.0%2C%20170.7%20118.8%20C%20171.4%20118.3%2C%20172.2%20117.6%2C%20172.4%20117.4%20C%20172.8%20117.0%2C%20172.8%20116.9%2C%20172.0%20116.5%20C%20171.6%20116.2%2C%20171.2%20115.8%2C%20171.1%20115.6%20C%20170.8%20114.8%2C%20172.7%20111.8%2C%20175.1%20109.0%20C%20176.1%20107.9%2C%20176.7%20107.0%2C%20176.7%20106.7%20C%20176.7%20105.7%2C%20178.7%20103.3%2C%20184.3%2097.8%20C%20185.5%2096.6%2C%20186.4%2095.5%2C%20186.4%2095.4%20C%20186.4%2095.1%2C%20185.0%2095.4%2C%20180.1%2096.6%20C%20175.2%2097.7%2C%20173.4%2097.9%2C%20173.4%2097.3%20C%20173.4%2096.9%2C%20172.6%2097.0%2C%20170.8%2097.7%20C%20169.9%2098.1%2C%20168.9%2098.2%2C%20166.7%2098.3%20C%20163.9%2098.4%2C%20163.8%2098.4%2C%20163.6%2097.9%20C%20163.5%2097.7%2C%20163.5%2097.1%2C%20163.6%2096.7%20C%20163.8%2096.1%2C%20163.7%2096.0%2C%20163.2%2096.2%20C%20163.0%2096.3%2C%20161.2%2097.1%2C%20159.2%2098.1%20C%20157.3%2099.0%2C%20155.5%2099.8%2C%20155.1%2099.8%20C%20154.8%2099.8%2C%20153.9%20100.0%2C%20153.1%20100.2%20C%20151.2%20100.8%2C%20148.0%20101.3%2C%20147.2%20101.1%20C%20146.1%20100.8%2C%20145.8%2099.7%2C%20145.8%2096.5%20C%20145.8%2095.0%2C%20145.8%2093.7%2C%20145.7%2093.7%20C%20145.3%2093.7%2C%20142.7%2095.7%2C%20140.4%2097.7%20C%20135.6%20102.0%2C%20129.8%20106.2%2C%20126.1%20108.0%20C%20124.0%20109.0%2C%20120.5%20110.2%2C%20118.9%20110.6%20L%20118.1%20110.7%20118.2%20104.8%20C%20118.3%2098.7%2C%20118.4%2097.8%2C%20119.6%2094.6%20C%20120.5%2091.9%2C%20122.5%2088.1%2C%20124.9%2084.3%20C%20126.1%2082.4%2C%20127.4%2080.1%2C%20127.9%2079.3%20C%20128.7%2077.8%2C%20128.8%2077.7%2C%20128.4%2077.3%20C%20128.1%2077.0%2C%20128.1%2076.7%2C%20128.2%2076.2%20C%20128.4%2075.2%2C%20130.1%2071.7%2C%20131.6%2069.1%20C%20132.3%2067.8%2C%20132.9%2066.5%2C%20132.9%2066.1%20C%20132.9%2065.5%2C%20133.5%2063.8%2C%20134.2%2062.7%20C%20135.1%2061.0%2C%20137.2%2054.9%2C%20137.0%2054.6%20C%20136.9%2054.6%2C%20135.9%2054.9%2C%20134.7%2055.3%20C%20133.0%2055.9%2C%20132.1%2056.0%2C%20130.2%2056.1%20C%20128.7%2056.2%2C%20127.7%2056.2%2C%20127.4%2056.0%20C%20126.5%2055.5%2C%20125.9%2053.1%2C%20125.9%2050.1%20C%20125.9%2048.7%2C%20125.8%2047.1%2C%20125.7%2046.6%20C%20125.5%2046.0%2C%20125.5%2044.7%2C%20125.7%2041.9%20C%20126.0%2037.7%2C%20125.9%2036.8%2C%20125.3%2037.1%20C%20123.6%2037.8%2C%20123.3%2037.3%2C%20122.6%2032.4%20C%20122.2%2029.9%2C%20121.8%2023.9%2C%20121.7%2021.2%20C%20121.7%2020.4%2C%20121.8%2017.1%2C%20121.8%2013.9%20C%20121.9%2010.6%2C%20121.9%208.0%2C%20121.9%208.0%20C%20121.8%208.0%2C%20121.1%209.0%2C%20120.4%2010.1%27%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
  --maple-a: #c1440e;         /* 枫红 */
  --maple-b: #e07b39;         /* 橙金 */
  --maple-c: #a8341a;         /* 深枫红 */
  --maple-d: #d9a441;         /* 银杏黄 */
}

/* ---------- ② 叶子：**两层叶场**（铺开的稀疏底纹）+ **两片前景大叶** ----------
   为什么不是"四片叶子"：第一版就是四片，结果**一屏只看得见两片**（其余在屏幕外），
   完全没有"天气感"。叶场给密度，前景叶给层次。

   ⚠️ **叶子的"在不在"和"飘不飘"是分开写的**：
      位置 / 大小 / 颜色写在**闸门外面** → 开了"减少动态效果"的人**也看得到枫叶**，
      只是它们**静止**；动画写在闸门里面。
      （第一版把整片叶子塞进闸门里，reduce 的人一片都看不到，而且我的截图脚本
        全部用 `reducedMotion:'reduce'` —— **截图里也一片叶子都没有**。
        "能进截图的改变，才是用户判断得了的改变"这条又踩了一次。）

   层次：`z-index: 0` 的定位元素画在**非定位内容之上** → 叶子飘在卡片前面（真叶子就是飘在眼前）。
   两道保险：`pointer-events: none`（绝不挡点击）+ z-index 低于 `.tabbar`(6)/`.layer`(20)
   （答题浮层和导航栏上**不会有叶子**）。 */
body.skin-autumn::before,
body.skin-autumn::after,
html:has(body.skin-autumn)::before,
html:has(body.skin-autumn)::after {
  content: '';
  position: fixed;
  z-index: 0;
  pointer-events: none;
  background: var(--maple-b);
  -webkit-mask-image: var(--maple-标准);
  mask-image: var(--maple-标准);
  -webkit-mask-repeat: repeat;
  mask-repeat: repeat;
}

/* 叶场 A：**两种形状两层叠**（标准 400px + 侧翻 600px）。
   ☠️ 为什么一层里要放**两种形状、两种尺寸**：第一版是"一种形状平铺"，
      结果看起来像**墙纸**（等距、同角度、同大小），完全不像落叶。
      两种 tile 尺寸（400 / 600）叠在一起，合成图案的重复距离变成它们的最小公倍数
      **1200px** —— 屏幕上根本看不出重复；再加上形状不同，就散开了。
   ⚠️ 位移量必须取 **1200px（400 和 600 的公倍数）** 才能无缝循环；
      取不动公倍数的话，循环那一刻所有叶子会集体"跳"一下。
   叶子大小 = 0.115 × mask-size → 46px / 69px，都是远景叶该有的大小。 */
body.skin-autumn::before {
  inset: -1200px 0 0 0;         /* 往上多留一个循环位移，飘出顶不露边 */
  opacity: 0.34;
  background: var(--maple-b);
  -webkit-mask-image: var(--maple-标准), var(--maple-侧翻);
  mask-image: var(--maple-标准), var(--maple-侧翻);
  -webkit-mask-size: 400px 400px, 600px 600px;
  mask-size: 400px 400px, 600px 600px;
  -webkit-mask-position: 20px 40px, 260px 310px;
  mask-position: 20px 40px, 260px 310px;
}
/* 叶场 B：另外两种形状（细长 500px + 宽扁 750px），颜色更浅、速度更慢 → 视差。
   ⚠️ 同样：位移量取 **1500px（500 和 750 的公倍数）**。 */
body.skin-autumn::after {
  inset: -1500px 0 0 0;
  opacity: 0.27;
  background: var(--maple-d);
  -webkit-mask-image: var(--maple-细长), var(--maple-宽扁);
  mask-image: var(--maple-细长), var(--maple-宽扁);
  -webkit-mask-size: 500px 500px, 750px 750px;
  mask-size: 500px 500px, 750px 750px;
  -webkit-mask-position: 180px 120px, 430px 520px;
  mask-position: 180px 120px, 430px 520px;
}

/* 两片前景大叶（各自一片，不重复）—— 给层次和"看得清是一片枫叶"的辨识度。
   「no-repeat + 放大 mask-size」的换算：要 62px 的叶子就写 62 ÷ 0.115 ≈ 540px。 */
html:has(body.skin-autumn)::before,
html:has(body.skin-autumn)::after {
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: 540px 540px;
  mask-size: 540px 540px;
  -webkit-mask-position: center;
  mask-position: center;
  opacity: 0.72;
}
html:has(body.skin-autumn)::before {
  left: 12%; top: 24%; width: 62px; height: 62px;
  background: var(--maple-a);
  -webkit-mask-image: var(--maple-标准);
  mask-image: var(--maple-标准);
}
html:has(body.skin-autumn)::after {
  left: 84%; top: 58%; width: 50px; height: 50px;
  background: var(--maple-c);
  -webkit-mask-image: var(--maple-侧翻);
  mask-image: var(--maple-侧翻);
}

/* 系统允许动效时才动。
   ⚠️ 叶场的位移量是 **900px（两个 mask-size 的公倍数）**，所以循环点是**无缝**的；
      前景叶从屏幕上方外面起步（`top: -90px`），免得第一帧"啪"地跳一下。 */
@media (prefers-reduced-motion: no-preference) {
  @keyframes maple-field {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(0, 1200px, 0); }
  }
  /* ⚠️ 两个叶场的位移量**不一样**（1200 / 1500），各自等于自己那两个 mask-size 的公倍数 ——
     所以必须有两个 keyframes，不能共用一个。 */
  @keyframes maple-field-2 {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(0, 1500px, 0); }
  }
  @keyframes maple-a {
    0%   { transform: translate3d(0, 0, 0) rotate(0deg); }
    100% { transform: translate3d(90px, 118vh, 0) rotate(320deg); }
  }
  @keyframes maple-c {
    0%   { transform: translate3d(0, 0, 0) rotate(12deg); }
    100% { transform: translate3d(-100px, 124vh, 0) rotate(-300deg); }
  }
  /* 叶场走 150 / 190 秒一个循环 —— **慢，才像天气**；
     快了会变成"下叶子雨"，那是游戏不是秋天。
     两个叶场用时长的差制造视差（1200px/150s vs 1500px/190s ≈ 8px/s）。 */
  body.skin-autumn::before { animation: maple-field 150s linear infinite; }
  body.skin-autumn::after { animation: maple-field-2 190s linear infinite; }
  html:has(body.skin-autumn)::before { top: -90px; animation: maple-a 26s linear infinite; }
  html:has(body.skin-autumn)::after { top: -90px; animation: maple-c 31s linear infinite; animation-delay: -18s; }
}
/* ===== 注入块: game（本行是锚点，别改；改内容不用动它） ===== */
/* ===== 第 7 套皮肤：像素游戏（`body.skin-game`）（2026-10-05 · PC 版会话） =====
   ------------------------------------------------------------
   用户口径：「**游戏风怎么样**」。

   ⚠️ 为什么是**像素方块（8-bit）**而不是"再加一层霓虹"：
      前 6 套已经把 低饱和沉稳（经典蓝 / 伙伴位）· 青霓虹精密（科技风）·
      深蓝荧光（海洋）· 黑金奢华（典藏金）· 暖浅色纸感（秋日）占满了。
      游戏风如果走"霓虹 + 发光"就**跟科技风撞车** —— 正是 §一百〇三 纠正过我的那类错。
      所以这一套挑的是**现在完全空着**的语汇：**大色块 + 硬边框 + 圆角归零 + 步进式动效**。
      能这样挑的底气：App 本来就有等级徽章 / 经验值 / 掌握度角标（游戏化的），
      像素语汇和它们是**一家人**，不用新造一套东西。

   ⚠️ 不共用 HUD 几何（`skins-extra.js` 里 `共用HUD: false`）：
      共用会把科技风的 `--radius: 10px` 和切角面板一起带过来，**角就不方了**。
      这一套的整个意思就是方块，所以几何必须自己写。

   ⚠️ 怎么做到"少写"：`:root` 是**变量驱动**的
      （`--accent` / `--card` / `--line` / `--green` / `--radius`…），
      `.btn-main` / `.quiz-bar-fill` / `.tab.active` / `.lv-badge` 全都绑在变量上，
      所以**改一轮变量就拿到了大部分效果**，下面那些规则是补"像素"特有的东西
      （硬边框、硬阴影、格子图案、步进动效）。

   ☠️ "在不在" 与 "飘不飘" 分开写（这个坑这个仓库踩过三次，见 §一百〇四 第四节）：
      **图案 / 颜色 / 硬阴影写在闸门外面** —— 开了"减少动态效果"的人照样看到像素格子；
      **只有动画写在 `prefers-reduced-motion: no-preference` 里面**。
      另一半原因更要命：**所有截图脚本都用 `reducedMotion:'reduce'`**，
      塞进闸门里 = 截图上什么都没有，而用户是靠截图判断的。

   @mobile-ok: 第 7 套可选皮肤，和其余几套同级，本来就该手机 PC 都能选。
      ⚠️ 这一行**必须自己写**（不能指望上一节顺延）：判据 7 的规矩是
      "一次声明管一节，到下一个分节横幅为止"，而本块在文件末尾、后面没有横幅。
      第一次加这一块时没写，判据 7 报的是"通过"，但签字用的是**秋日那一节的**
      ——**过了，但通过的理由不是我的**。这种"假通过"比红更难发现。
   ============================================================ */

body.skin-game {
  /* ---------- 配色：深墨蓝 + 明黄 + 正红 + 荧光绿（经典游戏机配色） ---------- */
  --accent: #ffd23f;
  --accent-dark: #c99a00;          /* 按钮"厚度" + 硬阴影色 */
  --accent-light: #2a2410;
  /* ☠️ `--accent-text` 的用途是**"压在 `--accent-light` 上的文字色"**
     （`.subj-tab.active` / `.opt.picked` / `.stage-tab.active` / `.skin-btn.active small` …），
     **不是**"明黄按钮上的深字"。
     ⚠️ 第一版我把它也写成 #ffd23f —— 那是"亮底配深字"的思路串了台：
        亮黄压在深底 `#2a2410` 上虽然清楚，但同一个变量还喂给了别的元素，
        结果答题浮层里那个 span 变成 **rgb(43,34,8) 压在 rgb(30,27,61)** = **1.04:1，等于看不见**。
        是 `_dev-自查-深色皮肤对比度.js` 抓出来的（硬闸 < 2:1）。
     现在：这个变量 = **亮黄**（配 --accent-light 深底），
     而"明黄按钮上的深字"由下面 `.btn-main` 那条**直接写颜色**，不靠这个变量。 */
  --accent-text: #ffd23f;

  --blue: #4ecdc4;
  --blue-light: #12302e;
  --blue-text: #7fe3dc;

  --red: #ff4757;
  --red-light: #33131a;
  --red-text: #ff8a94;

  /* ⚠️ 主色（--green）就是那个明黄 —— `.btn-main` / `.quiz-bar-fill` / `.tab.active`
     全绑在 --accent 和 --green 上，改这一轮变量 = 一次拿到大部分观感。
     ⚠️ 亮黄底**配深字**（#20180a），配白字只有 1.4:1 那种踩过的坑，别再犯 ——
        但注意：那个"深字"由 `.btn-main` 那条**直接写颜色**，**不走** --green-text。

     ☠️ --green-text 是**"压在 --green-light 上的文字色"**，它俩必须**同向**：
        `.opt.correct`（答对后的选项）= `color: var(--green-text)` + `background: var(--green-light)`。
        第一版我把 --green-light 改成深色 #2a2410（当"深色底上的浅色块"用），
        却把 --green-text 留在深字 #2b2208 → **深字压深底 = 1.04:1，答对的知识点名字根本看不见**。
        是 `_dev-自查-深色皮肤对比度.js` 的硬闸（< 2:1）抓出来的，
        而且它是靠"父级路径"才认出来的（只报 `span` 时找不着）—— 那个补丁也是这一轮加的。
     现在：light 是深底、text 是亮字，同向。 */
  --green: #ffd23f;
  --green-dark: #c99a00;
  --green-light: #2a2410;
  --green-text: #ffdf6b;

  --yellow: #ffe66d;
  --gray: #9aa0c0;
  --gray-light: #12102a;           /* 页面底 = 深墨蓝 */
  /* ⚠️ 卡片从 #1b1838 提到 #1e1b3d：第一版卡片和页底明度太近，
     在大片深底（首页 / 学习页）上"分不出哪块是卡片"。 */
  --line: #4a4478;
  --text: #eef0ff;
  --card: #1e1b3d;

  --radius: 0px;                   /* ★ 圆角归零 —— 这一套的骨架就是方块 */
  background: #12102a;
}

/* ---------- 像素格子底（点阵 + 星点）----------
   ⚠️ 全是 CSS 渐变画的，**没有新素材**（不用进 git、不会 404、不占缓存）。
   ⚠️ 11 层星点 + 2 层格子 = **13 层**。这么写是为了不引入任何图片文件；
      代价是下面的动效必须**整体平移**，不能去动 background-position
      （13 个值要一个个写全，漏一个就整条动画失效 —— 第一版就是这么写的，已改掉）。
   星点用 background-repeat: repeat + 512×512，位置写绝对 px（不用百分比）→ 和格子对齐。 */
body.skin-game {
  /* 格子原点（动效就是改这两个数；默认变量让静态时也能编译） */
  --格子x: 0px;
  --格子y: 0px;
}
body.skin-game::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    /* 星点（三种大小、三种颜色，512 的 tile 里 11 颗） */
    radial-gradient(2px 2px at 24px 36px,  rgba(255, 255, 255, 0.55), transparent 100%),
    radial-gradient(2px 2px at 148px 92px, rgba(255, 210, 63, 0.50),  transparent 100%),
    radial-gradient(3px 3px at 312px 44px, rgba(255, 255, 255, 0.42), transparent 100%),
    radial-gradient(2px 2px at 420px 164px, rgba(78, 205, 196, 0.45), transparent 100%),
    radial-gradient(2px 2px at 72px 236px,  rgba(255, 255, 255, 0.38), transparent 100%),
    radial-gradient(2px 2px at 248px 300px, rgba(255, 210, 63, 0.36),  transparent 100%),
    radial-gradient(3px 3px at 468px 396px, rgba(255, 255, 255, 0.32), transparent 100%),
    radial-gradient(2px 2px at 108px 436px, rgba(78, 205, 196, 0.34),  transparent 100%),
    radial-gradient(2px 2px at 392px 300px, rgba(255, 255, 255, 0.40), transparent 100%),
    radial-gradient(2px 2px at 196px 484px, rgba(255, 71, 87, 0.30),   transparent 100%),
    radial-gradient(2px 2px at 344px 224px, rgba(255, 255, 255, 0.30), transparent 100%),
    /* 像素格子（8px 一格，每格左上角一个 2px 亮点 → 硬边格子）
       ⚠️ 第一版 0.05 太淡，在**大片深底**（首页 / 学习页）上几乎看不见 ——
          截图里那片空区域就是一块纯色。提到 0.075 才看得出"这是一张像素底"。 */
    linear-gradient(rgba(255, 255, 255, 0.075) 2px, transparent 2px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.075) 2px, transparent 2px),
    /* 更淡的一层 32px 大方格：给"大片空区域"一点尺度感，
       不然只有 8px 小格子时，远看仍是一片纯色。 */
    linear-gradient(rgba(255, 255, 255, 0.022) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.022) 1px, transparent 1px);
  background-size: 512px 512px, 512px 512px, 512px 512px, 512px 512px, 512px 512px,
                   512px 512px, 512px 512px, 512px 512px, 512px 512px, 512px 512px,
                   512px 512px, 8px 8px, 8px 8px, 32px 32px, 32px 32px;
  background-position: var(--格子x) var(--格子y);
}

body.skin-game .app {
  position: relative;
  z-index: 1;
  background: transparent;         /* 让 ::before 的格子透出来 */
}
body.skin-game .topbar { background: transparent; }

/* ---------- 面板 / 卡片：厚描边 + 硬阴影（没有模糊 = 像素感）---------- */
body.skin-game .subject-card,
body.skin-game .card,
body.skin-game .pill,
body.skin-game .lv-badge,
body.skin-game .quiz-bar,
body.skin-game .exam-bar,
body.skin-game .opt,
body.skin-game .key,
body.skin-game .mini-btn,
body.skin-game .icon-btn {
  border-radius: 0;
  border: 3px solid var(--line);
  /* ⚠️ 那个 `inset 0 1px 0 rgba(255,255,255,.07)` 是**像素面板的顶面高光** ——
     游戏 UI 的面板几乎都有这一条，卡片这才"浮"起来。
     ⚠️ 卡片类那几个另外要 4px 硬阴影；`.pill` / `.lv-badge` / `.quiz-bar` 这类小控件
        用 3px 就够（用 4px 会显得头重）。 */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07), 3px 3px 0 rgba(0, 0, 0, 0.45);
}
body.skin-game .subject-card,
body.skin-game .card,
body.skin-game .opt,
body.skin-game .key {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07), 4px 4px 0 rgba(0, 0, 0, 0.45);
}

/* ---------- 主按钮：明黄底 + 黑描边 + 硬阴影，按下去像"陷进去一格" ---------- */
body.skin-game .btn-main,
body.skin-game .multi-confirm,
body.skin-game .foot-btn.primary,
body.skin-game .result-filter .mini-btn.active,
body.skin-game .cfg-opts .mini-btn.active,
body.skin-game .key.ok,
body.skin-game .rc-go,
body.skin-game .uc-tab.active,
body.skin-game .icon-btn.exam-submit {
  background: var(--accent);
  border: 3px solid #20180a;       /* 黑描边 —— 像素游戏的按钮都是"贴纸" */
  border-radius: 0;
  color: #20180a;                  /* ⚠️ 亮黄底必须配深字 */
  box-shadow: 4px 4px 0 #120d02;
  font-weight: 800;
  letter-spacing: 0.3px;
}
body.skin-game .btn-main:active,
body.skin-game .opt:active,
body.skin-game .key:active {
  transform: translate(3px, 3px);
  box-shadow: 1px 1px 0 #120d02;
}

/* ---------- 进度条：格子化的段，而不是光滑的条 ---------- */
body.skin-game .quiz-bar,
body.skin-game .exam-bar {
  height: 16px;
  background: #0c0a1c;
  border-color: #20180a;
  overflow: hidden;
}
body.skin-game .quiz-bar-fill {
  background: var(--accent) repeating-linear-gradient(
    90deg,
    rgba(0, 0, 0, 0.30) 0 2px,
    transparent 2px 10px
  );
  border-radius: 0;
}
body.skin-game .exam-bar i {
  background: var(--accent) repeating-linear-gradient(
    90deg,
    rgba(0, 0, 0, 0.30) 0 2px,
    transparent 2px 10px
  );
}

/* ---------- 顶部徽章：像素"药丸" → 方块 ---------- */
body.skin-game .pill {
  border-radius: 0;
  background: var(--card);
  padding: 4px 10px;
}
body.skin-game .lv-badge {
  border-radius: 0;
  border: 3px solid #20180a;
  background: var(--accent);
  color: #20180a;
  text-shadow: none;
  letter-spacing: 0.5px;
}
/* ⚠️ `.lv-big`（「我的」页那个大奖章）原生是 **写死的 `color:#fff` + `var(--accent)` 底**，
   两处撞在一起：明黄底压白字 = **1.44:1**。科技风靠 `body.skin-tech .lv-big`
   那条治过同一个病（它那边 --accent 是亮青，白字同样不行）。
   这里照同一条路子，把字色换成深字 —— **不改 app.js**（那是别人的段落）。 */
body.skin-game .lv-big { color: #20180a; }

/* ⚠️ `.timer`（计算训练的计时器）是 `.timer` 自己的 `#ff9600` 字 + `#fff4e5` 米色底，
   两个都是**写死的** → 任何深色皮肤下它都还是"一颗米色药丸"（实测 2.01:1，和经典蓝一样差）。
   科技风 / 海洋 / 典藏金在文件另一处一起治过（`body.skin-tech .timer, body.skin-ocean .timer,
   body.skin-gold .timer`）—— **第 7 套加进来时别忘了也把 game 报进去**，
   不然它就跟经典蓝一样停在 2.01:1。这是"加皮肤要顺手做的事"清单里的一项。 */
body.skin-game .timer {
  color: var(--accent-text);
  background: var(--accent-light);
}

/* ---------- 底部导航：选中的那一格整块点亮 ---------- */
body.skin-game .tabbar {
  background: #0c0a1c;
  border-top: 3px solid #20180a;
}
body.skin-game .tab.active {
  background: var(--accent-light);
  box-shadow: inset 0 -4px 0 var(--accent);
}

/* ---------- 选项 / 数字键盘：硬边框，选中态是"亮块" ---------- */
body.skin-game .opt {
  background: var(--card);
  border-color: var(--line);
}
body.skin-game .opt.picked {
  border-color: var(--accent);
  background: var(--accent-light);
  color: var(--accent-text);
}
body.skin-game .key {
  background: var(--card);
  border-bottom-width: 3px;
}

/* ---------- 像素小人：Q 版形象本来就是低分辨率，`pixelated` 正好 ----------
   ⚠️ 只加渲染方式，**不改尺寸** —— 尺寸一变会动到版面（`.s-chibi` 是别人的段落）。 */
body.skin-game .s-chibi img,
body.skin-game .subj-art img,
body.skin-game .avatar img {
  image-rendering: pixelated;
}

/* ---------- 动效层（★ 全部关在闸门里 —— 见文件头那段）----------
   ⚠️ 用 `steps()` 而不是 `ease`：像素动画就是**一格一格跳**的，
      连续插值反而没有像素味。这是这一套用 steps 的唯一原因。 */
@media (prefers-reduced-motion: no-preference) {
  /* 光标闪烁（像游戏里的文字输入框） */
  @keyframes 像素闪 {
    0%, 49%   { opacity: 1; }
    50%, 100% { opacity: 0.2; }
  }
  body.skin-game .tab.active .tab-ico {
    animation: 像素闪 1.1s steps(1, end) infinite;
  }

  /* 底图一格格地走（改 CSS 变量 → ::before 上合成 transform，**不重绘全屏**）
     8px 走 8 步、每步 0.24s = 1.92s，正好一个格子；走完变量归零无缝循环。
     ⚠️ 第一版去动 `background-position`（13 层要写 13 个值），
        既容易漏到整条动画失效，又是**全屏重绘** —— 低端安卓会卡。已改掉。 */
  @keyframes 格子走 {
    from { --格子x: 0px;    --格子y: 0px; }
    to   { --格子x: 8px;    --格子y: -8px; }
  }
  body.skin-game::before {
    animation: 格子走 1.92s steps(8, end) infinite;
  }

  /* 卡片 hover：只碰 transform + box-shadow，不触发重排 */
  body.skin-game .subject-card,
  body.skin-game .card {
    transition: transform 0.12s steps(2, end), box-shadow 0.12s steps(2, end);
  }
  body.skin-game .subject-card:hover,
  body.skin-game .card:hover {
    transform: translate(-2px, -2px);
    box-shadow: 6px 6px 0 rgba(0, 0, 0, 0.5);
  }
}

/* ===== 像素游戏 结束 ===== */

/* ============================================================
   皮肤「朱批」（`body.skin-cinnabar`）（2026-10-05 · PC 版会话）
   ------------------------------------------------------------
   用户从三个候选里点了「**朱批（深色漆红）**」。

   **为什么是这个钩子**：这个 App 里有 **17 位老师角色**。
   「朱批」= 老师红笔批改 + 朱砂印 + 红榜题名 ——
   对**职教高考**的学生，"朱批"就是他们每天面对的东西。
   比"随便来个红色"有意义得多。

   ☠️☠️ 这一套有一条**别的皮肤没有的硬约束**，做之前必须先读懂：
        `--red`（答错色）在这个 App 里**已经被占用**，而"**红 = 错**"
        和"绿 = 对"是同一条硬习惯。style.css 第 962 行那条注释写得很清楚：
          「绿色特意保留给"答对了"用 —— 因为绿色 = 对，是大家的习惯，
            如果把答对也改成蓝色，反而会让人看不懂。」
        红同理。所以**红色皮肤不能只是把主题色换成红**，否则学生在红色界面上
        答错时会分不清"这是按钮还是我错了"。

   两条铁律（这是这套皮肤能不能用的关键）：

     ① **主行动按钮不用红，用米金。**
        红只出现在**批注、印、选中态、进度**上 —— 是氛围，不是"到处是警告"。

     ② **主题红和答错红靠「明度」拉开，不靠色相。**
        · 朱砂 `#a8322a`  明度 **30**（暗、沉、像印泥）
        · 答错 `#ff6b6b`  明度 **71**（亮、跳、像警告）
        → 亮度差 **41**。色盲的人也分得开。
        （对照：秋日枫叶的枫红与答错红只差 **12** —— 那是我上一轮做出来的隐患，
          已在同一轮里修掉。量法见 `_dev-查-红撞红.js`。）

   ⚠️ 不共用 HUD 几何（漆器 / 印章配霓虹切角是两种气质硬拼），
      所以只挂 `skin-cinnabar` → 走 App 原来的圆角几何，
      这一节**不用重写任何组件样式**，只换颜色 + 加三处"朱批"记号。
   ============================================================ */

/* ---------- ① 漆器配色 ---------- */
body.skin-cinnabar {
  --accent: #a8322a;          /* 朱砂 / 印泥：暗、沉。**明度 30**，和答错红差 41 */
  --accent-dark: #7a211b;
  --accent-light: #2c1210;    /* 深枣红底：选中态、浅底 */
  --accent-text: #ff8a72;     /* 压在深底上的**亮朱砂**：深色皮肤里 accent 当不了字色（见 ⑦） */
  --blue: #6f86a8;            /* 次色：青灰（别用艳蓝，会跳出漆器气质） */
  --blue-light: #16202c;
  --blue-text: #a9c2e0;
  --gray-light: #0f0908;      /* 页面底：暖黑（不是纯黑，纯黑配朱砂会发死） */
  --card: #1a100e;            /* 卡片：深漆褐 */
  --line: #3a211c;
  --text: #f6e8dc;            /* 正文：暖白（冷白配朱砂显脏） */
  --gray: #a89287;
  --green: #5fbf82;           /* 对错色必须保持可辨：绿留给"答对"，别染成朱砂 */
  --green-light: #12261a;
  --green-text: #9affc0;
  --red: #ff6b6b;             /* 答错：**明度 71**，比朱砂亮得多 —— 见文件头铁律② */
  --red-light: #2e1113;
  --red-text: #ffb3b3;
  --ink-gold: #e3cf9a;        /* 米金：主行动按钮的底色（铁律①） */
  --ink-gold-dark: #b09b62;
  --ink-deep: #241a12;        /* 压在米金上的深墨字 */
  /* 漆器底：顶上一点暖光（像灯打在漆面上），往下压到近黑 */
  background:
    radial-gradient(58% 30% at 50% -4%, rgba(168, 50, 42, 0.30) 0%, transparent 70%),
    linear-gradient(180deg, #1a0f0d 0%, #120a09 42%, #0b0605 100%);
  background-attachment: fixed;
}
html:has(body.skin-cinnabar) { background: #0b0605; }

/* ---------- ② 漆面反光：一道很柔的斜向高光 ----------
   漆器的质感来源是"抛光面把光反出来"，不是纹理。
   所以这里**不做细纹**（细纹会变噪点），只给一道宽的柔光。 */
body.skin-cinnabar::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(115deg,
    transparent 0%, rgba(227, 207, 154, 0.045) 28%,
    rgba(227, 207, 154, 0.075) 42%, transparent 62%);
}

/* ---------- ③ 朱批记号 1：**所有"主行动"按钮都换成米金** ----------
   ☠️ 铁律①。而且**必须同时改字色和底色**：
      不共用 HUD 就没有科技风那段"亮底 → 深字"的覆盖
      （`body.skin-tech .key.ok, .btn-main, .multi-confirm, .foot-btn.primary …{ color: #04141a }`），
      而那几个类**自己的底色就是 `--accent` / `--blue`**：
        · 只改字色 → 深字压朱砂，实测 **2.56:1**（看不见）
        · 只改底色 → 白字压米金（也看不见）
      **两个一起改**才对 —— 这就是科技风那份名单存在的原因，照它抄一遍。
      名单里那几个 `active` / `primary` 是历史补漏（见上面科技风那段注释：
      "新加的'亮底按钮'必须自己加进这个名单，而且要拿有数据的存档量一遍"）。 */
body.skin-cinnabar .btn-main,
body.skin-cinnabar .key.ok,
body.skin-cinnabar .multi-confirm,
body.skin-cinnabar .foot-btn.primary,
body.skin-cinnabar .rc-go,
body.skin-cinnabar .icon-btn.exam-submit,
body.skin-cinnabar .cfg-opts .mini-btn.active,
body.skin-cinnabar .result-filter .mini-btn.active,
body.skin-cinnabar .uc-tab.active {
  background: var(--ink-gold);
  border-color: var(--ink-gold);
  border-bottom-color: var(--ink-gold-dark);
  color: var(--ink-deep);
}

/* ---------- ④ 朱批记号 2：小节标题前一条**朱砂竖杠** ----------
   这是整套皮肤里最"朱批"的一笔 —— 老师批改作业就是先在旁边画一道红杠。
   纯装饰：`position: absolute` 不占流，**不影响任何布局**（量版面自查读到的矩形不变）。 */
body.skin-cinnabar .sec-title {
  position: relative;
  padding-left: 12px;
}
body.skin-cinnabar .sec-title::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 4px;
  height: 1.05em;
  margin-top: -0.525em;
  border-radius: 2px;
  background: var(--accent);
}

/* ---------- ⑤ 朱批记号 3：等级徽章变成一颗**朱印** ----------
   等级 = 一颗印（"Lv.7" 像盖上去的），圆角收方、加一圈印泥边。 */
body.skin-cinnabar .lv-badge,
body.skin-cinnabar .lv-big {
  border-radius: 5px;
  background: var(--accent);
  color: #fdf3e6;
  box-shadow: inset 0 0 0 2px rgba(253, 243, 230, 0.30);
}

/* ---------- ⑥ 计时器：深色皮肤那一批一起治（见上面那段注释） ---------- */
body.skin-cinnabar .timer {
  color: var(--accent-text);
  background: var(--accent-light);
}

/* ---------- ⑦ ☠️ **把"拿 accent 当字色"的那一批统一亮一档** ----------
   这是朱批这套皮肤**最容易漏、也最致命**的一处。实测：
   `--accent`（朱砂 `#a8322a`，明度 41）当**底色**完全没问题，
   但当**字色**压在深卡片（`--card #1a100e`）上只有 **2.81:1** ——
   首页的品牌名、目标环数字、任务卡的「去看看」、考试的计时器……**一片看不清**。

   为什么科技风 / 海洋风 / 典藏金没有这个问题：
   它们的 `--accent` **本身够亮**（青 l50 / 荧光青绿 l52 / 鎏金 l60），
   拿来做字色天然够对比。**朱批的 accent 必须是暗的**（那是铁律②：靠明度躲开答错红），
   所以它躲不开这一条 —— 暗色 accent 的代价就是"当字色要另配一个亮色"。

   下面这份名单是**从 style.css 里 `grep 'color: var(--accent)'` 抄出来的**，
   不是我凭印象列的；漏一个就有一处看不清（改完必须跑对比度自查复验）。 */
body.skin-cinnabar .brand,
body.skin-cinnabar .ring-center b,
body.skin-cinnabar .goal-line b,
body.skin-cinnabar .task-go,
body.skin-cinnabar .stat b,
body.skin-cinnabar .finish-xp,
body.skin-cinnabar .tab.active,
body.skin-cinnabar .league-info b,
body.skin-cinnabar .ladder-row.me .lr-rank,
body.skin-cinnabar .lr-xp,
body.skin-cinnabar .backup-line b,
body.skin-cinnabar .result-score,
body.skin-cinnabar .his-row b,
body.skin-cinnabar .cd-days,
body.skin-cinnabar .task-ico,
body.skin-cinnabar .exam-timer {
  color: var(--accent-text);
}

/* ⚠️ `#notice-toggle`（首页公告卡的「展开 ▾」）是个例外：
   它的颜色是 `notice.js` **用内联样式**写上去的（`C.主 = 'var(--accent)'`），
   内联样式**压过任何选择器**（除非 `!important`）。
   全站只有这一处是"JS 内联拿 accent 当字色"（`grep var(--accent) *.js` 只有它），
   所以这里单独放一个 `!important` —— 不是偷懒，是**唯一能覆盖内联的办法**。
   要根治得让 notice.js 把 `主` 换成 `浅字`，但那要改别人的文件，留给以后。 */
body.skin-cinnabar #notice-toggle {
  color: var(--accent-text) !important;
}

/* ============================================================
   皮肤「青绿山水」（body.skin-shanshui）（2026-10-05 · PC 版会话）
   ------------------------------------------------------------
   用户口径：「**古风的怎么样**」。

   ⚠️☠️ **先说一个必须点出来的问题**：上一轮的「**朱批**」**已经吃掉古风的一半**了 ——
      漆器黑 + 朱砂 + 米金 + 朱印 + 朱砂竖杠，那套本身就是古风的一支
      （**文书 / 批牍**那一脉）。所以这一套**不能**再做"宣纸 + 朱砂 + 印章"，
      否则两套摆在一起会像同一套的深浅版。

   → 换**另一支**：**青绿山水**。出处是王希孟《千里江山图》那一脉，
      配色是**矿物色**：石青（azurite）+ 石绿（malachite）+ 赭石（ochre）+ 泥金。
      几个好处：
        · **浅色**（绢本 / 宣纸底）—— 原来 8 套里只有 3 套浅色
        · **石青石绿这个色谱一套都没占**（经典蓝是亮蓝、海洋风是深青、秋日枫叶是暖橙）
        · 气质和朱批**完全不同**：朱批是"暗、重、官方"，山水是"亮、清、旷"

   ⚠️ 不共用 HUD 几何（矿物色的绢本配霓虹切角是两种文明硬拼）→ 走 App 原来的圆角几何。

   三件事做出"山水"：
     ① **宣纸底**：米白 + 极淡的双向纤维纹（不是纯色平底）
     ② **远山三重**：三层山影，越远越淡、越近越矮 —— **这是整套皮肤的"脸"**
     ③ **石青主色 + 石绿次色 + 赭石/泥金点缀**，全部矿物色、一律压灰（不艳）
   ============================================================ */

/* ---------- ① 绢本 / 宣纸配色（矿物色，一律压灰不艳） ---------- */
body.skin-shanshui {
  --accent: #2e5c86;          /* 石青（azurite）：矿物蓝，压过灰 */
  --accent-dark: #1f4463;
  --accent-light: #e3ebf1;    /* 淡石青洗过的底 */
  --accent-text: #1f4463;
  --blue: #3f7a63;            /* 次色：石绿（malachite） */
  --blue-light: #e4efe8;
  --blue-text: #2c5a48;
  --gray-light: #f3efe3;      /* 页面底：宣纸米白（偏暖一点点，不是纯白） */
  --card: #fbf9f2;            /* 卡片：比纸再亮一档 */
  --line: #ddd5c4;            /* 描边：淡赭（矿物画的"界线"都是赭） */
  --text: #2a2723;            /* 正文：**墨**（不是纯黑，纯黑压在宣纸上发硬） */
  --gray: #7d7466;
  --green: #3f7a52;           /* 对错色保持可辨：绿留给"答对" */
  --green-light: #e2efe3;
  --green-text: #2b5a3a;
  --red: #b5443a;             /* 答错：赭红（压在浅底上够深，看得清） */
  --red-light: #f6e3df;
  --red-text: #8f2f27;
  /* 赭石 / 泥金：留给"点睛"，不进主题色 */
  --zhe: #a9603a;
  --ni: #c9a227;
  /* 宣纸底 = 米白 + **双向极淡纤维纹**（两个角度的细线）。
     纯色平底会让"纸"变成"塑料"；纹理要压到几乎看不见，只留颗粒感。 */
  background-color: #f3efe3;
  background-image:
    repeating-linear-gradient(8deg, rgba(120, 104, 78, 0.035) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(98deg, rgba(120, 104, 78, 0.028) 0 1px, transparent 1px 6px);
  background-attachment: fixed;
}
html:has(body.skin-shanshui) { background: #f3efe3; }

/* ---------- ② 远山三重 ----------
   ☠️ 三层用**四个伪元素里的三个**，而且**顺序是被渲染顺序决定的**，别乱配：
      实际绘制顺序是 html::before → body 背景 → body::before → body::after → html::after。
      所以：body::before 最远 → body::after 中间 → **html::after 最近**（它画得最晚）。
      配反了的话最近的山会被最远的盖住，看起来就是"前山挡住了后山"。

   ⚠️ 山影画在 .app **之下**（靠下面 ③ 那条 z-index:1），
      于是山只在**卡片之间的空隙、页面留白、版心两侧**露出来 ——
      这正是"山水在远处"的感觉，而不是"山糊在内容上"。
      高度取 34vh / 26vh / 19vh：**越近越矮**（近山在画面下缘，被裁掉更多）。
      颜色全部走主题变量，皮肤换色时山也跟着换。 */
body.skin-shanshui::before,
body.skin-shanshui::after,
html:has(body.skin-shanshui)::after {
  content: '';
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 0;
  pointer-events: none;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-position: bottom center;
  mask-position: bottom center;
}
/* 最远：最高、最淡 —— "远山如黛" */
body.skin-shanshui::before {
  height: 34vh;
  opacity: 0.16;
  background: var(--accent);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%201280%20300%27%20preserveAspectRatio%3D%27none%27%3E%3Cpath%20fill%3D%27%23000%27%20d%3D%27M0,200 L160,110 L300,165 L470,80 L640,170 L800,100 L980,175 L1140,120 L1280,190 L1280,300 L0,300 Z%27%2F%3E%3C%2Fsvg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%201280%20300%27%20preserveAspectRatio%3D%27none%27%3E%3Cpath%20fill%3D%27%23000%27%20d%3D%27M0,200 L160,110 L300,165 L470,80 L640,170 L800,100 L980,175 L1140,120 L1280,190 L1280,300 L0,300 Z%27%2F%3E%3C%2Fsvg%3E");
}
/* 中间：石绿 */
body.skin-shanshui::after {
  height: 26vh;
  opacity: 0.2;
  background: var(--blue);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%201280%20300%27%20preserveAspectRatio%3D%27none%27%3E%3Cpath%20fill%3D%27%23000%27%20d%3D%27M0,300 L0,230 L140,150 L280,215 L430,130 L580,205 L740,140 L900,220 L1060,155 L1200,225 L1280,190 L1280,300 Z%27%2F%3E%3C%2Fsvg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%201280%20300%27%20preserveAspectRatio%3D%27none%27%3E%3Cpath%20fill%3D%27%23000%27%20d%3D%27M0,300 L0,230 L140,150 L280,215 L430,130 L580,205 L740,140 L900,220 L1060,155 L1200,225 L1280,190 L1280,300 Z%27%2F%3E%3C%2Fsvg%3E");
}
/* 最近：最矮最实（画得最晚 = 压在最上面） */
html:has(body.skin-shanshui)::after {
  height: 19vh;
  opacity: 0.22;
  background: var(--zhe);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%201280%20300%27%20preserveAspectRatio%3D%27none%27%3E%3Cpath%20fill%3D%27%23000%27%20d%3D%27M0,300 L0,255 L120,200 L260,250 L400,190 L560,245 L700,205 L860,255 L1000,210 L1160,258 L1280,225 L1280,300 Z%27%2F%3E%3C%2Fsvg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%201280%20300%27%20preserveAspectRatio%3D%27none%27%3E%3Cpath%20fill%3D%27%23000%27%20d%3D%27M0,300 L0,255 L120,200 L260,250 L400,190 L560,245 L700,205 L860,255 L1000,210 L1160,258 L1280,225 L1280,300 Z%27%2F%3E%3C%2Fsvg%3E");
}

/* ---------- ③ 让内容压在山水之上 ----------
   ☠️ 不加这一段，山会画在**卡片和文字上面**（z-index:0 的定位元素高于非定位内容）。
      加了之后：.app 成为 z-index:1 的定位元素，整棵内容树都在山之上；
      而 .app 的底色**置透明**，纸纹和山才能从卡片缝隙、页面留白里透出来
      （和科技风那边 .app background: transparent 是同一招）。 */
body.skin-shanshui .app {
  position: relative;
  z-index: 1;
  background: transparent;
}

/* ---------- ④ 点睛：等级徽章用**泥金** ----------
   矿物画最后一道工序就是"点金"，只点最要紧的地方。 */
body.skin-shanshui .lv-badge,
body.skin-shanshui .lv-big {
  background: var(--ni);
  color: #3a2f10;
  box-shadow: inset 0 0 0 2px rgba(58, 47, 16, 0.18);
}
/* 小节标题前一条**石青细杠** —— 和朱批那条朱砂竖杠是**同一个位置、不同矿物色**：
   这是全站统一的"批注记号"位，两套皮肤各用各的矿物色，位置一致。 */
body.skin-shanshui .sec-title {
  position: relative;
  padding-left: 12px;
}
body.skin-shanshui .sec-title::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 3px;
  height: 1.05em;
  margin-top: -0.525em;
  border-radius: 2px;
  background: var(--accent);
}

/* ===== 注入块: game-splash（锚点，别改；改内容不用动它） ===== */
/* ===== PC 开屏：科技开启（≥900px 才有）（2026-10-06 · PC 版会话） =====
   ------------------------------------------------------------
   用户口径（按时间序）：
     「PC 的开展（开屏）动画也搞一下，不能是手机的」→「我想要个纳米感」
     →「算了科技吧」→「科技流动」→「**没有那种科技开启**」

   ☠️ 最后一句是关键的自我修正：我前一版做的是**"会动的壁纸"**
      （网格在流、光带在扫，但 logo 一直是"已经在那儿"的静态图片 + 三行字）。
      而"科技**开启**"是一段**启动序列**，不是一张动态背景：
        ① 暗场起（logo 不可见）
        ② 一道光扫过 logo、logo 随之亮起来
        ③ HUD 角标从四角画出来，围住 logo
        ④ 底部一条刻度进度条走满
        ⑤ 状态字 + 闪烁块，像仪器输出
      → 这一版按这个顺序重排；网格/扫描线退成**底噪**，不再是主角。

   ---- 载体：**全部用 index.html 里已有的元素**，不新增 DOM ----
     `#splash::before`      扫光（横带）
     `#splash::after`       底噪网格（52px 向上流）
     `.sp-glow`             整屏细扫描线（借用，覆盖掉它原本的光晕）
     `.sp-mark img`         logo：切角框 + 青辉 + 一道扫光
     `.sp-rip` / `.sp-rip2` **HUD 两个角**（它们本来就是 8px 的小方块，
                             正好当角标；基础 alpha 动画被这里整体接管）
     `.sp-flow`             底部刻度进度条（它的 `i` 还留着基础那道光带，没动）
     `.sp-title` / `.sp-sub` 标题 / 状态字

   ⚠️ 纯 CSS，`app.js` / `index.html` 一个字节没动；
      手机不受影响（整块在 `@media (min-width:900px)` 内）。
   ☠️ 时间预算按**真实 1650ms** 排（`startSplash()` 到点 `remove()`）：
      logo 扫光 0.30~0.98s → 角标 0.62~1.06s → 进度条 0.30~1.25s →
      状态字 0.70~1.00s → 1.25s 之后全部静止，留约 400ms 看成品。

   ☠️☠️ 两条这一轮用血换来的规矩（别再犯）：
     ① **特异性**：基础规则里凡带 `.playing` 的（如 `#splash.playing .sp-glow` 是 (1,2,1)），
        我光写 `#splash .sp-glow` (1,1,1) **永远输** —— 改多少参数都"没反应"。
        所以下面凡是覆盖 `.playing` 下的动画，**一律带上 `.playing`**。
     ② **两份 display 必须成对改**：logo 有 `.sp-img-light` / `.sp-img-tech` 两张，
        基础靠皮肤二选一。只藏科技版而不打开浅色版 → **两张同时被藏、logo 根本不渲染**
        （实测 boundingBox 为 null）。基础注释里写着"这个坑 v41 踩过一次"，我又踩了一次。
   ============================================================ */

@media (min-width: 900px) and (prefers-reduced-motion: no-preference) {

  /* ---------- ① 整屏 + 暗场 ---------- */
  #splash {
    max-width: none;
    background-color: #03060b;
    /* 中心一团青光：给"启动中的反应堆"一个视觉重心 */
    background-image: radial-gradient(ellipse 70% 55% at 50% 46%,
      rgba(34, 211, 238, 0.12), rgba(3, 6, 11, 0) 72%);
  }
  /* ⚠️ 成对改：打开浅色版、藏掉科技版（见文件头 ②） */
  #splash .sp-img-light { display: block !important; }
  #splash .sp-img-tech { display: none !important; }

  /* ---------- ② 扫光：一道横带自上而下扫过（启动的第一下）---------- */
  #splash::before {
    content: '';
    position: absolute;
    left: -10%; right: -10%;
    top: 0;
    height: 26vh;
    z-index: 3;                       /* 压在 logo 之上：光要"扫过去" */
    pointer-events: none;
    transform: translateY(-30vh);
    background: linear-gradient(180deg,
      transparent 0%,
      rgba(34, 211, 238, 0.06) 40%,
      rgba(150, 245, 255, 0.26) 50%,
      rgba(34, 211, 238, 0.06) 60%,
      transparent 100%);
    animation: 扫光 0.68s cubic-bezier(.32, .72, .38, 1) 0.30s 1 both;
  }
  @keyframes 扫光 {
    from { transform: translateY(-30vh); }
    to   { transform: translateY(115vh); }
  }

  /* ---------- ③ 底噪：52px 网格向上流（退成背景，不再是主角）---------- */
  #splash::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-image:
      linear-gradient(rgba(34, 211, 238, 0.085) 1px, transparent 1px),
      linear-gradient(90deg, rgba(34, 211, 238, 0.085) 1px, transparent 1px);
    background-size: 52px 52px, 52px 52px;
    animation: 网格上流 8s linear infinite;
  }
  @keyframes 网格上流 { to { background-position: 0 -520px, 0 -520px; } }

  /* ---------- ④ 整屏细扫描线（借 `.sp-glow`，覆盖掉它原本的光晕）----------
     ☠️ 选择器**必须带 `.playing`** —— 基础规则 `#splash.playing .sp-glow` 是 (1,2,1)，
        不带就永远被它压住（见文件头 ①）。 */
  #splash .sp-glow {
    position: absolute;
    inset: 0;
    width: auto; height: auto;
    margin: 0;
    border-radius: 0;
    filter: none;
    opacity: 1;
    background: repeating-linear-gradient(180deg,
      rgba(34, 211, 238, 0.035) 0 1px,
      transparent 1px 4px);
  }
  #splash.playing .sp-glow { animation: 扫描线下移 3.2s linear infinite; }
  @keyframes 扫描线下移 { to { background-position: 0 64px; } }

  /* ---------- ⑤ HUD 两个角：从 8px 小方块"画"成 46px 的角标 ----------
     ⚠️ 它们基础是 `#splash.playing .sp-rip { animation: sp-rip … }`（扩散波纹），
        这里**整体接管**（同选择器、写在后面）——不是"补一条 animation-delay"。 */
  #splash .sp-rip {
    position: absolute;
    border: 0;                        /* 丢掉基础的整圈边框，改成两条边 */
    border-radius: 0;
    opacity: 0;
  }
  /* 左上角：上 + 左 两条边 */
  #splash .sp-rip {
    left: -22px; top: -22px;
    border-left: 2px solid rgba(34, 211, 238, 0.85);
    border-top: 2px solid rgba(34, 211, 238, 0.85);
  }
  /* 右下角：下 + 右 两条边。
     ☠️ 这里**不要写 `border-left: 0; border-top: 0`** —— 那两句会覆盖掉上面
        `border: 0` 里的"零值"设定，实测把整个元素的边框算成了 `0/0`
        （`borderRight/Width` 也跟着塌成 0），于是右下角**完全看不见**。
        下面直接写全两条需要的边，不写"清零"的那两条。 */
  #splash .sp-rip2 {
    left: auto; top: auto;
    right: -22px; bottom: -22px;
    border-right: 2px solid rgba(34, 211, 238, 0.85);
    border-bottom: 2px solid rgba(34, 211, 238, 0.85);
  }
  #splash.playing .sp-rip  { animation: 角标画入 0.44s cubic-bezier(.2, .8, .3, 1) 0.62s both; }
  #splash.playing .sp-rip2 { animation: 角标画入 0.44s cubic-bezier(.2, .8, .3, 1) 0.72s both; }
  @keyframes 角标画入 {
    from { width: 8px;  height: 8px;  opacity: 0; }
    to   { width: 46px; height: 46px; opacity: 1; }
  }

  /* ---------- ⑥ 启动进度条：挂在**图标正下方**（`.sp-mark` 内）----------
     ☠️☠️ 这一条查了很久，根因值得单独记：
       我原本想把它做成"屏底进度条"，用了 `position: fixed` + `left/right` 拉伸，
       结果**怎么都不生效**。真因不是特异性、不是 flex、不是 `inset` 简写（这三个我都排掉了），
       而是 —— **`#splash` 自己带 `transform` 动画**（退出用的 `sp-out` 里有 `scale`），
       **带 transform 的元素会成为 `position:fixed` 后代的包含块**。
       所以那个 `fixed` 不是"相对视口"，而是"相对 `#splash` 自己"，
       `bottom` 自然算到离屏底 521px 的地方（三套写法实测都是 ~520~543px）。
       → 换成 `position:absolute`，包含块用 `.sp-mark`（它没有 transform）。
         好处还多一条：进度条贴着 logo，读起来是"**图标在启动**"，
         比孤零零一条挂在屏底更有因果感。
     ⚠️ `.sp-mark` 是 `display:flex`，所以子元素要 `flex:none` 免得被缩
        （这条是实测过的：不写就会被 `flex-shrink:1` 缩成 0 宽）。 */
  #splash .sp-flow {
    display: block;
    position: absolute;
    inset: auto;
    left: 0;
    right: 0;
    top: auto;
    bottom: -18px;
    width: auto;
    height: 2px;
    flex: none;
    border-radius: 0;
    overflow: hidden;
    background: rgba(34, 211, 238, 0.16);
  }
  /* 刻度：每 8px 一格 —— 让它读起来像"进度刻度"而不是一条普通线 */
  #splash .sp-flow::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: repeating-linear-gradient(90deg,
      rgba(3, 6, 11, 0.92) 0 1px, transparent 1px 8px);
  }
  #splash .sp-flow i {
    position: absolute;
    left: 0; top: 0; bottom: 0;
    right: auto;
    width: 0; height: 100%;
    transform: none;
    opacity: 1;
    display: block;
    background: linear-gradient(90deg, rgba(34, 211, 238, 0.5), #7ef0ff);
    box-shadow: 0 0 10px rgba(34, 211, 238, 0.75);
  }
  #splash.playing .sp-flow i { animation: 进度 0.95s cubic-bezier(.3, .1, .2, 1) 0.30s 1 both; }
  @keyframes 进度 { from { width: 0; } to { width: 100%; } }

  /* ---------- ⑦ logo：切角青框 + 辉光 + 一道扫光划过 ---------- */
  #splash .sp-mark img {
    width: 112px; height: 112px;
    border: 2px solid rgba(34, 211, 238, 0.62);
    border-radius: 0;
    clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 14px 100%, 0 calc(100% - 14px));
    box-shadow: 0 0 30px rgba(34, 211, 238, 0.35), inset 0 0 18px rgba(34, 211, 238, 0.18);
    background-color: #061017;
  }
  #splash .sp-mark::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    background: linear-gradient(115deg,
      transparent 42%, rgba(190, 245, 255, 0.85) 50%, transparent 58%);
    transform: translateX(-130%);
    animation: logo扫光 0.62s cubic-bezier(.4, .1, .3, 1) 0.44s 1 both;
  }
  @keyframes logo扫光 {
    from { transform: translateX(-130%); }
    to   { transform: translateX(130%); }
  }

  /* ---------- ⑧ 标题 / 状态字 ----------
     ⚠️ 字色**跟着皮肤走**（基础是 `var(--sp-main)`）—— 不写死青色，
        否则换皮肤时开屏会和全站脱节。 */
  #splash .sp-title {
    font-size: 44px;
    letter-spacing: 14px;
    text-shadow: 0 0 22px rgba(34, 211, 238, 0.55), 2px 2px 0 rgba(3, 6, 11, 0.9);
  }
  /* 状态字：等宽 + 字距，读起来像仪器输出 */
  #splash .sp-sub {
    font-size: 13px;
    letter-spacing: 6px;
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  }
  /* 状态字后面跟一个闪烁块（`.sp-sub::after` 在基础里没被用，可以借） */
  #splash .sp-sub::after {
    content: '';
    display: inline-block;
    width: 7px; height: 11px;
    margin-left: 8px;
    vertical-align: -1px;
    background: currentColor;
    animation: 块闪 0.9s steps(1, end) infinite;
  }
  @keyframes 块闪 { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

  /* ---------- ⑨ 时间轴（覆盖基础节奏）----------
     ☠️ 写在 `animation:` 简写之外，且**带动画元素时必须同样带 `.playing`**
        （特异性，见文件头 ①）。 */
  #splash.playing .sp-mark  { animation: 科技标入 0.56s cubic-bezier(.2, .9, .25, 1) 0.30s both; }
  #splash.playing .sp-title { animation-delay: 0.42s; }
  #splash.playing .sp-sub   { animation-delay: 0.70s; }
  @keyframes 科技标入 {
    from { transform: scale(0.78); opacity: 0; }
    to   { transform: none;        opacity: 1; }
  }

  /* ---------- ⑩ 内容层压在底噪/扫描线之上 ---------- */
  #splash .sp-mark,
  #splash .sp-title,
  #splash .sp-sub { position: relative; z-index: 2; }

  /* ⚠️ 退出**不覆盖**：基础是 `#splash.leaving { animation: sp-out .52s … }`，
     0.52s < `startSplash()` 的 560ms 移除延时，不会"没播完就被删"。少改一处少一处错。 */
}

/* ===== 注入块: angel（锚点，别改；改内容不用动它） ===== */
/* ===== 第 10 套皮肤：圣辉（`body.skin-angel`）（2026-10-06 · PC 版会话） =====
   ------------------------------------------------------------
   用户口径：「**这次要求是天使感觉，带来圣骑士的感觉**」。

   ⚠️ 和「典藏金」怎么拉开（两套都用到金，这是最该防的撞脸）：
     · 典藏金 = **深色的奢华**（近黑底 #050402 + 鎏金拉丝 + 顶光）——"展厅里的藏品"；
     · 圣辉   = **浅色的神圣**（天灵白底 + 清晨圣光 + 光环翅膀）——"教堂里的光"。
     **同色相不可怕，同明度才可怕**（§一百〇六 那条教训）。这两套明度正好相反。

   ⚠️ 关键决策：**用真正的 SVG 图形资产**（翅膀、光环、圣盾），不是梯度椭圆。
      前三轮失败的根本原因：梯度画的"翅膀"读成"金色椭圆"，用户看不出是天使。
      → `design/angel-crest.svg`：光环 + 展翅 + 十字圣盾，组合成圣骑士徽章。

   ⚠️ 不动 `app.js`：9.6 皮肤段是别的会话的。这一套纯靠 `app.js` 现成的
      `--accent` / `--card` / `--line` / `--radius` 变量 + 追加的装饰层。

   ☠️ 老规矩（§一百〇四 第四节，这个坑踩过三次）：
      **图案 / 颜色 / 光晕写在闸门外面**（reduce 的人照样看得见），
      **只有动画写在 `prefers-reduced-motion: no-preference` 里面**。
      另一半原因更要命：**所有截图脚本都用 `reducedMotion:'reduce'`**，
      塞进闸门里 = 截图上什么都没有，而用户是靠截图判断的。
   ============================================================ */

body.skin-angel {
  /* ---------- 天灵白 + 圣金 + 远空蓝（浅色皮肤配色）---------- */
  --accent: #b8860b;              /* 圣金（暗金，亮金压白底对比度不够） */
  --accent-dark: #8a6408;
  --accent-light: #f5ecd8;        /* 浅金底：选中态（浅色皮肤用浅底） */
  --accent-text: #2a2008;         /* 压在金底上的深字 */

  --blue: #6b8fbf;                /* 远空蓝 */
  --blue-light: #e8f2f8;
  --blue-text: #3d5a7f;

  --red: #c94f4f;
  --red-light: #f8e8e8;
  --red-text: #7f3030;

  --green: #5faf6f;               /* 答对绿（浅色皮肤要深一点才够对比） */
  --green-dark: #4e8f5a;
  --green-light: #e8f4e8;
  --green-text: #2d5f35;

  --yellow: #d9a441;
  --gray: #8b8470;                /* 石灰色 */
  --gray-light: #f8f6f0;          /* 天灵白（页面底） */
  --line: #d4c4a8;                /* 暖米色描边 */
  --text: #3a3428;                /* 深字体 */
  --card: #fffcf8;                /* 纯白卡片 */

  --radius: 14px;
  background: #f8f6f0;
}

/* ---------- ① 自上而下的天色渐变 + 圣光辉（页面级，PC 与手机都有）---------- */
html:has(body.skin-angel) {
  background: #f8f6f0;
  background-image:
    /* 圣光辉：从顶部中心放射的金色光芒（12 道，宽而明显） */
    repeating-conic-gradient(from 0deg at 50% 8%,
      rgba(255, 235, 180, 0.28) 0deg 12deg,
      rgba(255, 235, 180, 0) 12deg 30deg),
    /* 清晨圣光核：顶部中心的暖金光团 */
    radial-gradient(circle 320px at 50% 8%, rgba(255, 245, 210, 0.75), transparent 55%),
    /* 天光：清白的天空色，从上到下淡化 */
    linear-gradient(180deg, rgba(235, 245, 255, 0.35) 0%, rgba(250, 248, 245, 0.15) 50%, transparent 80%);
  background-repeat: no-repeat, no-repeat, no-repeat;
  background-size: auto, auto, auto;
  background-attachment: fixed, fixed, fixed;
}

/* ---------- ② 天使徽章：光环 + 翅膀 + 圣盾（真 SVG 资产）---------- */
html:has(body.skin-angel)::before {
  content: '';
  position: fixed;
  left: 50%;
  top: 20px;
  width: 420px;
  height: 210px;
  margin-left: -210px;
  z-index: 0;
  pointer-events: none;
  background-image: url(./mascot/angel-crest.svg);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center top;
  opacity: 0.88;
  filter: drop-shadow(0 2px 8px rgba(184, 134, 11, 0.15))
          drop-shadow(0 0 28px rgba(255, 240, 200, 0.3));
}

/* ---------- ③ 圣坛金框：给整个版心加一圈金色光边 ---------- */
html:has(body.skin-angel)::after {
  content: '';
  position: fixed;
  inset: 12px;
  z-index: 0;
  pointer-events: none;
  border: 2px solid rgba(184, 134, 11, 0.28);
  border-radius: 8px;
  box-shadow:
    inset 0 0 0 1px rgba(255, 245, 220, 0.4),
    inset 0 0 42px rgba(255, 235, 190, 0.12),
    0 0 20px rgba(255, 225, 170, 0.08);
}

/* ---------- ④ 极淡的纸感纹理 ---------- */
body.skin-angel::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(0deg, rgba(184, 134, 11, 0.018) 0 1px, transparent 1px 5px),
    repeating-linear-gradient(90deg, rgba(184, 134, 11, 0.012) 0 1px, transparent 1px 7px);
  background-attachment: fixed;
}

/* ---------- ⑤ 内容压在装饰层之上 ---------- */
body.skin-angel .app {
  position: relative;
  z-index: 1;
  background: transparent;
}
body.skin-angel .topbar { 
  background: transparent;
  backdrop-filter: blur(2px);
}

/* ---------- ⑥ 卡片：白底 + 暖描边 + 圣光边 ---------- */
body.skin-angel .subject-card,
body.skin-angel .card,
body.skin-angel .pill,
body.skin-angel .mini-btn,
body.skin-angel .opt,
body.skin-angel .key {
  border: 1.5px solid var(--line);
  background: var(--card);
  box-shadow: 
    0 1px 0 rgba(255, 255, 255, 0.85) inset, 
    0 2px 6px rgba(120, 96, 40, 0.06),
    0 0 0 1px rgba(255, 255, 255, 0.5) inset;
}

/* ---------- ⑦ 主按钮：金底 + 深字（对比度硬要求）---------- */
body.skin-angel .btn-main,
body.skin-angel .multi-confirm,
body.skin-angel .foot-btn.primary,
body.skin-angel .result-filter .mini-btn.active,
body.skin-angel .cfg-opts .mini-btn.active,
body.skin-angel .key.ok,
body.skin-angel .rc-go,
body.skin-angel .uc-tab.active,
body.skin-angel .icon-btn.exam-submit {
  background: linear-gradient(180deg, #d4af37 0%, #b8860b 100%);
  border-color: var(--accent-dark);
  color: #2a2008;
  box-shadow: 
    0 1px 0 rgba(255, 255, 255, 0.25) inset,
    0 2px 8px rgba(184, 134, 11, 0.2),
    0 0 12px rgba(255, 235, 180, 0.3);
}

/* ---------- ⑧ 标题：暖金 + 圣光 ---------- */
body.skin-angel .sec-title,
body.skin-angel .brand {
  color: #8a6408;
  letter-spacing: 0.5px;
  text-shadow: 0 0 18px rgba(255, 235, 180, 0.4);
}

body.skin-angel .lv-badge {
  background: linear-gradient(135deg, #d4af37 0%, #b8860b 100%);
  color: #2a2008;
  box-shadow: 0 0 16px rgba(255, 225, 150, 0.6),
              0 2px 6px rgba(184, 134, 11, 0.3);
}

/* ---------- ⑨ 圣盾小图标：在品牌旁边 ---------- */
body.skin-angel .brand::before {
  content: '✦';
  display: inline-block;
  margin-right: 6px;
  color: #d4af37;
  font-size: 1.1em;
  text-shadow: 0 0 12px rgba(255, 235, 180, 0.6);
}

/* ---------- ⑩ 底部导航（手机）：暖白 + 金色选中 ---------- */
body.skin-angel .tabbar {
  background: rgba(255, 253, 248, 0.95);
  border-top: 1.5px solid var(--line);
  backdrop-filter: blur(8px);
}

/* ---------- ⑪ 手机尺寸：缩小徽章 ---------- */
@media (max-width: 899px) {
  html:has(body.skin-angel)::before {
    width: 320px;
    height: 160px;
    margin-left: -160px;
    top: 12px;
  }
}

/* ---------- ⑫ 动效层（★ 全部关在闸门里）---------- */
@media (prefers-reduced-motion: no-preference) {
  /* 徽章缓慢呼吸 */
  @keyframes 徽章呼吸 {
    0%, 100% { opacity: 0.85; transform: scale(1); }
    50%      { opacity: 0.95; transform: scale(1.02); }
  }
  html:has(body.skin-angel)::before {
    animation: 徽章呼吸 5s ease-in-out infinite;
  }

  /* 圣光层缓慢闪烁 */
  @keyframes 圣光流动 {
    0%, 100% { filter: brightness(1); }
    50%      { filter: brightness(1.08); }
  }
  html:has(body.skin-angel) {
    animation: 圣光流动 8s ease-in-out infinite;
  }

  /* 金框微光流动 */
  @keyframes 金框微光 {
    0%, 100% { opacity: 0.85; }
    50%      { opacity: 1; }
  }
  html:has(body.skin-angel)::after {
    animation: 金框微光 6s ease-in-out infinite;
  }

  /* PC 才有：卡片浮起时带圣光 */
  @media (min-width: 900px) {
    body.skin-angel .subject-card,
    body.skin-angel .card {
      transition: box-shadow 0.22s ease, transform 0.22s ease;
    }
    body.skin-angel .subject-card:hover,
    body.skin-angel .card:hover {
      transform: translateY(-2px);
      box-shadow: 
        0 1px 0 rgba(255, 255, 255, 0.85) inset,
        0 8px 20px rgba(120, 96, 40, 0.14),
        0 0 0 1px rgba(184, 134, 11, 0.25),
        0 0 18px rgba(255, 235, 180, 0.2);
    }
  }
}

/* ===== 圣辉 结束（块尾标记，别删） ===== */