/* ============================================================================
   pages-identity.css —— 原 pages.css 的第 4/6 段（2026-09-19 拆分）

   原文件 3,696 行，把六种板块的样式装在了一起（《模型档位与代码质量_操作准则》
   §5 点名的技术债）。现按文件自己的 ===== 横幅拆成六段，index.html 按
   原顺序引入 —— 层叠顺序与拆分前完全一致（拆分脚本做过逐行相等校验）：

     1 pages-login.css → 2 pages-store.css → 3 pages-practice.css
     → 4 pages-identity.css → 5 pages-practice-fx.css → 6 pages-learn.css

   本段：编号与好友 + 在线状态 + 单元报告
   ============================================================================ */

/* ===========================================================================
   编号与好友（views/pickid.js + views/friends.js）
   ---------------------------------------------------------------------------
   两块界面共用的东西其实只有「一串数字」这一个母题：
   选号页里候选是数字、好友页里编号是数字 —— 所以数字一律用等宽字体 + 字距，
   学生一眼就能把 205703 和 205730 分开。这不是装饰，是可读性。
   =========================================================================== */

.copy-sink {
  position: fixed;
  left: -9999px;
  top: 0;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* ---------- 选号页 ---------- */

.pk-wrap { display: flex; flex-direction: column; gap: var(--gap); }

.pk-hero {
  display: flex;
  gap: 20px;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  padding: 20px;
}
.pk-hero-l { flex: 1 1 320px; min-width: 0; }
/* 右栏放「还没选」的编号预览框：不能被压扁，也不跟着拉伸 */
.pk-hero-r { flex: 0 0 auto; display: flex; align-items: center; }
.pk-hero-l h2 { margin: 0 0 8px; font-size: var(--fs-xl); color: var(--t-bright); }
.pk-hero-l p { margin: 0 0 6px; color: var(--t-primary); line-height: 1.6; }
.pk-idbox {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 14px 26px;
  border: 1px dashed var(--c-line);
  border-radius: var(--r-md);
  background: var(--c-input);
}
.pk-idbox .dots {
  font-size: 26px;
  letter-spacing: 6px;
  color: var(--t-dim);
  font-family: ui-monospace, Consolas, Menlo, monospace;
}
.pk-idbox i { font-style: normal; font-size: var(--fs-xs); color: var(--t-dim); }

.pk-step { padding: 18px 20px 20px; }
.pk-step.is-idle { display: none; }

.pk-step-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
  font-size: var(--fs-lg);
  color: var(--t-bright);
}
.pk-step-head .n {
  flex: 0 0 auto;
  width: 24px; height: 24px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--c-accent-deep);
  color: var(--t-bright);
  font-size: var(--fs-xs);
}

.pk-digitblock { margin-bottom: 14px; }
.pk-digitlabel {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 8px;
}
.pk-digitlabel b { color: var(--t-primary); font-weight: 600; }
.pk-digitlabel span { color: var(--t-dim); font-size: var(--fs-xs); }

.pk-digitrow { display: flex; flex-wrap: wrap; gap: 8px; }
.pk-chip {
  width: 46px; height: 46px;
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  background: var(--c-input);
  color: var(--t-primary);
  font-size: 19px;
  font-family: ui-monospace, Consolas, Menlo, monospace;
  cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.pk-chip:hover { background: var(--c-hover); }
.pk-chip.is-on {
  background: var(--c-accent-deep);
  border-color: var(--c-accent);
  color: var(--t-bright);
}
.pk-chip.is-blocked { opacity: .4; }

.pk-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 6px;
}
.pk-batch-hint { color: var(--t-dim); font-size: var(--fs-xs); }

.pk-batch-meta {
  margin-bottom: 12px;
  color: var(--t-muted);
  font-size: var(--fs-sm);
}
.pk-batch-meta b { color: var(--c-accent); }

.pk-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 8px;
}
.pk-grid-empty { grid-column: 1 / -1; padding: 14px 0; }

.pk-cand {
  min-height: var(--tap);
  padding: 10px 6px;
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  background: var(--c-input);
  color: var(--t-bright);
  font-size: 17px;
  letter-spacing: 1.5px;
  font-family: ui-monospace, Consolas, Menlo, monospace;
  cursor: pointer;
  transition: background .12s, border-color .12s, transform .12s;
}
.pk-cand:hover { background: var(--c-hover); border-color: var(--c-accent); }
.pk-cand.is-sel {
  background: var(--c-accent-deep);
  border-color: var(--c-accent);
  transform: translateY(-1px);
}

.pk-confirmbar {
  position: sticky;
  bottom: 8px;
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
  padding: 12px 14px;
  border: 1px solid var(--c-accent);
  border-radius: var(--r-md);
  background: var(--c-card-hi);
  box-shadow: 0 8px 22px rgba(0, 0, 0, .35);
}
.pk-bar-num {
  font-size: 22px;
  letter-spacing: 2px;
  color: var(--t-bright);
  font-family: ui-monospace, Consolas, Menlo, monospace;
}
.pk-confirmbar .grow { flex: 1 1 auto; }

.pk-modal-num {
  margin: 6px 0 10px;
  font-size: 36px;
  letter-spacing: 6px;
  text-align: center;
  color: var(--c-accent);
  font-family: ui-monospace, Consolas, Menlo, monospace;
}

.pk-done {
  padding: 34px 20px 30px;
  text-align: center;
}
.pk-done-check {
  width: 52px; height: 52px;
  margin: 0 auto 14px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--c-green-b);
  color: var(--t-bright);
  font-size: 26px;
}
.pk-done h2 { margin: 0 0 16px; color: var(--t-bright); font-size: var(--fs-xl); }
.pk-done p { margin: 0 0 8px; color: var(--t-primary); line-height: 1.6; }
.pk-done .pk-actions { justify-content: center; margin-top: 20px; }

.pk-bignum {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin: 0 0 18px;
}
.pk-bignum .d {
  min-width: 54px;
  padding: 12px 0;
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  background: var(--c-input);
  color: var(--c-accent);
  font-size: 34px;
  font-family: ui-monospace, Consolas, Menlo, monospace;
}

/* 未选编号的常驻提示条，沿用首次改密那条的骨架，只换个强调色 */
.pwd-banner.is-pickid { border-left-color: var(--c-accent); }

/* ---------- 好友页 ---------- */

.fr-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  padding: 16px 20px;
  margin-bottom: var(--gap);
}
.fr-me { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.fr-me .lbl { color: var(--t-dim); font-size: var(--fs-xs); }
.fr-me .num {
  font-size: 28px;
  letter-spacing: 3px;
  color: var(--c-accent);
  font-family: ui-monospace, Consolas, Menlo, monospace;
}
.fr-me .num.is-none { color: var(--t-dim); font-size: 20px; letter-spacing: 0; }

.fr-stats { display: flex; gap: 22px; }
.fr-stat { text-align: center; }
.fr-stat b {
  display: block;
  font-size: 24px;
  color: var(--t-bright);
  line-height: 1.1;
}
.fr-stat span { font-size: var(--fs-xs); color: var(--t-dim); }

.fr-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: var(--gap);
  border-bottom: 1px solid var(--c-line);
}
.fr-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--tap);
  padding: 0 14px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--t-muted);
  font-size: var(--fs-lg);
  cursor: pointer;
}
.fr-tab:hover { color: var(--t-primary); }
.fr-tab.is-active {
  color: var(--t-bright);
  border-bottom-color: var(--c-accent);
}
.fr-dot {
  min-width: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--c-accent);
  color: var(--t-ink);
  font-size: var(--fs-xs);
  text-align: center;
}

.fr-body { min-height: 160px; }
.fr-sechead { margin: 18px 0 10px; }
.fr-sechead:first-child { margin-top: 0; }
.fr-sechint { margin-left: auto; font-size: var(--fs-xs); }

.fr-list {
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  overflow: hidden;
}
.fr-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  min-height: var(--tap);
  background: var(--c-card);
  border-bottom: 1px solid var(--c-line-soft);
}
.fr-row:last-child { border-bottom: 0; }
.fr-row:hover { background: var(--c-card-hi); }
.fr-av { flex: 0 0 auto; line-height: 0; }
.fr-info { flex: 1 1 auto; min-width: 0; }
.fr-name {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--t-primary);
  font-size: var(--fs-lg);
  flex-wrap: wrap;
}
.fr-sub {
  margin-top: 2px;
  color: var(--t-dim);
  font-size: var(--fs-xs);
  letter-spacing: 1px;
  font-family: ui-monospace, Consolas, Menlo, monospace;
}
.fr-sub.is-none { color: var(--c-gold); letter-spacing: 0; font-family: inherit; }
.fr-act { flex: 0 0 auto; display: flex; gap: 8px; align-items: center; }
.fr-state { color: var(--t-dim); font-size: var(--fs-sm); }
.fr-state.is-ok { color: var(--c-green-a); }
.fr-state.is-block { color: var(--c-gold); }

.fr-find { display: flex; gap: 10px; flex-wrap: wrap; }
.fr-find .input {
  flex: 1 1 220px;
  letter-spacing: 4px;
  font-family: ui-monospace, Consolas, Menlo, monospace;
  font-size: 17px;
}
.fr-find-result { margin-top: 16px; }
.fr-tip { margin-top: 12px; font-size: var(--fs-xs); line-height: 1.6; }

.fr-need {
  padding: 34px 24px 30px;
  text-align: center;
}
.fr-need .icon-wrap {
  width: 44px; height: 44px;
  margin: 0 auto 12px;
  color: var(--c-accent);
  display: block;
}
.fr-need h2 { margin: 0 0 12px; color: var(--t-bright); font-size: var(--fs-xl); }
.fr-need p { margin: 0 auto 8px; max-width: 480px; color: var(--t-primary); line-height: 1.6; }
.fr-need .btn-lg { margin-top: 18px; }

@media (max-width: 620px) {
  .pk-bignum .d { min-width: 40px; font-size: 26px; }
  .pk-grid { grid-template-columns: repeat(auto-fill, minmax(78px, 1fr)); }
  .fr-head { align-items: flex-start; }
  .fr-row { flex-wrap: wrap; }
  .fr-act { width: 100%; justify-content: flex-end; }
  .fr-me .num { font-size: 24px; }
}

/* ---------- 「正在练」在线状态（好友页）----------
   只给「词本 + 单元」，绝不给实时分数 —— 这是老师定的红线。 */
.fr-presence-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 12px 0 4px;
  padding: 9px 14px;
  background: var(--c-card);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
}

.fr-presence-btn { flex: 0 0 auto; }

.fr-presence-txt {
  color: var(--t-muted);
  font-size: var(--fs-sm);
  margin-right: auto;
}

/* 行内徽标：默认空（不占视觉），有状态才亮起来 */
.fr-live {
  margin-top: 3px;
  font-size: var(--fs-xs);
  color: var(--t-dim);
  min-height: 1em;
}

.fr-live.is-on { color: #a6d95c; }


/* ═══════════════════════════════════════════════════════════════════════
   老师 2026-09-19 练习手感件：
   确认提交（绿）/ 错误分级色 / 庆祝彩纸 / 跳过条 / 单元勾选 / 进度行
   ═══════════════════════════════════════════════════════════════════════ */

/* ---- 绿色确认提交按钮 ---- */
.btn-confirm {
  background: linear-gradient(90deg, var(--c-green-a), var(--c-green-b));
  border: 1px solid var(--c-green-b);
  color: #fff;
}

.btn-confirm:hover { filter: brightness(1.12); }
.btn-confirm:disabled {
  filter: grayscale(0.7) brightness(0.75);
  cursor: not-allowed;
}

.pc-hint-green { color: #a6d95c; }

/* ---- 题面旁的发音提示按钮（限频冷却态） ---- */
.pc-hint-audio { margin-top: 8px; }

.pc-speak.is-cd {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ---- 反馈条：庆祝 / 三级错误 / 跳过 ----
   is-w1 绿 = 只错 1–2 个字母；is-w2 橙 = 没过半；is-w3 红 = 过半。
   红牌只给错得多的词 —— 错一两个字母不值得挨红牌。 */
.pc-fb.is-win {
  background: rgba(117, 176, 34, 0.16);
  border-left: 3px solid var(--c-green-a);
}

.pc-fb.is-win .pc-fb-icon { color: #a6d95c; }

.pc-fb.is-w1 {
  background: rgba(117, 176, 34, 0.10);
  border-left: 3px solid var(--c-green-a);
}

.pc-fb.is-w2 {
  background: rgba(212, 175, 55, 0.12);
  border-left: 3px solid var(--c-gold);
}

.pc-fb.is-w3 {
  background: rgba(192, 57, 43, 0.15);
  border-left: 3px solid var(--c-red-a);
}

.pc-fb.is-w1 .pc-fb-icon { color: #a6d95c; }
.pc-fb.is-w2 .pc-fb-icon { color: var(--c-gold); }
.pc-fb.is-w3 .pc-fb-icon { color: #ef8b8b; }

.pc-fb.is-skip {
  background: var(--c-input);
  border-left: 3px solid var(--c-line);
}

/* 槽位行跟反馈条同色 */
.pc-slots.is-w0 .pc-slot { border-bottom-color: var(--c-green-a); }
.pc-slots.is-w1 .pc-slot { border-bottom-color: var(--c-green-a); }
.pc-slots.is-w2 .pc-slot { border-bottom-color: var(--c-gold); }
.pc-slots.is-w3 .pc-slot { border-bottom-color: var(--c-red-a); }

/* ---- 庆祝彩纸（1.8 秒自拆，零依赖 CSS 动画） ---- */
.pc-stage { position: relative; }
.pc-result-wrap, .pc-quiz { position: relative; }

.pc-confetti {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 5;
}

.pc-confetti i {
  position: absolute;
  top: -12px;
  width: 9px;
  height: 14px;
  border-radius: 2px;
  opacity: 0.95;
  animation: pc-confetti-fall linear forwards;
}

@keyframes pc-confetti-fall {
  0% { transform: translateY(-10px) rotate(0deg); }
  100% { transform: translateY(105vh) rotate(540deg); }
}

/* ---- 跳过条 ---- */
.pc-skip-bar {
  display: flex;
  justify-content: center;
  margin: 6px 0 14px;
}

.pc-skip {
  color: var(--t-muted);
  border-color: var(--c-line);
}

.pc-skip:hover { color: var(--t-primary); }

/* ---- 词本页：单元勾选 + 底部开始条 ---- */
/* 选中只靠框体：绿边 + 内层绿描边 + 淡绿底 + 一点外发光。
   inset 阴影做的那层描边不参与布局，卡片不会抖。 */
.pc-unit.is-picked {
  border-color: var(--c-green-a);
  background: rgba(117, 176, 34, 0.14);
  box-shadow: inset 0 0 0 1px var(--c-green-a), 0 0 0 3px rgba(117, 176, 34, 0.12);
}

/* 独占锁：局中这一页的单元卡也不可改（与词本页 .lib-units.is-locked 同一口径）。
   ★ 同样要写在 is-picked 之后 + :not(.is-picked)：
     hover 规则的选择器级别更高，会把已选中的绿边盖掉。 */
.pc-units.is-locked .pc-unit { cursor: not-allowed; }
.pc-units.is-locked .pc-unit:not(.is-picked):hover {
  background: var(--c-card);
  border-color: transparent;
}

.pc-pick-bar {
  position: sticky;
  bottom: 14px;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  background: var(--c-card-hi);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
}

.pc-pick-info {
  color: var(--t-primary);
  font-size: var(--fs-md);
  margin-right: auto;
}

/* ---- 结算：进度行 ---- */
.pc-progress-note {
  margin: 14px 0;
  padding: 12px 16px;
  background: var(--c-card);
  border: 1px solid var(--c-line);
  border-left: 3px solid var(--c-green-a);
  border-radius: var(--r-md);
  color: var(--t-primary);
  font-size: var(--fs-md);
}

/* ═══════════════════════════════════════════════════════════════════════
   老师 2026-09-19 主控页（库详情）：单元进度 + 模式 + 绿/蓝开始按钮
   绿 = 可以开始；蓝 = 正在运行中。这一对颜色是全套词本
   「学习 / 练习 / 挑战」的开始与结束语言，别在别处另起一套。
   ═══════════════════════════════════════════════════════════════════════ */

.lib-run-head {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.lib-run-head h1 { margin: 0 auto 0 0; }

.btn-run {
  background: linear-gradient(90deg, var(--c-green-a), var(--c-green-b));
  border: 1px solid var(--c-green-b);
  color: #fff;
  min-width: 132px;
}

.btn-run:hover { filter: brightness(1.12); }

/* 运行中：蓝色 + 呼吸感，明确告诉学生「这一局还没结束」 */
.btn-run.is-running {
  background: linear-gradient(90deg, var(--c-accent), var(--c-accent-dim));
  border-color: var(--c-accent-dim);
  color: #0e1621;
  cursor: default;
  animation: btn-run-pulse 2.4s ease-in-out infinite;
}

@keyframes btn-run-pulse {
  0%, 100% { box-shadow: 0 0 0 rgba(102, 192, 244, 0); }
  50% { box-shadow: 0 0 14px rgba(102, 192, 244, 0.55); }
}

/* ---- 模式 ---- */
.lib-modes {
  display: flex;
  align-items: stretch;
  gap: 10px;
  margin: 14px 0 6px;
  flex-wrap: wrap;
}

.lib-modes-l {
  align-self: center;
  color: var(--t-dim);
  font-size: var(--fs-md);
}

.lib-mode {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 190px;
  padding: 10px 14px;
  background: var(--c-card);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  text-align: left;
  cursor: pointer;
}

.lib-mode .t { color: var(--t-bright); font-size: var(--fs-lg); }
.lib-mode .h { color: var(--t-dim); font-size: var(--fs-xs); line-height: 1.4; }

.lib-mode.is-on {
  border-color: var(--c-green-a);
  background: rgba(117, 176, 34, 0.10);
}

.lib-mode.is-on .t { color: #a6d95c; }
.lib-mode.is-soon { opacity: 0.55; cursor: not-allowed; }

/* 独占锁（老师 2026-09-19）：局中模式一律锁住。
   压暗只是提示「现在不能点」，真正的拦阻在 JS 里 —— 点击会被拦下并说明原因。
   刻意不用真 disabled：真禁用的按钮给不出理由，学生只会以为坏了。
   单元那边的锁在 .lib-unit.is-picked 之后（见下文），因为要「选中态照旧」。 */
.lib-mode.is-locked { opacity: 0.5; cursor: not-allowed; }

/* ---- 单元网格 ---- */
.lib-units {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 10px;
  margin: 14px 0;
}

/* 勾选规则提示：多选只在挑战模式开放，这句话要写在网格上方，别让学生猜 */
.lib-units-hint {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 14px 0 -4px;
  font-size: var(--fs-xs);
}

.lib-units-rule { color: var(--t-dim); }
.lib-units-pick { color: #a6d95c; font-weight: 600; }

.lib-unit {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--c-card);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  text-align: left;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, box-shadow 0.12s;
}

.lib-unit:hover { background: var(--c-card-hi); }

/* 选中与否只看框体（老师 2026-09-19：卡里不再写「✓ 已选」，
   那两三个字会把卡里的其它文字挤变形）。
   所以这里的绿要给足：粗一点的绿边 + 一层淡绿底 + 一点外发光，
   让「我选了这个」在 32 张卡里一眼跳出来。 */
/*   这里的「粗边」用 inset 阴影而不是 border-width：改 border 宽度会让卡片
      尺寸跳 1px，32 张卡跟着抖一下（看着像闪屏）。inset 不参与布局，稳。 */
.lib-unit.is-picked {
  border-color: var(--c-green-a);
  background: rgba(117, 176, 34, 0.14);
  box-shadow: inset 0 0 0 1px var(--c-green-a), 0 0 0 3px rgba(117, 176, 34, 0.12);
}

/* 独占锁：局中单元不可改。要写在这里（is-picked 之后）并且 :not(.is-picked)——
   否则这条 hover 规则（4 级）会盖掉 is-picked 的绿边框（2 级），
   局中被选中的卡一悬停就褪色，学生会以为选择被取消了。
   只有「没被选中」的卡才撤掉悬停高亮；已选中的绿照旧亮着。 */
.lib-units.is-locked .lib-unit { cursor: not-allowed; }
.lib-units.is-locked .lib-unit:not(.is-picked):hover {
  background: var(--c-card);
  border-color: var(--c-line);
}

.lib-unit-no {
  flex: 0 0 26px;
  color: var(--t-dim);
  font-variant-numeric: tabular-nums;
}

.lib-unit-body { flex: 1 1 auto; display: flex; flex-direction: column; gap: 3px; }
.lib-unit-title { color: var(--t-primary); font-size: var(--fs-md); }
.lib-unit-sub { color: var(--t-dim); font-size: var(--fs-xs); }

.lib-unit-bar {
  display: block;
  height: 4px;
  background: var(--c-input);
  border-radius: 2px;
  overflow: hidden;
}

.lib-unit-fill {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--c-green-a), var(--c-green-b));
}

.lib-unit-state {
  flex: 0 0 auto;
  font-size: var(--fs-xs);
  color: var(--t-dim);
}

.lib-unit-state.is-going { color: var(--c-accent); }
.lib-unit-state.is-done { color: #a6d95c; }
.lib-unit-state.is-perfect { color: var(--c-gold); }

/* playing 窗口收摊后（close() 被浏览器拦下时才会出现）：
   一张静态卡片，告诉学生手动点 ×，绝不再往平台页面里跳。 */
.pc-win-done {
  max-width: 520px;
  margin: 60px auto;
  padding: 32px 24px;
  text-align: center;
}

.pc-win-done-big {
  font-size: var(--fs-xl);
  color: var(--t-bright);
  margin-bottom: 10px;
}

.pc-win-done p {
  color: var(--t-muted);
  font-size: var(--fs-md);
  line-height: 1.6;
}

/* (原来的 .lib-unit-go「✓ 已选 / 选择」已删除 —— 它挤掉了卡里的其它文字。
   选中状态现在只由 .lib-unit.is-picked 的框体负责。) */

/* ---- 底部开始条 ---- */
.lib-run-bar {
  position: sticky;
  bottom: 14px;
  z-index: 4;
  padding: 12px 16px;
  background: var(--c-card-hi);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
}

.lib-run-info { color: var(--t-primary); font-size: var(--fs-md); }
.lib-run-bar.is-warn { border-color: var(--c-gold); }
.lib-run-bar.is-warn .lib-run-info { color: #d8bd6a; }

/* ---- playing 窗口里的模式条 ---- */
.pc-mode-note {
  margin: 10px 0;
  padding: 10px 14px;
  background: var(--c-card);
  border: 1px solid var(--c-line);
  border-left: 3px solid var(--c-green-a);
  border-radius: var(--r-md);
  color: var(--t-primary);
  font-size: var(--fs-md);
}

.pc-mode-note.is-assess { border-left-color: var(--c-accent); }

/* ═══════════════════════════════════════════════════════════════════════
   老师 2026-09-19 · 逐字母检验（动画落在字母框上，不再弹提示窗）
   ═══════════════════════════════════════════════════════════════════════ */

/* 结论只留一行：不再是一闪而过的卡片 */
.pc-verify {
  margin-top: 18px;
  padding: 4px 2px;
}

.pc-verify .pc-fb-main { font-size: var(--fs-lg); }
.pc-verify.is-win .pc-fb-icon { color: #a6d95c; }
.pc-verify.is-w1 .pc-fb-icon { color: #a6d95c; }
.pc-verify.is-w2 .pc-fb-icon { color: var(--c-gold); }
.pc-verify.is-w3 .pc-fb-icon { color: #ef8b8b; }
.pc-verify.is-bad .pc-fb-icon { color: #ef8b8b; }
.pc-verify.is-skip .pc-fb-text { color: var(--t-muted); }
/* ★ S15：判分时机设成「完成以后统计对错」时，答题屏**一个字都不说对错** ——
   这一行只说「记下了」，所以它必须长得**没有任何褒贬色彩**：
   不用绿（像对了）、不用红/金（像错了），就用最淡的那一档，与「跳过」同一族。 */
.pc-verify.is-quiet .pc-fb-text { color: var(--t-muted); }

/* 键盘输入模式提交后现造的槽位行（只读） */
.pc-slots.is-static { margin-top: 14px; }

/* 逐格检验：绿 = 位置对，红 = 错（并把正确字母填进来）；
   扫完保持颜色，学生可以盯着看全了再走。 */
.pc-slot.is-hit {
  border-bottom-color: var(--c-green-a);
  color: #a6d95c;
  background: rgba(117, 176, 34, 0.10);
}

.pc-slot.is-miss {
  border-bottom-color: var(--c-red-a);
  color: #ef8b8b;
  background: rgba(192, 57, 43, 0.12);
}

/* 「还没扫到」的这一格：一圈很淡的待查标记。
   一眼看得出扫描是从左往右在走，而不是页面卡住了。 */
.pc-slot.is-scan {
  border-color: var(--c-line);
  color: var(--t-muted);
}

.pc-slot.is-scan .pc-slot-ch { opacity: 0.45; }

/* 扫到这一格时的一次性高亮 */
.pc-slot.is-flash {
  transform: translateY(-4px) scale(1.14);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35);
  transition: transform 0.16s ease, box-shadow 0.16s ease;
}

/* 判定进行中：把槽位和词库都锁住，手再快也改不了答案 ——
   判定期间改输入没有意义，只会引出「我明明改对了为什么算我错」这种扯皮。
   is-judging 同时挂在 pc-slots 和 tiles 两个容器上，所以这里写成后代选择器。 */
.is-judging .pc-slot { pointer-events: none; }

.is-judging .pc-tile {
  pointer-events: none;
  opacity: 0.4;
}

/* ---- 单元卡上的「报告」按钮 ---- */
.lib-unit-report {
  flex: 0 0 auto;
  min-height: 26px;
  padding: 0 10px;
  background: transparent;
  border: 1px solid var(--c-line);
  border-radius: var(--r-sm);
  color: var(--t-muted);
  font-size: var(--fs-xs);
  cursor: pointer;
}

.lib-unit-report:hover { color: var(--c-accent); border-color: var(--c-accent-dim); }

/* ---- 单元阶段报告 ---- */
.rep-group-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 10px;
}

.rep-group-name { font-size: var(--fs-lg); color: var(--t-bright); }
.rep-group-n { color: var(--t-dim); font-size: var(--fs-sm); }
.rep-group-note { margin-left: auto; color: var(--t-dim); font-size: var(--fs-xs); }

.rep-group.is-first .rep-group-name { color: #a6d95c; }
.rep-group.is-tiger .rep-group-name { color: var(--c-accent); }
.rep-group.is-wall .rep-group-name { color: #ef8b8b; }
.rep-group.is-fresh .rep-group-name { color: var(--t-muted); }

.rep-chips { display: flex; flex-wrap: wrap; gap: 6px; }

.rep-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 5px 10px;
  background: var(--c-input);
  border: 1px solid var(--c-line);
  border-radius: var(--r-sm);
}

.rep-chip .w { color: var(--t-primary); font-size: var(--fs-md); }
.rep-chip .m { color: var(--t-dim); font-size: var(--fs-xs); }

.rep-empty { color: var(--t-dim); font-size: var(--fs-sm); }



/* ---------- 选号页的两个弹窗（老师 2026-09-26） ---------- */
.modal .pk-modal-line {
  margin: 0 0 8px;
  color: var(--t-primary);
  font-size: var(--fs-md);
  line-height: 1.7;
}
.modal .pk-modal-line:last-of-type { margin-bottom: 2px; }
