/* 字从何来 — 设计系统
 *
 * 调性：深色古籍 / 金石 / 朱砂
 * 原则：所有视觉决策收敛到 token，页面只消费 token。
 *       美术资源不足时靠系统一致性兜底，而不是靠灵感。
 */

:root {
  /* ── 墨（背景层）────────────────────── */
  --ink-900: #0d0b09;
  --ink-800: #141110;
  --ink-700: #1c1815;
  --ink-600: #262019;
  --ink-500: #332b22;

  /* ── 宣纸（文字层）──────────────────── */
  --paper-100: #f2ece0;
  --paper-200: #ded5c4;
  --paper-300: #b0a695;
  --paper-400: #7d7468;
  --paper-500: #565049;

  /* ── 金石（主强调）──────────────────── */
  --bronze-400: #8a6f45;
  --bronze-500: #b8935a;
  --bronze-600: #d4af6a;
  --gold: #c9a227;

  /* ── 朱砂（次强调 / 警示）───────────── */
  --cinnabar: #b03a2e;
  --cinnabar-bright: #d4503f;

  /* ── 语义色 ─────────────────────────── */
  --bg: var(--ink-900);
  --surface: var(--ink-800);
  --surface-raised: var(--ink-700);
  --border: rgba(184, 147, 90, 0.18);
  --border-strong: rgba(184, 147, 90, 0.36);

  --text: var(--paper-100);
  --text-muted: var(--paper-300);
  --text-faint: var(--paper-400);
  --accent: var(--bronze-500);
  --accent-bright: var(--bronze-600);

  /* ── 06 关系网专用（浅色画布上不能用半透明青铜，会读成灰）── */
  --graph-edge-component: #2f5d43;   /* 实线：构形关系（墨绿） */
  --graph-edge-related: #b8935a;     /* 虚线：相关字（青铜） */

  /* ── 字形专用 ───────────────────────── */
  --glyph-ink: var(--paper-100);          /* 已写出的墨 */
  --glyph-ghost: rgba(242, 236, 224, 0.07); /* 未写出的底纹 */
  --glyph-dim: rgba(242, 236, 224, 0.22);   /* 高亮时的其余笔画 */

  /* ── 字阶 ───────────────────────────── */
  --fs-xs: 11px;
  --fs-sm: 13px;
  --fs-base: 15px;
  --fs-lg: 18px;
  --fs-xl: 24px;
  --fs-2xl: 34px;
  --fs-3xl: 52px;

  --font-serif: "Songti SC", "SimSun", "Noto Serif SC", "Source Han Serif SC", serif;
  --font-sans: "PingFang SC", "Microsoft YaHei", "Noto Sans SC", system-ui, sans-serif;

  /* ── 间距 ───────────────────────────── */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;

  /* ── 圆角 ───────────────────────────── */
  --r-sm: 3px;
  --r-md: 6px;
  --r-lg: 10px;

  /* ── 动效 ───────────────────────────── */
  --dur-fast: 160ms;
  --dur-base: 300ms;
  --dur-slow: 560ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-inout: cubic-bezier(0.65, 0, 0.35, 1);
}

/* ── 基础 ───────────────────────────────── */
* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* 我的造字：保持与主站相同的数字东方材料感，但把操作区放在第一视野。 */
.zc-footer { margin-top: var(--sp-7); padding-top: var(--sp-4); border-top: 1px solid var(--border); line-height: 1.8; }

/* 没准备好之前，整页不显示。
 *
 * 这里说的是两件事，第二件是后补的、也是用户真正看到的那一件：
 *
 * ① 空壳。Vue 挂载完成前 #app 是空的，整页只剩「字启千年」和页脚那条授权说明 ——
 *    实测挂载前 .zc-app 只有 236px 高（挂载后 1786px），小字号的授权说明正好落在首屏
 *    最显眼的位置。
 * ② 字形。⚠️ 上一版只藏了页脚，还专门写了「页眉不藏：挂载前后像素一致」—— 那条
 *    论证量的是**盒子几何**（top 28 / 高 100 / 字号 49.464px 不动），**没量字形**。
 *    而页眉恰恰是换字最明显的地方：站上三个字体文件是 5.2 / 17.7 / 25.1 MB，冷启动
 *    实测第 54ms 才登记、第 370ms 才加载完；@font-face 又写着 font-display:swap，
 *    于是**整页先用后备字形画一遍，再整体换掉**（Windows 上落到雅黑/宋体）。
 *    实测第 297ms 那一帧：页眉是细宋、正文一片空白。用户的原话是「弹出来一秒别的样式
 *    的网站界面」—— 说的就是这个，不是页脚。
 *
 * 所以现在整块 .zc-app 一起等。用 visibility 而不是 display：display:none 会让浏览器
 * 不为这些文字做布局，也就不会去请求字体，闸门会绕成死锁；visibility 保留布局。
 * .zc-ready 由 src/ui/app-shell.js 的 ZQ.revealWhenReady 在**挂载完成 + 字体到位**
 * 之后加上；无脚本时由 index.html 的 <noscript> 兜底。 */
html:not(.zc-ready) .zc-app { visibility: hidden; }
.zc-mine { display: grid; gap: var(--sp-6); }
.zc-mine-intro { display: flex; align-items: end; justify-content: space-between; gap: var(--sp-6); padding: var(--sp-5); background: linear-gradient(120deg, rgba(20, 48, 55, .78), rgba(20, 17, 16, .35)); border: 1px solid var(--border); border-radius: var(--r-lg); }
.zc-mine-intro h2 { font-family: var(--font-serif); font-size: clamp(1.8rem, 4vw, 2.8rem); font-weight: 400; letter-spacing: .08em; }
.zc-mine-intro p { max-width: 680px; color: var(--text-muted); margin-top: var(--sp-2); }
.zc-mine-count { min-width: 120px; text-align: right; color: var(--text-muted); }
.zc-mine-count b { display: block; color: var(--accent-bright); font: 400 2.6rem var(--font-serif); }
.zc-mine-count span { font-size: var(--fs-sm); }
.zc-mine-work { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(260px, .75fr); align-items: start; gap: var(--sp-5); }
.zc-mine-composer .zc-compose { grid-template-columns: 116px minmax(0, 1fr); }
.zc-mine-composer .zc-compose-palette { max-height: 610px; overflow: auto; }
.zc-mine-tools { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-top: var(--sp-3); }
.zc-mine-form { display: grid; gap: var(--sp-4); padding: var(--sp-5); position: sticky; top: 18px; }
.zc-mine-form label { display: grid; gap: 7px; color: var(--text-muted); font-size: var(--fs-sm); }
.zc-mine-form input { width: 100%; min-height: 42px; padding: 8px 10px; border-radius: var(--r-sm); border: 1px solid var(--border-strong); background: rgba(0,0,0,.16); color: var(--text); font: inherit; }
.zc-mine-form input:focus { outline: 2px solid rgba(212,175,106,.42); outline-offset: 1px; }
.zc-mine-quick { display: flex; flex-wrap: wrap; gap: 7px; }
.zc-mine-quick button { padding: 5px 9px; color: var(--text-muted); background: transparent; border: 1px solid var(--border); border-radius: 999px; cursor: pointer; font: inherit; font-size: var(--fs-sm); }
.zc-mine-quick button:hover { color: var(--accent-bright); border-color: var(--bronze-400); }
.zc-mine-summary { color: var(--text-muted); font-size: var(--fs-sm); }
.zc-mine-summary b { color: var(--text); font-weight: 500; }
.zc-mine-generate { width: 100%; justify-content: center; }
.zc-poster-result { display: grid; grid-template-columns: minmax(260px, 430px) 1fr; gap: var(--sp-6); align-items: center; padding: var(--sp-5); background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); }
.zc-poster-frame { width: min(100%, 430px); box-shadow: 0 18px 50px rgba(0,0,0,.35); }
.zc-poster-frame canvas { display: block; width: 100%; height: auto; }
.zc-poster-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); color: var(--text-muted); }
.zc-poster-actions > div { flex: 1 1 100%; }
.zc-mine-library { padding-top: var(--sp-5); border-top: 1px solid var(--border); }
.zc-mine-library-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: var(--sp-3); margin-top: var(--sp-3); }
.zc-mine-card { position: relative; display: grid; grid-template-columns: 68px 1fr; gap: var(--sp-3); align-items: center; padding: var(--sp-3); background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md); }
.zc-mine-card-glyph { color: var(--accent-bright); font: 2rem var(--font-serif); text-align: center; overflow: hidden; white-space: nowrap; }
.zc-mine-card p, .zc-mine-card small { color: var(--text-muted); font-size: var(--fs-sm); }
.zc-icon-btn { position: absolute; right: 5px; top: 4px; width: 24px; height: 24px; color: var(--text-faint); background: transparent; border: 0; font-size: 22px; cursor: pointer; }
.zc-icon-btn:hover { color: var(--cinnabar-bright); }
.zc-mine-notice { padding: 10px 14px; color: var(--accent-bright); border-left: 2px solid var(--accent); background: rgba(184,147,90,.08); }

@media (max-width: 820px) {
  .zc-mine-work, .zc-poster-result { grid-template-columns: 1fr; }
  .zc-mine-form { position: static; }
  .zc-mine-intro { align-items: start; flex-direction: column; }
  .zc-mine-count { text-align: left; }
}
@media (max-width: 560px) {
  .zc-mine-composer .zc-compose { grid-template-columns: 1fr; }
  .zc-mine-composer .zc-compose-palette { max-height: none; }
}

/* 宣纸质感：极淡的噪点 + 径向渐晕，避免纯色死板 */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(ellipse at 50% 0%, rgba(184, 147, 90, 0.06), transparent 60%),
    radial-gradient(ellipse at 50% 100%, rgba(176, 58, 46, 0.04), transparent 60%);
}

/* ── 布局 ───────────────────────────────── */
.zc-app {
  position: relative;
  z-index: 1;
  max-width: 1080px;
  margin: 0 auto;
  padding: var(--sp-6) var(--sp-5);
}

.zc-header {
  display: flex;
  align-items: baseline;
  gap: var(--sp-4);
  padding-bottom: var(--sp-5);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--sp-6);
}

.zc-title {
  font-family: var(--font-serif);
  font-size: var(--fs-2xl);
  font-weight: 400;
  letter-spacing: 0.08em;
}

.zc-subtitle {
  font-size: var(--fs-sm);
  color: var(--text-faint);
  letter-spacing: 0.16em;
}

.zc-stage {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: var(--sp-6);
  align-items: start;
}

@media (max-width: 780px) {
  .zc-stage { grid-template-columns: 1fr; }
}

/* ── 字形画布 ───────────────────────────── */
.zc-canvas-wrap {
  position: relative;
  background: linear-gradient(160deg, var(--ink-800), var(--ink-700));
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-4);
  aspect-ratio: 1 / 1;
}

.zc-canvas { width: 100%; height: 100%; display: block; }

/* 字形渲染层 */
.zc-ghost path {
  fill: var(--glyph-ghost);
  transition: fill var(--dur-base) var(--ease-out);
}

.zc-brush {
  stroke: var(--glyph-ink);
  transition: stroke var(--dur-base) var(--ease-out),
              opacity var(--dur-fast) var(--ease-out);
}

.zc-brush.zc-dim { stroke: var(--glyph-dim); }
.zc-brush.zc-hidden { opacity: 0; }

/* 印章：右下角朱砂小方，视觉锚点 */
.zc-seal {
  position: absolute;
  right: var(--sp-4);
  bottom: var(--sp-4);
  width: 34px;
  height: 34px;
  border: 1.5px solid var(--cinnabar);
  border-radius: 2px;
  display: grid;
  place-items: center;
  font-family: var(--font-serif);
  font-size: var(--fs-sm);
  color: var(--cinnabar);
  opacity: 0.75;
  letter-spacing: 0;
}

/* ── 控制条 ─────────────────────────────── */
.zc-controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;        /* 放不下就整颗换行 —— 不要靠压缩按钮宽度来塞 */
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}

.zc-btn {
  font-family: inherit;
  font-size: var(--fs-sm);
  letter-spacing: 0.06em;
  /* flex 子项默认会缩，缩过头按钮里的字就自己折成两行（「并览」→「并/览」）。
     侧栏只有 280px，四个按钮+间隔刚好卡在边界上，实测会被压。 */
  flex: 0 0 auto;
  white-space: nowrap;
  color: var(--text);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-2) var(--sp-4);
  cursor: pointer;
  transition: all var(--dur-fast) var(--ease-out);
}

.zc-btn:hover {
  border-color: var(--border-strong);
  background: var(--ink-600);
}

.zc-btn.is-primary {
  border-color: var(--bronze-400);
  color: var(--accent-bright);
}

.zc-btn.is-primary:hover { background: rgba(184, 147, 90, 0.12); }

.zc-btn[disabled] { opacity: 0.35; cursor: not-allowed; }

/* ── 进度 / 时间轴 ──────────────────────── */
.zc-timeline {
  flex: 1;
  -webkit-appearance: none;
  appearance: none;
  height: 2px;
  background: var(--ink-500);
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}

.zc-timeline::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--bronze-500);
  cursor: grab;
  transition: transform var(--dur-fast) var(--ease-out);
}

.zc-timeline::-webkit-slider-thumb:hover { transform: scale(1.25); }

.zc-timeline::-moz-range-thumb {
  width: 12px; height: 12px; border: none; border-radius: 50%;
  background: var(--bronze-500); cursor: grab;
}

/* ── 侧栏 ───────────────────────────────── */
.zc-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-4);
}

.zc-panel + .zc-panel { margin-top: var(--sp-4); }

.zc-panel-title {
  font-size: var(--fs-xs);
  letter-spacing: 0.2em;
  color: var(--text-faint);
  text-transform: uppercase;
  margin-bottom: var(--sp-3);
}

/* 选字网格 */
.zc-chargrid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--sp-1);
}

.zc-charbtn {
  font-family: var(--font-serif);
  font-size: var(--fs-lg);
  color: var(--text-muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  aspect-ratio: 1;
  cursor: pointer;
  transition: all var(--dur-fast) var(--ease-out);
}

.zc-charbtn:hover {
  color: var(--text);
  background: var(--ink-600);
}

.zc-charbtn.is-active {
  color: var(--accent-bright);
  border-color: var(--bronze-400);
  background: rgba(184, 147, 90, 0.1);
}

/* 笔画列表 */
.zc-strokelist { display: flex; flex-direction: column; gap: 2px; }

.zc-strokeitem {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--text-faint);
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: all var(--dur-fast) var(--ease-out);
}

.zc-strokeitem:hover { background: var(--ink-700); color: var(--text-muted); }

.zc-strokeitem.is-active {
  background: rgba(184, 147, 90, 0.12);
  color: var(--accent-bright);
}

.zc-strokeitem .dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: currentColor; opacity: 0.5; flex: none;
}

.zc-strokeitem.is-radical .dot { background: var(--cinnabar); opacity: 1; }

.zc-strokeitem .tag {
  margin-left: auto;
  font-size: var(--fs-xs);
  color: var(--cinnabar);
  letter-spacing: 0.08em;
}

/* 元信息 */
.zc-meta { display: flex; gap: var(--sp-4); font-size: var(--fs-sm); }
.zc-meta dt { color: var(--text-faint); font-size: var(--fs-xs); letter-spacing: 0.1em; }
.zc-meta dd { color: var(--text); font-family: var(--font-serif); font-size: var(--fs-lg); }

/* 提示条 */
.zc-note {
  font-size: var(--fs-xs);
  color: var(--text-faint);
  line-height: 1.7;
  border-left: 2px solid var(--border-strong);
  padding-left: var(--sp-3);
  margin-top: var(--sp-4);
}

.zc-note strong { color: var(--text-muted); font-weight: 500; }

/* ── 构形挑战 ───────────────────────────── */

/* 已归位的构件：定住，不再响应拖拽 */
.zc-comp.is-locked { cursor: default; }
.zc-comp.is-locked .zc-comp-hit { cursor: default; }
.zc-comp.is-locked .zc-comp-shape { fill: var(--bronze-600); }

.zc-chalstat {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;   /* 数字跳动时宽度不抖 */
}

.zc-chalstat + .zc-chalstat {
  margin-left: var(--sp-4);
  color: var(--text-faint);
}

/* 成功面板 */
.zc-solved {
  position: relative;
  margin-top: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  background: linear-gradient(120deg, rgba(184, 147, 90, 0.14), rgba(176, 58, 46, 0.08));
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  animation: zc-rise var(--dur-slow) var(--ease-out) both;
}

@keyframes zc-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

.zc-solved-badge {
  display: inline-block;
  font-family: var(--font-serif);
  font-size: var(--fs-lg);
  letter-spacing: 0.24em;
  color: var(--cinnabar-bright);
  border: 1.5px solid var(--cinnabar);
  border-radius: var(--r-sm);
  padding: 2px var(--sp-3);
}

.zc-solved-relation {
  font-family: var(--font-serif);
  font-size: var(--fs-lg);
  color: var(--text);
  letter-spacing: 0.06em;
  margin-top: var(--sp-3);
}

.zc-solved-stats {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  margin-top: var(--sp-2);
  font-variant-numeric: tabular-nums;
}

/* ── 拆解模块 ───────────────────────────── */

/* 整字底纹：分离后仍能看出该拼回哪里 */
.zc-decomp-ghost path {
  fill: rgba(242, 236, 224, 0.045);
}

/* 不可拆解的字（象形字）：整字实心显示 */
.zc-decomp-solid path {
  fill: var(--paper-200);
}

/* 构件 */
.zc-comp {
  cursor: grab;
  touch-action: none;        /* 触屏拖拽必需，否则会被页面滚动抢走 */
}
.zc-comp .zc-comp-shape {
  fill: var(--paper-200);
  transition: fill var(--dur-fast) var(--ease-out);
}
.zc-comp .zc-comp-hit {
  pointer-events: stroke;    /* 透明描边只负责扩大抓取范围 */
  cursor: grab;
}
.zc-comp:hover .zc-comp-shape { fill: var(--paper-100); }

.zc-comp.is-selected .zc-comp-shape { fill: var(--accent-bright); }
.zc-comp.is-dragging { cursor: grabbing; }
.zc-comp.is-dragging .zc-comp-hit { cursor: grabbing; }
.zc-comp.is-dragging .zc-comp-shape { fill: var(--paper-100); }

/* 拖拽时抬起来一点的投影感 */
.zc-comp.is-dragging { filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55)); }

/* 构件信息条 */
.zc-compinfo {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: rgba(184, 147, 90, 0.08);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-md);
  margin-top: var(--sp-4);
  min-height: 52px;
}

.zc-compinfo .glyph {
  font-family: var(--font-serif);
  font-size: var(--fs-2xl);
  color: var(--accent-bright);
  line-height: 1;
}

.zc-compinfo .name {
  font-size: var(--fs-base);
  color: var(--text);
}

.zc-compinfo .meaning {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.zc-compinfo .role {
  margin-left: auto;
  font-size: var(--fs-xs);
  letter-spacing: 0.12em;
  color: var(--cinnabar-bright);
  border: 1px solid var(--cinnabar);
  border-radius: var(--r-sm);
  padding: 1px var(--sp-2);
}

.zc-compinfo.is-empty { color: var(--text-faint); }

/* 字理说明 */
.zc-relation {
  font-family: var(--font-serif);
  font-size: var(--fs-lg);
  color: var(--text-muted);
  letter-spacing: 0.06em;
  margin-top: var(--sp-3);
}

/* 构件按钮组 */
.zc-modeline {
  display: flex;
  gap: var(--sp-2);
  align-items: center;
}

.zc-seg {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
}

.zc-seg button {
  font-family: inherit;
  font-size: var(--fs-sm);
  color: var(--text-muted);
  background: transparent;
  border: none;
  padding: var(--sp-2) var(--sp-4);
  cursor: pointer;
  transition: all var(--dur-fast) var(--ease-out);
}

.zc-seg button:hover { background: var(--ink-600); color: var(--text); }

.zc-seg button.is-active {
  background: rgba(184, 147, 90, 0.14);
  color: var(--accent-bright);
}

/* ═══════════════════════════════════════════
   演变模块
   ═══════════════════════════════════════════ */

/* 阶段缩略图条 —— 既是时间轴的可视刻度，也是点击跳转的入口 */
.zc-evostrip {
  display: flex;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
}

.zc-evostage {
  flex: 1;
  min-width: 0;
  background: var(--ink-700);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-1) var(--sp-1) var(--sp-2);
  cursor: pointer;
  text-align: center;
  transition: all var(--dur-fast) var(--ease-out);
}

.zc-evostage:hover { border-color: var(--border-strong); background: var(--ink-600); }

.zc-evostage.is-active {
  border-color: var(--gold);
  background: rgba(201, 162, 39, 0.08);
}

/* 正在淡入的「下一期」：和画布上正在淡上来的那一层对应。
   用虚线边，和 is-active 的实线金边区分开 —— 淡完之后它才变成 is-active。 */
.zc-evostage.is-next {
  border-color: var(--cinnabar);
  border-style: dashed;
  background: rgba(178, 58, 44, 0.08);
}

/* 没有字形的那一期：压暗 + 划掉，一眼看出这是「史料里没有」而不是「程序坏了」 */
.zc-evostage.is-absent { opacity: 0.42; }
.zc-evostage.is-absent .zc-evostage-name { text-decoration: line-through; }

.zc-evostage svg { display: block; width: 100%; height: auto; }
.zc-evostage path { fill: var(--glyph-ink); fill-rule: evenodd; }

.zc-evostage-name {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.zc-evostage.is-active .zc-evostage-name { color: var(--gold); }

/* 阶段详情 */
.zc-stageinfo-head {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  flex-wrap: wrap;
}

.zc-stageinfo-name {
  font-family: var(--font-serif);
  font-size: var(--fs-xl);
  color: var(--accent-bright);
  letter-spacing: 0.08em;
}

.zc-stageinfo-period {
  font-size: var(--fs-sm);
  color: var(--text-faint);
  letter-spacing: 0.06em;
}

.zc-stageinfo-note {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  margin-top: var(--sp-2);
  line-height: 1.7;
}

.zc-stageinfo-src {
  font-size: var(--fs-xs);
  color: var(--text-faint);
  line-height: 1.7;
  margin-top: var(--sp-3);
  padding-top: var(--sp-2);
  border-top: 1px solid var(--border);
}

.zc-stageinfo-src b { color: var(--text-muted); font-weight: 500; }
.zc-stageinfo-src .warn { color: var(--cinnabar-bright); }

/* 此字各期覆盖一览 */
.zc-stagecov { display: flex; flex-wrap: wrap; gap: var(--sp-1); }

.zc-covchip {
  font-size: var(--fs-xs);
  padding: 2px var(--sp-2);
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  color: var(--text-faint);
}

.zc-covchip.has { color: var(--text-muted); border-color: var(--border-strong); }
.zc-covchip.is-now { border-color: var(--gold); color: var(--gold); }
.zc-covchip.no { opacity: 0.45; }

/* 隶变节点：这一期**不在**时间轴上（本地无隶书字形，不拿小篆或楷书顶替），
   所以它紧跟在「此字各期覆盖一览」之后，明说自己属于「时间轴之外」。
   按钮长得像 covchip，但它是**能点的** —— 形状相近、行为不同，所以用
   :hover/:focus-visible 把可点这件事显出来。 */
.zc-li-node { margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--border); }
.zc-li-chars { display: flex; flex-wrap: wrap; gap: var(--sp-1); margin-top: var(--sp-2); }

.zc-li-chip {
  font-family: var(--font-serif);
  font-size: var(--fs-lg);
  line-height: 1;
  padding: 5px var(--sp-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}

.zc-li-chip:hover,
.zc-li-chip.is-active { border-color: var(--gold); color: var(--gold); }
.zc-li-chip:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* 并览模式下画布是六宫格，不需要外部留白感 */
.zc-canvas.is-overview { background: var(--ink-800); }

/* 演变模块的 SVG 元素：颜色一律走 class ——
   CSS 变量在 SVG 表现属性（fill="var(--x)"）里不生效，只在 CSS 规则里生效。 */
.zc-evo-glyph { fill: var(--glyph-ink); }

.zc-evo-cell { fill: none; stroke: var(--border); }
.zc-evo-miss { fill: var(--text-faint); }
/* 缺格依据那行。刻意与 .zc-evo-miss 同色 —— 它不是新的一档灰，
   只是正文下面的一行小字；对比度由读合成像素那组用例量，不在这里另立一套。 */
.zc-evo-note { fill: var(--text-faint); }
.zc-evo-label { fill: var(--text-faint); }
.zc-evo-label.is-current { fill: var(--gold); }

/* ── 06 汉字关系网：图元（同样一律走 class）──────────────────────────
   线型本身就是信息，不是装饰：实线 = 两个字的构形有关系（谁由谁构成，
   由 src/graph.js 按 DECOMPOSITION 机械判定），虚线 = 教学目录里同列的
   相关字。这是 data/catalog.js 文件头 [8] 那一节早就定下的约定。
   这一页的主画布也是浅色（workbench.css 把 --glyph-ink 改成了深墨），
   所以下面直接用那几个变量，不另造一套颜色。 */
.zc-graph-edge { stroke: var(--graph-edge-component); stroke-width: 1.8; }
.zc-graph-edge.is-component { stroke-width: 2.4; }
.zc-graph-edge.is-related { stroke: var(--graph-edge-related); stroke-width: 1.6; stroke-dasharray: 5 5; }
/* 选中推荐路径时加粗换色，但**不取消虚线** —— 一取消就分不出这条边
   到底是构形还是语义了，那正是这张图要讲的事。 */
.zc-graph-edge.is-path { stroke: var(--gold); stroke-width: 3.2; }

/* 画布下方的图例。色块刻意与上面两条**同宽同色**（实线、虚线 dashed），
   不另画一套 —— 图例长得跟图上不一样，比没有图例更糟。
   色值来自 --graph-edge-*，与画布边同源：verify/test-graph-ui.mjs ⑦
   直接比两处**算出来的**颜色。 */
.zc-graph-key { display:flex; align-items:flex-start; gap:9px; margin:0 0 9px; font:400 13px/1.65 var(--font-reading); color:#4d6155; }
.zc-graph-key b { color:#283f30; font-weight:600; }
.zc-graph-key-line { flex:none; width:28px; height:3px; margin-top:9px; background:var(--graph-edge-component); border-radius:2px; }
.zc-graph-key-line.is-related { height:0; background:var(--graph-edge-related); border-top:3px dashed var(--graph-edge-related); border-radius:0; }
.zc-graph-key-example { font-style:normal; font-family:var(--font-brand); font-size:14px; letter-spacing:.02em; color:#3a5a45; margin-left:2px; }

/* 节点：宣纸圆章。圆圈保持不透明（线从字底下穿过时会被挡住，
   verify/test-graph-ui.mjs ② 按算出来的 fill 断言）。 */
.zc-graph-node { filter: drop-shadow(0 1px 2px rgba(35,60,45,.14)); }
.zc-graph-node circle { fill: #fffefa; stroke: #5c6f62; stroke-width: 1.6; }
.zc-graph-node[role="button"] { cursor: pointer; }
.zc-graph-node[role="button"]:hover { filter: drop-shadow(0 3px 6px rgba(35,60,45,.22)); }
.zc-graph-node[role="button"]:hover circle { stroke: var(--gold); stroke-width: 2.4; }
.zc-graph-glyph { fill: var(--glyph-ink); font-family: var(--font-brand); font-weight: 500; }
.zc-graph-node.is-core .zc-graph-glyph { font-size: 26px; }
.zc-graph-node.is-extended .zc-graph-glyph { font-size: 23px; }
.zc-graph-node.is-related .zc-graph-glyph { font-size: 21px; }
.zc-graph-node.is-unknown .zc-graph-glyph { font-size: 19px; }
/* 分层浓度：核心字深墨圈、扩展字淡一档、关联字/表外构件再淡且虚一格 ——
   与「虚线是语义关系」同一个读法：它不是一个能当选中字的字。 */
.zc-graph-node.is-core circle { stroke: var(--graph-edge-component); stroke-width: 2.2; }
.zc-graph-node.is-extended circle { stroke: #5c6f62; stroke-width: 1.8; }
.zc-graph-node.is-related circle { stroke: #8a9b8e; stroke-width: 1.5; stroke-dasharray: 4 3; fill: #fbfaf4; }
.zc-graph-node.is-unknown circle { stroke: #aab8ad; stroke-width: 1.4; stroke-dasharray: 2 3; fill: #fbfaf4; }
.zc-graph-node.is-locked .zc-graph-glyph { fill: var(--glyph-dim); }
.zc-graph-node.is-center circle { fill: var(--glyph-ink); stroke: var(--glyph-ink); }
.zc-graph-node.is-center .zc-graph-glyph { fill: #fffefa; font-size: 30px; }
/* 中心节点的外圈（r+6，由 render() 加在墨圈**之后**，保证墨圈是第一个 circle） */
.zc-graph-center-ring { fill: rgba(255,254,250,0); stroke: var(--graph-edge-component); stroke-width: 1.5; }
.zc-graph-node.is-path circle { stroke: var(--gold); stroke-width: 2.8; }
/* 关联字的「点它其实去的是这个字」：用纸色描边做光晕，读成一个小标签。
   不另画矩形 —— 矩形要量字宽，越界断言按真实渲染框量，会多出风险。
   光晕顺带把底色变成一块平的白（实测底色众数恒为 rgb(255,254,250)，
   与光晕同色），所以这里的对比度只由字色决定。原来的 #6b7d70 在这个底色上
   实测 4.34:1（见 verify/test-graph-ui.mjs 里那段合成像素实测）—— 够不到小字 4.5:1 的下限，
   而它是全页最小的一行字（11px 画在 560 单位的画布里）。压到与其余小字同一个
   #5c6a4e 后 ≈5.7:1。字形尺寸、光晕宽度、坐标一律未动。 */
.zc-graph-anchor { fill: #5c6a4e; stroke: #fffefa; stroke-width: 4; paint-order: stroke; font: 400 11px var(--font-reading); }

/* ── 构形实验室外壳（02 的三模式页签）────────── */

.zc-lab-tabs { margin-bottom: var(--sp-4); }

.zc-lab-hint {
  font-size: var(--fs-sm);
  color: var(--text-faint);
  margin-bottom: var(--sp-5);
  min-height: 1.6em;      /* 三句提示长短不一，留出固定高度，切页签时下面的画布不跳 */
}

.zc-lab aside { min-width: 0; }

/* ── 构形实验室 ③ 自由构字 ─────────────────── */

/* ⚠️ 主栏必须限宽，不能是 1fr。
 *    .zc-canvas-wrap 是 aspect-ratio:1/1，跟着栏宽走 —— 模式①② 看不出来，
 *    因为整字总会把方框填满；但模式③ 摆的是好几个构件，一行三块每块只占三分之一高，
 *    栏一宽（实测 1120px）画布就成了 1100px 见方，构件缩在中间一条，又空又小。
 *    560 是配 SIZE=520 的：画布显示尺寸接近 1:1，拖拽手感也对。
 *    限在**主栏**而不是单给画布限宽，是因为判定条也在这一栏里 ——
 *    只限画布的话，判定条还是会撑到全栏宽，两块的左边缘对不齐。 */
.zc-compose {
  display: grid;
  grid-template-columns: 232px minmax(0, 560px);
  justify-content: center;
  gap: var(--sp-5);
  align-items: start;
}
@media (max-width: 720px) {
  .zc-compose { grid-template-columns: 1fr; }
}

.zc-compose-hint {
  display: block;
  margin-top: var(--sp-1);
  font-size: var(--fs-xs);
  color: var(--text-faint);
  letter-spacing: 0;
}

/* 构件盘：6 列，正好 24 格排满 4 行 */
.zc-compose-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--sp-1);
  margin-top: var(--sp-3);
}

.zc-compbtn {
  aspect-ratio: 1;
  font-family: var(--font-serif);
  font-size: var(--fs-xl);
  color: var(--text-muted);
  background: var(--ink-700);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.zc-compbtn:hover {
  background: var(--ink-600);
  color: var(--text);
  border-color: var(--border-strong);
}
.zc-compbtn:active { transform: translateY(1px); }

/* 派生偏旁（亻 宀）不是独立的字，视觉上降一级 —— 这一点在 UI 上必须能看出来 */
.zc-compbtn.is-derived {
  color: var(--text-faint);
  border-style: dashed;
}

.zc-compose-main { min-width: 0; }

.zc-compose-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  font-size: var(--fs-sm);
  color: var(--text-faint);
}

/* 空画布要像个**待用的画布**。空的近白方块加一行小字，一眼看过去和「没渲染出来」
   没有区别，所以补一个虚线落位框把它说成「往这儿放」的区域，再补第二行讲下一步。
   只管空态：03 拿 .zc-compose-empty 显示引擎报错，那个类不动。 */
.zc-compose-blank {
  flex-direction: column;
  gap: var(--sp-3);
  text-align: center;
}

.zc-compose-blank-frame {
  width: 108px;
  height: 108px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
}

.zc-compose-blank-lead {
  font-size: var(--fs-base);
  color: var(--text-muted);
}

.zc-compose-blank small { font-size: var(--fs-xs); color: var(--text-faint); }

.zc-compose-struct { margin-left: auto; }

/* 判定条 */
.zc-verdict {
  margin-top: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  min-height: 64px;
  background: rgba(184, 147, 90, 0.06);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  border-radius: var(--r-md);
  transition: border-color var(--dur-base) var(--ease-out),
              background var(--dur-base) var(--ease-out);
}

.zc-verdict.is-idle  { color: var(--text-faint); }
.zc-verdict.is-real  { border-left-color: var(--gold); background: rgba(201, 162, 39, 0.10); }
.zc-verdict.is-mine  { border-left-color: var(--accent); }
.zc-verdict.is-near  { border-left-color: var(--cinnabar-bright); background: rgba(176, 58, 46, 0.08); }
.zc-verdict.is-none  { border-left-color: var(--border-strong); color: var(--text-muted); }

.zc-verdict-badge {
  display: inline-block;
  font-size: var(--fs-xs);
  letter-spacing: 0.16em;
  color: var(--gold);
  border: 1px solid currentColor;
  border-radius: var(--r-sm);
  padding: 1px var(--sp-2);
  margin-bottom: var(--sp-2);
}
.zc-verdict.is-near .zc-verdict-badge { color: var(--cinnabar-bright); }

.zc-verdict-line { font-size: var(--fs-base); color: var(--text); }

.zc-verdict-char {
  font-family: var(--font-serif);
  font-size: var(--fs-2xl);
  color: var(--gold);
  font-weight: 400;
  line-height: 1;
  padding: 0 var(--sp-1);
}

.zc-verdict-tag {
  margin-left: var(--sp-2);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  padding: 1px var(--sp-2);
  vertical-align: middle;
}

.zc-verdict-relation {
  margin-top: var(--sp-2);
  font-family: var(--font-serif);
  font-size: var(--fs-lg);
  color: var(--text-muted);
  letter-spacing: 0.06em;
}

/* 自造字的免责声明 —— 学术红线在 UI 上的落点，别弱化它 */
.zc-verdict-warn {
  margin-top: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--cinnabar-bright);
}

/* ── 顶层外壳（五个模块）────────────────────── */

.zc-modbar {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin-bottom: var(--sp-5);
}

/* 模块页签比模式页签(01/02/03 里面的那一层)重一档 —— 两级页签挨在一起，
   长一样的话看不出哪个是"整个作品"、哪个是"这一块里的分法" */
.zc-modtabs button {
  font-size: var(--fs-base);
  padding: var(--sp-3) var(--sp-5);
  letter-spacing: 0.04em;
}

/* 在建的模块：压暗，但仍然可点（点进去是说明页，不是死链） */
.zc-modtabs button.is-todo { color: var(--text-faint); }
.zc-modtabs button.is-todo.is-active { color: var(--text-muted); }
.zc-modtabs-dot { color: var(--cinnabar); margin-left: 2px; vertical-align: super; font-size: 0.7em; }

.zc-todo-blurb {
  font-size: var(--fs-base);
  color: var(--text-muted);
  line-height: 1.9;
  margin: var(--sp-2) 0 var(--sp-4);
}

.zc-todo-list {
  margin: 0;
  padding-left: var(--sp-5);
  font-size: var(--fs-sm);
  color: var(--text-faint);
  line-height: 2.1;
}
.zc-todo-list li::marker { color: var(--bronze-600); }

/* ── 01 字源探索 ────────────────────────────── */

/* 两栏：左边字源卡(定宽)，右边交给 mode-write 自己再分「画布 | 笔画」
   三栏总宽在 1080 里刚好放得下，不用再缩画布 */
.zc-origin {
  display: grid;
  grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
  gap: var(--sp-5);
  align-items: start;
}
@media (max-width: 900px) {
  .zc-origin { grid-template-columns: 1fr; }
}

.zc-origin-glyph {
  background: linear-gradient(160deg, var(--ink-800), var(--ink-700));
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-3);
  margin-bottom: var(--sp-3);
}
.zc-origin-glyph svg { width: 100%; height: auto; display: block; aspect-ratio: 1 / 1; }

.zc-origin-head {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  flex-wrap: wrap;
}
.zc-origin-era {
  font-family: var(--font-serif);
  font-size: var(--fs-lg);
  color: var(--accent-bright);
  letter-spacing: 0.08em;
}
.zc-origin-period {
  font-size: var(--fs-xs);
  color: var(--text-faint);
  letter-spacing: 0.06em;
}

.zc-origin-note {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  line-height: 1.8;
  margin-top: var(--sp-2);
}

.zc-origin-cap {
  font-size: var(--fs-xs);
  color: var(--text-faint);
  line-height: 1.7;
  margin-top: var(--sp-2);
}

.zc-origin-credit {
  font-size: var(--fs-xs);
  color: var(--text-faint);
  line-height: 1.7;
  margin-top: var(--sp-3);
  padding-top: var(--sp-2);
  border-top: 1px solid var(--border);
}
.zc-origin-credit .warn { color: var(--cinnabar-bright); }

/* ── 03 千年演变 ─────────────────────────────── */

/* 主栏 = 画布 + 缩略图条，两条上下叠。缩略图条自己带 margin-top */
.zc-evo-main { min-width: 0; }

/* ── 04 汉字挑战 ─────────────────────────────── */

/* 单栏居中。04 不需要侧栏 —— 题干、作答、解析是一条从上往下的线，
   摆成两栏反而要眼睛来回找「现在该看哪」 */
.zc-quiz { max-width: 720px; margin: 0 auto; }

.zc-quiz-head {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--text-muted);
  margin-bottom: var(--sp-2);
}
.zc-quiz-step { color: var(--text-faint); letter-spacing: 0.06em; }
.zc-quiz-kind {
  font-family: var(--font-serif);
  font-size: var(--fs-base);
  color: var(--accent-bright);
  letter-spacing: 0.1em;
}
/* 得分推到最右边 —— margin-left:auto 比 justify-content 稳，
   中间那个题型名长度会变，用 space-between 的话它一长就挤在一起 */
.zc-quiz-score { margin-left: auto; color: var(--text-faint); }

.zc-quiz-bar {
  height: 2px;
  background: var(--border);
  border-radius: 1px;
  overflow: hidden;
  margin-bottom: var(--sp-4);
}
.zc-quiz-bar i {
  display: block;
  height: 100%;
  background: var(--bronze-500);
  transition: width var(--dur-base) var(--ease-out);
}

.zc-quiz-ask {
  font-size: var(--fs-lg);
  line-height: 1.8;
  color: var(--text);
  margin: 0 0 var(--sp-4);
}

/* ① 待认的古文字形：给个和字源卡同款的内嵌底，让它像一件展品 */
.zc-quiz-glyph {
  background: linear-gradient(160deg, var(--ink-800), var(--ink-700));
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.zc-quiz-glyph svg { width: 100%; height: auto; max-width: 220px; display: block; margin: 0 auto; aspect-ratio: 1 / 1; }

/* ② 构件：和 02 里的构件片同一套观感 */
.zc-quiz-parts {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-bottom: var(--sp-4);
}
.zc-quiz-part {
  font-family: var(--font-serif);
  font-size: var(--fs-3xl);
  line-height: 1;
  color: var(--glyph-ink);
  background: linear-gradient(160deg, var(--ink-700), var(--ink-800));
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
}

/* ③ 字理：引用块的竖线用朱砂，和印章呼应 */
.zc-quiz-relation {
  margin: 0 0 var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border-left: 2px solid var(--cinnabar);
  background: rgba(176, 58, 46, 0.06);
  font-family: var(--font-serif);
  font-size: var(--fs-xl);
  line-height: 1.7;
  color: var(--paper-100);
  letter-spacing: 0.04em;
}

/* ④ 排序题：一排格子 */
.zc-quiz-order {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.zc-quiz-tile {
  width: 108px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-raised);
  padding: var(--sp-2);
  transition: border-color var(--dur-fast), background var(--dur-fast);
}
.zc-quiz-tile svg { width: 100%; height: auto; display: block; aspect-ratio: 1 / 1; }
.zc-quiz-tile-cap {
  font-size: var(--fs-xs);
  line-height: 1.5;
  color: var(--text-faint);
  text-align: center;
  min-height: 2.6em;
  margin-top: var(--sp-1);
}
.zc-quiz-tile.is-ok { border-color: var(--gold); background: rgba(201, 162, 39, 0.08); }
.zc-quiz-tile.is-ok .zc-quiz-tile-cap { color: var(--gold); }
.zc-quiz-tile.is-no { border-color: var(--cinnabar); background: rgba(176, 58, 46, 0.08); }
.zc-quiz-tile.is-no .zc-quiz-tile-cap { color: var(--cinnabar-bright); }

/* 键盘光标（排序题）。← → 换的是「光标那一格」，不给可见标记的话键盘就没法用 ——
   用户看不出按下去改的会是哪一格。只在未作答时出现，所以跟 is-ok / is-no 不冲突。 */
.zc-quiz-tile.is-cursor {
  border-color: var(--gold);
  box-shadow: 0 0 0 2px rgba(201, 162, 39, 0.32);
}

.zc-quiz-tile-move { display: flex; gap: var(--sp-1); margin-top: var(--sp-1); }
.zc-quiz-tile-move .zc-btn {
  flex: 1;
  padding: 2px 0;
  font-size: var(--fs-xs);
  line-height: 1.4;
}

/* 选项：两列。四项排一行的话中文选项会窄得换行，两列刚好 */
.zc-quiz-options {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
@media (max-width: 560px) {
  .zc-quiz-options { grid-template-columns: 1fr; }
}

.zc-quiz-opt {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 64px;
  padding: var(--sp-3);
  font: inherit;
  color: var(--text);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  cursor: pointer;
  transition: border-color var(--dur-fast), background var(--dur-fast), transform var(--dur-fast);
}
.zc-quiz-opt:hover:not([disabled]) { border-color: var(--border-strong); transform: translateY(-1px); }
.zc-quiz-opt[disabled] { cursor: default; }
.zc-quiz-opt-g {
  font-family: var(--font-serif);
  font-size: var(--fs-2xl);
  line-height: 1.1;
}
/* 构件组合的选项：构件之间给个明显的缝，别让人看成「一个月字旁的生僻字」 */
.zc-quiz-opt .zc-quiz-opt-g + .zc-quiz-opt-g { margin-left: var(--sp-2); }
.zc-quiz-opt.is-picked { border-color: var(--accent); }
.zc-quiz-opt.is-ok { border-color: var(--gold); background: rgba(201, 162, 39, 0.1); color: var(--gold); }
.zc-quiz-opt.is-no { border-color: var(--cinnabar); background: rgba(176, 58, 46, 0.1); color: var(--cinnabar-bright); }

.zc-quiz-submit {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.zc-quiz-tip { font-size: var(--fs-xs); color: var(--text-faint); }

/* 解析 */
.zc-quiz-feedback {
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  border-radius: var(--r-md);
  padding: var(--sp-4);
  background: var(--surface);
}
.zc-quiz-feedback.is-ok { border-left-color: var(--gold); }
.zc-quiz-feedback.is-no { border-left-color: var(--cinnabar); }
.zc-quiz-mark {
  font-family: var(--font-serif);
  font-size: var(--fs-lg);
  letter-spacing: 0.1em;
  margin-bottom: var(--sp-2);
}
.zc-quiz-feedback.is-ok .zc-quiz-mark { color: var(--gold); }
.zc-quiz-feedback.is-no .zc-quiz-mark { color: var(--cinnabar-bright); }
.zc-quiz-answer { font-size: var(--fs-sm); color: var(--text-muted); margin: 0 0 var(--sp-2); }
.zc-quiz-answer b { font-family: var(--font-serif); font-size: var(--fs-lg); color: var(--text); }
.zc-quiz-explain {
  font-size: var(--fs-sm);
  line-height: 1.9;
  color: var(--text-muted);
  margin: 0 0 var(--sp-3);
}

/* 成绩 */
.zc-quiz-final {
  font-family: var(--font-serif);
  font-size: var(--fs-3xl);
  color: var(--accent-bright);
  line-height: 1;
  margin-bottom: var(--sp-3);
}
.zc-quiz-final span {
  font-size: var(--fs-lg);
  color: var(--text-faint);
  margin-left: var(--sp-2);
}
.zc-quiz-verdict {
  font-size: var(--fs-base);
  line-height: 1.9;
  color: var(--text-muted);
  margin: 0 0 var(--sp-4);
}
