/* ============================================================
   app.css —— 页面级布局
   ------------------------------------------------------------
   顺序与页面对应：首页 → 页头 → 筛选 → 列表 → 题卡 → 作答控件 →
   判分回顾 → 结果摘要 → 详情 → 答题页 → 记录 → 管理/录入 →
   选题篮 → 登录。
   组件类名与 JS 里的字面量一一对应，改样式时用 grep 反查最方便。
   ============================================================ */

/* ---------------- 首页 ---------------- */

.hero {
  padding: 30px 28px 28px;
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 140% at 100% 0%, #eaf1ff 0%, rgba(234, 241, 255, 0) 58%),
    linear-gradient(180deg, var(--surface), var(--surface));
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
}
.hero-title {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -.3px;
  line-height: 1.3;
}
.hero-sub {
  margin-top: 10px;
  max-width: 640px;
  color: var(--text-2);
  font-size: 14.5px;
  line-height: 1.75;
}
.hero-actions { margin-top: 20px; display: flex; flex-wrap: wrap; gap: 10px; }

.home-block { margin-top: 34px; }
.block-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 16.5px;
  font-weight: 650;
  margin-bottom: 14px;
}
.block-title::before {
  content: "";
  width: 3px;
  height: 16px;
  border-radius: 2px;
  background: var(--brand);
}

.home-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 12px;
}
.home-stat {
  padding: 16px 18px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
}
.home-stat-value {
  font-size: 26px;
  font-weight: 700;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  color: var(--brand-dark);
}
.home-stat-label { margin-top: 3px; font-size: 12.5px; color: var(--text-3); }

.home-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  align-items: start;
  gap: 12px;
  margin-top: 12px;
}
.home-col {
  padding: 16px 18px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
}
.col-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
  margin-bottom: 12px;
  letter-spacing: .2px;
}

.dist { display: flex; flex-direction: column; gap: 9px; }
.dist-row {
  display: grid;
  grid-template-columns: 76px 1fr 40px;
  align-items: center;
  gap: 10px;
  font-size: 13px;
}
.dist-key { color: var(--text-2); white-space: nowrap; }
.dist-bar {
  height: 9px;
  border-radius: 999px;
  background: var(--surface-3);
  overflow: hidden;
}
.dist-bar > i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--brand), #6f9bfb);
  transition: width .4s ease;
}
.dist-val {
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--text-3);
}

.entries {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 12px;
}
.entry {
  position: relative;
  display: block;
  padding: 16px 18px 16px 22px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
  color: var(--text);
  overflow: hidden;
  transition: transform .16s, box-shadow .16s, border-color .16s;
}
.entry::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background: var(--brand);
}
.entry:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-2);
  border-color: #cdd9ee;
}
.entry-title { font-size: 15px; font-weight: 600; }
.entry-sub { margin-top: 3px; font-size: 12.5px; color: var(--text-3); }
.entry.e-blue::before { background: var(--brand); }
.entry.e-teal::before { background: var(--teal); }
.entry.e-amber::before { background: var(--warn); }
.entry.e-purple::before { background: var(--purple); }
.entry.e-gray::before { background: #8b94a3; }

.rec-list { display: flex; flex-direction: column; gap: 10px; }
.rec-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 17px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  transition: border-color .16s, box-shadow .16s;
}
.rec-item:hover { border-color: #cdd9ee; box-shadow: var(--shadow-1); }
.rec-main { display: flex; align-items: center; gap: 14px; flex: 1 1 auto; min-width: 0; }
.rec-score {
  display: flex;
  align-items: baseline;
  gap: 1px;
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
}
.rec-score strong { font-size: 21px; font-weight: 700; color: var(--brand-dark); }
.rec-score span { font-size: 12.5px; color: var(--text-3); }
.rec-info { min-width: 0; }
.rec-title { font-size: 14px; color: var(--text); }
.rec-sub { font-size: 12.5px; color: var(--text-3); }
.rec-arrow { color: var(--text-3); flex: 0 0 auto; }

/* ---------------- 页头 ---------------- */

.page-head { margin-bottom: 18px; }
.page-head-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.page-title { font-size: 22px; font-weight: 700; letter-spacing: -.2px; line-height: 1.35; }
.page-sub { margin-top: 6px; color: var(--text-2); font-size: 13.5px; line-height: 1.7; }

/* ---------------- 筛选面板 ---------------- */

.filters {
  padding: 14px 16px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
}
.filter-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }

.filter-search {
  flex: 1 1 260px;
  min-width: 180px;
  min-height: 38px;
  padding: 8px 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 14.5px;
}
.filter-search:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(47, 111, 237, .14);
}
.filter-selects {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.filter-select {
  min-height: 38px;
  padding: 0 28px 0 11px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background-color: var(--surface);
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%238b94a3' d='M2.2 4.4h7.6L6 8.8z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  font-size: 13.5px;
  color: var(--text);
  cursor: pointer;
  appearance: none;
  max-width: 100%;
}
.filter-select:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(47, 111, 237, .14);
}

.filter-tags { margin-top: 12px; border-top: 1px dashed var(--border); padding-top: 12px; }
.filter-tags > summary {
  display: flex;
  align-items: center;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--brand);
  user-select: none;
  padding: 2px 0;
}
.filter-tags > summary::before {
  content: "▸";
  margin-right: 6px;
  font-size: 11px;
  transition: transform .18s;
}
.filter-tags[open] > summary::before { transform: rotate(90deg); }
.filter-tags > summary:hover { color: var(--brand-dark); }

.tag-groups { margin-top: 12px; display: flex; flex-direction: column; gap: 12px; }
.tag-group { display: flex; flex-direction: column; gap: 7px; }
.tag-group-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-3);
  letter-spacing: .4px;
}

.filter-host { margin-bottom: 18px; }

/* ---------------- 列表 / 结果头部 ---------------- */

.results { display: flex; flex-direction: column; gap: 12px; }
.results-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 0 2px;
  font-size: 13.5px;
}
.results-cond { color: var(--text-2); }
.results-count { color: var(--text-3); white-space: nowrap; }
.tails { margin-top: 4px; }
.admin-list { display: flex; flex-direction: column; gap: 12px; }

/* ---------------- 题目列表卡片（qitem） ---------------- */

.qitem {
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
  overflow: hidden;
  transition: border-color .16s, box-shadow .16s;
}
.qitem:hover { border-color: #ccd8ec; box-shadow: var(--shadow-2); }

.qitem-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  padding: 11px 15px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.qitem-actions { margin-left: auto; display: flex; align-items: center; gap: 6px; }

.qitem-body {
  display: block;
  padding: 15px;
  color: var(--text);
  cursor: pointer;
}
.qitem-body:hover { background: #fcfdff; }

.qitem-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 10px 15px;
  border-top: 1px solid var(--border);
  background: #fcfcfd;
}
.qitem-source {
  margin-left: auto;
  font-size: 12px;
  color: var(--text-3);
  max-width: 46%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 列表内嵌「详情」按钮：推到 foot 最右；
   有来源时来源的 margin-left:auto 已把两者一起推右，按钮贴着来源即可 */
.qitem-detail { margin-left: auto; flex: none; }
.qitem-source + .qitem-detail { margin-left: 0; }

/* ---------------- 列表展开区：答案与解析（懒加载） ----------------
   默认隐藏；.is-open 展开。收起只是 display 切换，内容保留不重渲染，
   所以再次展开不会重复请求。 */
.qexpand { display: none; padding: 0 15px 15px; }
.qexpand.is-open { display: block; }
.qexpand .answer-panel { margin-top: 0; }
.qexpand-loading {
  padding: 14px;
  font-size: 13px;
  color: var(--text-3);
}
.qexpand-error {
  padding: 14px;
  font-size: 13px;
  color: var(--bad);
  background: var(--bad-weak);
  border-radius: var(--radius-sm);
}

/* 管理列表：头部按钮多一点，收紧间距 */
.admin-item .qitem-head { gap: 6px; }

/* ---------------- 题卡（qcard） ---------------- */

.qcard {
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.qcard-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  padding: 11px 15px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.qcard-head-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.qcard-body { padding: 16px 15px; }
.qcard-foot {
  padding: 10px 15px;
  border-top: 1px solid var(--border);
  background: #fcfcfd;
}

/* ---------------- 选项 ---------------- */

.qoptions { gap: 8px; padding: 12px 15px 15px; border-top: 1px dashed var(--border); }

/* ---------------- 选项排列方式（单选 / 多选 / 判断共用） ----------------
   这三个类**只负责"怎么排"**，容器自己只管内边距与外框。
   浏览(questionCard) / 作答(answerControl) / 判分回顾(reviewCard) 三处
   都挂这三个类 —— 所以任何一处排版对不上，问题一定出在这里，
   而不是散落在各页面的样式里。
   容器上不再写死 flex-direction，否则会盖掉下面这些 display。 */
.opt-layout-vertical { display: flex; flex-direction: column; }
.opt-layout-horizontal { display: flex; flex-wrap: wrap; align-items: flex-start; }
.opt-layout-horizontal > * { flex: 0 1 auto; }
/* 一排两个（默认）：等宽两列。minmax(0,1fr) 是关键 ——
   写成 1fr 时，公式过长会把格子撑破并顶出横向滚动条。 */
.opt-layout-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }

.qoption {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 4px 0;
  font-size: 15px;
  line-height: 1.7;
}
.opt-key {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  margin-top: 3px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  color: var(--text-2);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1;
}
.opt-body { flex: 1 1 auto; min-width: 0; }

.opt-flag {
  flex: 0 0 auto;
  margin-top: 4px;
  font-size: 11.5px;
  padding: 1px 7px;
  border-radius: 5px;
  white-space: nowrap;
}
.flag-ok { background: var(--ok-weak); color: var(--ok); border: 1px solid #b7e6d4; }
.flag-bad { background: var(--bad-weak); color: var(--bad); border: 1px solid #f3c3c5; }

.qoptions.is-reviewed .qoption.is-correct {
  background: var(--ok-weak);
  border-radius: var(--radius-sm);
  padding: 5px 10px;
  margin-left: -10px;
}
.qoptions.is-reviewed .qoption.is-correct .opt-key {
  background: var(--ok);
  border-color: var(--ok);
  color: #fff;
}
.qoptions.is-reviewed .qoption.is-mine-wrong {
  background: var(--bad-weak);
  border-radius: var(--radius-sm);
  padding: 5px 10px;
  margin-left: -10px;
}
.qoptions.is-reviewed .qoption.is-mine-wrong .opt-key {
  background: var(--bad);
  border-color: var(--bad);
  color: #fff;
}

/* ---------------- 作答控件 ---------------- */

.qanswer-wrap {
  padding: 12px 15px 15px;
  border-top: 1px dashed var(--border);
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.qanswer {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 15px;
  line-height: 1.7;
  resize: vertical;
}
.qanswer:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(47, 111, 237, .14);
}
.qanswer-input { background: #fcfdff; }
.qanswer-input::placeholder { color: var(--text-3); }
.qanswer-solve { font-family: var(--mono); font-size: 14px; }
.qanswer-hint { font-size: 12.5px; color: var(--text-3); }

.qanswer-choice {
  border: 0;
  padding: 12px 15px 6px;
  border-top: 1px dashed var(--border);
  /* 外层只管「选项区 + 清空按钮」的纵向堆叠，排列交给内层 .opt-layout-* */
  display: flex;
  flex-direction: column;
  gap: 7px;
  background: none;
}
/* 作答控件里的选项容器：不带 qoptions 的框线，只当排列容器用 */
.qanswer-choice .opt-inputs { gap: 7px; }
.answer-opt {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.answer-opt:hover { border-color: #bccbe8; background: #fbfcff; }

/* 原生控件保留（键盘与读屏可用），但用样式弱化，视觉上靠 opt-key 表达选中 */
.opt-input {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  margin: 8px 0 0;
  accent-color: var(--brand);
  cursor: pointer;
}
.answer-opt .opt-key { transition: background .15s, color .15s, border-color .15s; }
.opt-input:checked ~ .opt-key {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}
.answer-opt:has(.opt-input:checked) {
  border-color: var(--brand);
  background: var(--brand-weak);
}
.qanswer-choice.is-multi .opt-input:checked ~ .opt-key { background: var(--purple); border-color: var(--purple); }
.qanswer-choice.is-multi .answer-opt:has(.opt-input:checked) { border-color: var(--purple); background: var(--purple-weak); }

.qanswer-choice .qanswer-clear { align-self: flex-start; margin: 4px 0 4px 59px; }

/* ---------------- 判分回顾（reviewCard） ---------------- */

.review-list { display: flex; flex-direction: column; gap: 14px; }
.qcard.review.is-ok { border-left: 4px solid var(--ok); }
.qcard.review.is-bad { border-left: 4px solid var(--bad); }
.qcard.review.is-pending, .qcard.review.is-warn { border-left: 4px solid var(--warn); }
.qcard.review.is-blank, .qcard.review.is-muted { border-left: 4px solid var(--border-strong); }

.review-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 10px;
  padding: 12px 15px 4px;
  border-top: 1px dashed var(--border);
}
.review-block {
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border: 1px solid var(--border);
  min-width: 0;
}
.review-block.is-answer {
  background: var(--ok-weak);
  border-color: #b7e6d4;
}
.review-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-3);
  margin-bottom: 6px;
  letter-spacing: .3px;
}
.review-block.is-answer .review-label { color: #0d7a55; }
.review-block .content { font-size: 14.5px; }

.blank-table {
  margin: 10px 15px 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.blank-row {
  display: grid;
  grid-template-columns: 66px minmax(0, 1fr) 22px minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  font-size: 14px;
  border-bottom: 1px solid var(--border);
}
.blank-row:last-child { border-bottom: 0; }
.blank-row.is-ok { background: var(--ok-weak); }
.blank-row.is-bad { background: var(--bad-weak); }
.blank-idx { font-size: 12.5px; color: var(--text-3); white-space: nowrap; }
.blank-mine { min-width: 0; }
.blank-arrow { text-align: center; color: var(--text-3); }
.blank-std { min-width: 0; color: #0d7a55; font-weight: 500; }
.blank-row.is-bad .blank-std { color: var(--ok); }
.blank-row.is-bad .blank-mine { color: var(--bad); text-decoration: line-through; }

.review-reason {
  margin: 10px 15px 0;
  padding: 8px 11px;
  border-radius: var(--radius-sm);
  background: var(--warn-weak);
  border: 1px solid #f0dcb8;
  color: #8a5a10;
  font-size: 13px;
}

.parse-box { margin: 12px 15px 15px; border-top: 1px dashed var(--border); padding-top: 10px; }
.parse-box > summary {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--brand);
  user-select: none;
}
.parse-box > summary::before { content: "▸ "; font-size: 11px; }
.parse-box[open] > summary::before { content: "▾ "; }
.parse-body {
  margin-top: 10px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: #fcfcfd;
  border: 1px solid var(--border);
}

/* ---------------- 结果摘要 ---------------- */

.summary {
  display: grid;
  grid-template-columns: minmax(150px, 200px) minmax(0, 1fr);
  gap: 20px;
  padding: 20px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
  margin-bottom: 14px;
}
.summary-score {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 8px 0;
  border-right: 1px solid var(--border);
}
.score-num { display: flex; align-items: baseline; }
.score-main {
  font-size: 44px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--brand-dark);
  letter-spacing: -1px;
}
.score-full { font-size: 15px; color: var(--text-3); margin-left: 3px; }
.score-label { margin-top: 7px; font-size: 12.5px; color: var(--text-3); }

.summary-main { min-width: 0; display: flex; flex-direction: column; gap: 13px; }
.summary-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(78px, 1fr));
  gap: 10px;
}
.stat {
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border: 1px solid var(--border);
  text-align: center;
}
.stat-value {
  font-size: 19px;
  font-weight: 700;
  line-height: 1.25;
  font-variant-numeric: tabular-nums;
}
.stat-label { font-size: 11.5px; color: var(--text-3); }
.stat.is-ok { background: var(--ok-weak); border-color: #b7e6d4; }
.stat.is-ok .stat-value { color: var(--ok); }
.stat.is-bad { background: var(--bad-weak); border-color: #f3c3c5; }
.stat.is-bad .stat-value { color: var(--bad); }
.stat.is-warn { background: var(--warn-weak); border-color: #f0dcb8; }
.stat.is-warn .stat-value { color: var(--warn); }
.stat.is-muted .stat-value { color: var(--text-3); }

.accbar {
  height: 9px;
  border-radius: 999px;
  background: var(--surface-3);
  overflow: hidden;
}
.accbar-fill {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--ok), #4cc79a);
  transition: width .5s ease;
}
.summary-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  font-size: 12.5px;
  color: var(--text-3);
}
.summary.is-compact { padding: 14px; grid-template-columns: minmax(120px, 150px) minmax(0, 1fr); }
.summary.is-compact .score-main { font-size: 32px; }

.result-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  margin-bottom: 22px;
}

/* ---------------- 题目详情 ---------------- */

.detail-host { margin-top: 4px; }
.detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 290px;
  gap: 18px;
  align-items: start;
}
.detail-main { min-width: 0; display: flex; flex-direction: column; gap: 12px; }
.detail-actions { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; }
/* 未展开时是个空壳，别在按钮和题面之间多留一道缝 */
.reveal-host { min-width: 0; }
.reveal-host:empty { display: none; }
.detail-side {
  display: flex;
  flex-direction: column;
  gap: 12px;
  position: sticky;
  top: calc(var(--topbar-h) + 16px);
  min-width: 0;
}
.side-card {
  padding: 14px 16px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
}
.side-title {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-3);
  letter-spacing: .4px;
  margin-bottom: 10px;
}
.meta-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 4px 0;
  font-size: 13.5px;
  border-bottom: 1px dashed var(--border);
}
.meta-row:last-child { border-bottom: 0; }
.meta-label { flex: 0 0 62px; color: var(--text-3); font-size: 12.5px; }
.meta-value { flex: 1 1 auto; min-width: 0; color: var(--text); }

.answer-panel {
  padding: 16px 18px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid #b7e6d4;
  border-left: 4px solid var(--ok);
  box-shadow: var(--shadow-1);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.answer-title {
  font-size: 14px;
  font-weight: 650;
  color: #0d7a55;
  display: flex;
  align-items: center;
  gap: 7px;
}
.answer-title::before {
  content: "";
  width: 3px;
  height: 14px;
  border-radius: 2px;
  background: var(--ok);
}
.answer-title-2 { color: var(--text-2); margin-top: 4px; }
.answer-title-2::before { background: var(--brand); }

/* 「答案 / 解析」标题行也是 flex：选择题的答案是标题行里的第二个 span
   （答案与标题同行），所以这里不需要额外的 .answer-line 容器。 */
.answer-value {
  font-weight: 650;
  color: var(--brand-dark);
  letter-spacing: 1px;
  font-variant-numeric: tabular-nums;
}
.answer-value-block {
  padding: 11px 13px;
  border-radius: var(--radius-sm);
  background: #fcfcfd;
  border: 1px solid var(--border);
}

/* ---------------- 答题页 ---------------- */

.exam-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 20px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
}
.exam-head-main { min-width: 0; }
.exam-title { font-size: 19px; font-weight: 700; line-height: 1.35; }
.exam-meta {
  margin-top: 6px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  color: var(--text-3);
}
.exam-head-side { flex: 0 0 auto; }
.exam-timer {
  display: inline-flex;
  align-items: center;
  height: 38px;
  padding: 0 15px;
  border-radius: 999px;
  background: #2b3444;
  color: #fff;
  font-family: var(--mono);
  font-size: 17px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 1px;
}

/* 题号导航：吸在顶栏下方，长卷子随时能跳 */
.exam-nav {
  position: sticky;
  top: var(--topbar-h);
  z-index: 40;
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  overflow-x: auto;
  padding: 10px 4px;
  margin: 12px -4px 0;
  background: rgba(245, 246, 248, .95);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
  scrollbar-width: none;
}
.exam-nav::-webkit-scrollbar { display: none; }
.exam-dot {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-2);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.exam-dot:hover { border-color: var(--brand); color: var(--brand); }
.exam-dot.is-done {
  background: var(--brand-weak);
  border-color: #b9d0f8;
  color: var(--brand-dark);
  font-weight: 600;
}

.exam-body { display: flex; flex-direction: column; gap: 16px; margin-top: 16px; }
.exam-item { scroll-margin-top: 130px; }

.exam-bar {
  position: sticky;
  bottom: 0;
  z-index: 45;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 22px;
  padding: 13px 16px;
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, .96);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--border);
  box-shadow: 0 -2px 14px rgba(20, 28, 45, .07);
}
.exam-bar-left { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; min-width: 0; }
.exam-progress {
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-2);
}
.exam-progress.is-full { color: var(--ok); }
.exam-hint { font-size: 12.5px; color: var(--text-3); }
.exam-hint-ok { color: var(--ok); }

/* ---------------- 练习记录 ---------------- */

.rec-table {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.rec-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 17px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
  color: var(--text);
  transition: border-color .16s, box-shadow .16s;
}
.rec-row:hover { border-color: #cdd9ee; box-shadow: var(--shadow-2); }
.rec-row-main { display: flex; align-items: center; gap: 15px; flex: 1 1 auto; min-width: 0; }
.rec-row-score {
  display: flex;
  align-items: baseline;
  gap: 1px;
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
}
.rec-row-score strong { font-size: 23px; font-weight: 700; color: var(--brand-dark); line-height: 1; }
.rec-row-score span { font-size: 12.5px; color: var(--text-3); }
.rec-row-info { min-width: 0; }
.rec-row-title { font-size: 14px; }
.rec-row-sub { font-size: 12.5px; color: var(--text-3); }
.rec-row-side { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }

.acc-pill {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 11px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  border: 1px solid transparent;
}
.acc-ok { background: var(--ok-weak); color: var(--ok); border-color: #b7e6d4; }
.acc-warn { background: var(--warn-weak); color: var(--warn); border-color: #f0dcb8; }
.acc-bad { background: var(--bad-weak); color: var(--bad); border-color: #f3c3c5; }

/* ---------------- 组卷配置 ---------------- */

.probe { font-size: 13.5px; color: var(--text-2); }
.probe-text strong { font-size: 16px; color: var(--brand-dark); font-variant-numeric: tabular-nums; }
.probe-warn { color: var(--warn); margin-left: 6px; }

.start-bar {
  position: sticky;
  bottom: 0;
  z-index: 45;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 18px;
  padding: 13px 16px;
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, .96);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--border);
  box-shadow: 0 -2px 14px rgba(20, 28, 45, .07);
}

/* ---------------- 表单卡片（组卷用） ----------------
   录入 / 编辑页的样式已整体搬到 editor.css（统一编辑区，类名 ue- 前缀），
   这里只保留组卷页仍在用的 .form-card / .field-grid。 */

.form-card {
  padding: 20px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ---------------- 选题篮（pickbar / pickToggle） ---------------- */

.pick-toggle {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 11px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-2);
  font-size: 12.5px;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s;
}
.pick-toggle:hover { border-color: var(--brand); color: var(--brand); }
.pick-toggle.is-on {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
  font-weight: 500;
}
.pick-toggle.is-on:hover { background: var(--brand-dark); color: #fff; }

/* 0 题时不占位置，一旦有选题就从底部浮出来 */
.pickbar { display: none; }
.pickbar.is-on {
  position: fixed;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  z-index: 70;
  display: flex;
  align-items: center;
  gap: 16px;
  max-width: calc(100vw - 24px);
  padding: 10px 12px 10px 20px;
  border-radius: 999px;
  background: #232a35;
  color: #fff;
  box-shadow: var(--shadow-3);
  animation: tk-rise .22s ease;
}
@keyframes tk-rise {
  from { opacity: 0; transform: translate(-50%, 12px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}
.pickbar-count {
  display: flex;
  align-items: baseline;
  gap: 4px;
  font-size: 13.5px;
  color: #d6dae2;
  white-space: nowrap;
}
.pickbar-count strong { font-size: 19px; color: #fff; font-variant-numeric: tabular-nums; }
.pickbar-actions { display: flex; align-items: center; gap: 8px; }
.pickbar .btn-ghost {
  background: rgba(255, 255, 255, .1);
  border-color: rgba(255, 255, 255, .22);
  color: #eaeef4;
}
.pickbar .btn-ghost:hover { background: rgba(255, 255, 255, .2); color: #fff; }
.pickbar .btn-primary { background: var(--brand); border-color: var(--brand); }

/* ---------------- 登录 / 权限提示 ---------------- */

.auth-card {
  max-width: 420px;
  margin: 40px auto;
  padding: 26px 26px 22px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-2);
  text-align: center;
}
.auth-title { font-size: 21px; font-weight: 700; }
.auth-sub { margin-top: 8px; color: var(--text-2); font-size: 13.5px; line-height: 1.7; }
.auth-form { margin-top: 22px; display: flex; flex-direction: column; gap: 14px; text-align: left; }
.auth-actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: 18px; }
.auth-form .auth-actions { justify-content: stretch; margin-top: 6px; }
.auth-form .auth-actions .btn { width: 100%; }
.auth-hint {
  margin-top: 4px;
  font-size: 12px;
  color: var(--text-3);
  line-height: 1.65;
  text-align: left;
  padding: 9px 11px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}

/* ---------------- 响应式 ---------------- */

@media (max-width: 900px) {
  .detail-grid { grid-template-columns: minmax(0, 1fr); }
  .detail-side { position: static; }
  .summary { grid-template-columns: minmax(0, 1fr); gap: 16px; padding: 16px; }
  .summary-score {
    border-right: 0;
    border-bottom: 1px solid var(--border);
    padding-bottom: 14px;
  }
  .score-main { font-size: 38px; }
}

@media (max-width: 640px) {
  .hero { padding: 22px 18px; }
  .hero-title { font-size: 23px; }
  .hero-actions .btn { flex: 1 1 auto; }

  .filters { padding: 12px; }
  .filter-search { flex: 1 1 100%; }
  .filter-selects { width: 100%; }
  .filter-select { flex: 1 1 calc(50% - 4px); }

  .qitem-body, .qcard-body { padding: 13px 12px; }
  .qitem-head, .qcard-head { padding: 10px 12px; }
  .qitem-foot, .qcard-foot { padding: 9px 12px; }
  .qitem-source { max-width: 100%; margin-left: 0; }
  .qoptions { padding: 11px 12px 13px; }
  .qanswer-wrap, .qanswer-choice { padding: 11px 12px 13px; }
  .qanswer-choice .qanswer-clear { margin-left: 54px; }

  .review-pair { grid-template-columns: minmax(0, 1fr); padding: 11px 12px 4px; }
  .blank-row {
    grid-template-columns: 58px minmax(0, 1fr);
    row-gap: 2px;
  }
  .blank-arrow { display: none; }
  .blank-std::before { content: "→ "; color: var(--text-3); font-weight: 400; }

  .exam-head { padding: 14px; }
  .exam-title { font-size: 17px; }
  .exam-timer { height: 34px; font-size: 15px; padding: 0 12px; }
  .exam-bar, .start-bar { padding: 11px 12px; border-radius: var(--radius); }
  .exam-bar .btn-lg, .start-bar .btn-lg { flex: 1 1 100%; }
  .exam-hint { display: none; }

  .rec-item, .rec-row { padding: 12px 14px; gap: 11px; }
  .rec-score strong, .rec-row-score strong { font-size: 20px; }
  .rec-arrow { display: none; }
  .rec-row-side { gap: 6px; }

  .form-card { padding: 15px; }
  .auth-card { margin: 20px auto; padding: 20px 18px; }

  .pickbar.is-on {
    left: 12px;
    right: 12px;
    bottom: 12px;
    max-width: none;
    transform: none;
    border-radius: var(--radius-lg);
    justify-content: space-between;
    padding-left: 16px;
  }
  @keyframes tk-rise {
    from { opacity: 0; transform: translateY(12px); }
    to { opacity: 1; transform: none; }
  }
}

/* ============================================================
   标签管理（#/admin/tags）
   ------------------------------------------------------------
   一个分类轴一张卡：卡片头是"轴"（改名/删除/排序），卡片体是
   轴上的标签（逐行改名/删除/排序），卡片尾是行内新增。
   所有行都用同一套 flex 结构，靠 gap 而不是 margin 撑间距，
   这样移动端折行时不会出现莫名的大空隙。
   ============================================================ */

.axis-list { display: flex; flex-direction: column; gap: 14px; }

.axis-card {
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
  padding: 14px 15px 15px;
}
.axis-card.is-new { border-style: dashed; box-shadow: none; }

.axis-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.axis-titles { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; }
.axis-title { font-size: 16px; font-weight: 600; letter-spacing: -.1px; }

.axis-key {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--text-2);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 1px 6px;
}

.axis-tag {
  font-size: 11.5px;
  color: var(--brand);
  background: var(--brand-weak);
  border-radius: 999px;
  padding: 2px 8px;
}
.axis-tag.is-warn { color: var(--warn); background: var(--warn-weak); }

.axis-meta { font-size: 12.5px; color: var(--text-3); margin-left: auto; white-space: nowrap; }
.axis-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }

.axis-edit { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; width: 100%; }
.axis-edit-label { font-size: 12.5px; color: var(--text-2); }

.axis-input {
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-size: 13.5px;
  font-family: inherit;
  padding: 7px 10px;
  min-width: 0;
  flex: 1 1 160px;
  transition: border-color .15s, box-shadow .15s;
}
.axis-input:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-weak);
}
.axis-input::placeholder { color: var(--text-3); }

.tag-edit-input { flex: 1 1 220px; }

.axis-tags { display: flex; flex-direction: column; gap: 2px; padding-top: 4px; }
.axis-empty { font-size: 13px; color: var(--text-3); padding: 9px 0; }

.tag-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  border-radius: var(--radius-sm);
  border-bottom: 1px dashed var(--border);
}
.tag-line:last-of-type { border-bottom: 0; }
.tag-line:hover { background: #fbfcff; }
.tag-line.is-editing { background: var(--brand-weak); border-bottom-color: transparent; }

.tag-line-name { font-size: 14px; word-break: break-word; }

.tag-line-usage {
  font-size: 12px;
  color: var(--text-3);
  background: var(--surface-2);
  border-radius: 999px;
  padding: 1px 8px;
  white-space: nowrap;
}
.tag-line-usage.is-used { color: var(--warn); background: var(--warn-weak); }

.tag-line-actions { margin-left: auto; display: flex; align-items: center; gap: 5px; }

.tag-add { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.tag-add-input { flex: 1 1 220px; }
.tag-add .form-err { flex: 1 0 100%; }

.form-err { color: var(--bad); font-size: 12.5px; min-height: 0; }
.form-err:empty { display: none; }

.axis-hint { margin-top: 10px; font-size: 12.5px; color: var(--text-3); line-height: 1.7; }

/* 管理页标题右侧的动作区（「创建新题」按钮与其它头部动作并排） */
.head-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

@media (max-width: 640px) {
  .axis-head { gap: 8px; }
  .axis-meta { margin-left: 0; }
  .axis-actions { width: 100%; }
  .tag-line-actions { width: 100%; margin-left: 0; }
  .tag-line-name { flex: 1 1 auto; }
}

/* ============================================================
   字典管理（#/admin/tags）—— 分类轴/标签、题型、难度三本字典
   ------------------------------------------------------------
   页签切换三本字典；每本字典一张卡：卡头是标题与计数，卡体是
   "一条一项"的列表（dict-row），卡尾是行内新增。
   dict-row 一律 flex + wrap，窄屏自然折行、绝不横向溢出 ——
   这是题库在手机 / 微信内置浏览器里的硬约束。
   ============================================================ */

.dict-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0 2px; }

.dict-tab {
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-2);
  font-size: 13.5px;
  font-family: inherit;
  padding: 7px 14px;
  border-radius: 999px;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.dict-tab:hover { background: var(--surface-2); }
.dict-tab.is-on { background: var(--brand); border-color: var(--brand); color: #fff; }

.dict-table { display: flex; flex-direction: column; gap: 8px; padding-top: 4px; }

/* 页签下方的字典主体：与页签之间留一口气，免得卡片贴着胶囊 */
.dict-body { margin-top: 12px; }

.dict-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.dict-row.is-editing { display: block; background: var(--brand-weak); border-color: var(--brand); }

.dict-cell-main { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; min-width: 8rem; }
.dict-name { font-size: 14px; font-weight: 600; word-break: break-word; }
.dict-cell { font-size: 13px; color: var(--text-2); white-space: nowrap; }

.dict-flag {
  font-size: 12px;
  color: var(--text-3);
  background: var(--surface-2);
  border-radius: 999px;
  padding: 1px 8px;
}
.dict-flag.is-on { color: var(--brand); background: var(--brand-weak); }

.dict-usage {
  font-size: 12px;
  color: var(--text-3);
  background: var(--surface-2);
  border-radius: 999px;
  padding: 1px 8px;
  white-space: nowrap;
}
.dict-usage.is-used { color: var(--warn); background: var(--warn-weak); }

.dict-actions { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }

.dict-editor { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; width: 100%; }
.dict-editor .axis-input { flex: 0 1 auto; }
.dict-editor .axis-input:not(.dict-mode):not(.dict-score) { flex: 1 1 190px; }
.dict-mode { min-width: 8.5rem; }
.dict-score { width: 5.5rem; }
.dict-editor .dict-hint { flex: 1 0 100%; }
.dict-editor .form-err { flex: 1 0 100%; }

.dict-check {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-2);
  white-space: nowrap;
  cursor: pointer;
}
.dict-check.is-off { opacity: .55; cursor: not-allowed; }
.dict-check input { margin: 0; }

.dict-hint { font-size: 12px; color: var(--text-3); }

/* ---------------- 停用态（跨页面共用一套视觉语言） ----------------
   原则：停用是"收起来"，不是"坏掉了"。
   所以统一用**降低对比度 + 虚线标记**，而不是红色或删除线 ——
   红色暗示异常、删除线暗示已废弃，都会让人以为是需要修的问题。
   三处状态提示各有各的信息密度，缺一个用户就得靠猜：
     · 行/卡片整体降饱和 → 扫一眼列表就能分出"哪些不参与"
     · 「已停用」徽章     → 说清状态本身（灰底虚线，可逆感）
     · 按钮文案切换       → 说清"点下去会发生什么"（停用 ⇄ 启用） */

.dict-off-badge {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 7px;
  border-radius: 5px;
  background: var(--surface-2);
  border: 1px dashed var(--border-strong);
  color: var(--text-3);
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
  letter-spacing: .3px;
}

/* 停用的字典行 / 轴头 / 标签行：整行降饱和，但保持可点（要能启用回来） */
.dict-row.is-off,
.tag-line.is-off { background: var(--surface-2); }
.dict-row.is-off .dict-name,
.tag-line.is-off .tag-line-name { color: var(--text-3); }
.dict-row.is-off .dict-cell,
.tag-line.is-off .tag-line-usage { opacity: .75; }

.axis-head.is-off { background: var(--surface-2); }
.axis-head.is-off .axis-title { color: var(--text-3); }

/* 「启用」按钮：用品牌色描边，让"能恢复"这件事看起来是正向的 */
.btn.is-revive {
  color: var(--brand);
  border-color: #c9dcff;
  background: var(--brand-weak);
}
.btn.is-revive:hover { background: #dde8ff; }

/* 题目管理列表里的停用项 */
.qitem.is-off { background: var(--surface-2); opacity: .82; }
.qitem.is-off .qitem-body { background: transparent; }

/* 详情页顶部的停用横幅 */
.detail-off {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 14px;
  line-height: 1.6;
}
.detail-off strong { font-weight: 600; }

@media (max-width: 640px) {
  .dict-row { gap: 8px; }
  .dict-actions { width: 100%; margin-left: 0; }
  .dict-cell-main { min-width: 0; }
  .detail-off { flex-direction: column; gap: 2px; }
}

/* ============================================================
   知识目录树
   ------------------------------------------------------------
   折叠靠 `.knode.is-open > .knode-list { display: block }` 一条规则实现 ——
   展开/折叠只切父 li 的 class，**不重建 DOM**（这样折叠状态、
   滚动位置、输入焦点都能保住）。
   缩进用 padding-left 而不是 margin：整行都要可点，
   行宽必须撑满，否则右侧大片留白点了没反应。
   ============================================================ */

.ktree-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-1);
  padding: 10px 12px 14px;
}

.ktree-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
.ktree-bar-meta {
  margin-left: auto;
  font-size: 12px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

.ktree-edit {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  padding: 10px 12px;
  border: 1px solid var(--brand);
  border-radius: var(--radius);
  background: var(--brand-weak);
}
.ktree-edit-label { font-size: 13px; font-weight: 600; color: var(--brand-dark); }
.ktree-edit .axis-input { flex: 1 1 220px; min-width: 0; }
.ktree-edit .form-err { flex-basis: 100%; }

/* ---- 列表骨架 ---- */
/* 树容器：由 knowledge-tree.js 的 knowledgeTree() 返回，是 .ktree-card 里的主体。
   给个最小高度，避免"加载中→空树→有内容"时下方元素跳动。 */
.ktree { min-height: 60px; }
/* 页面里承载树的占位节点（knowledgeTree 每次重画会整体替换它的子节点） */
.ktree-host { min-height: 60px; }
.ktree:empty::after {
  content: '（暂无节点）';
  display: block;
  padding: 12px 2px;
  font-size: 13px;
  color: var(--text-3);
}

.knode-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
/* 子级缩进 + 一条竖线，让层级一眼可辨（纯缩进在深树里会糊成一片）。
   缩进量 28/24 → 22/18 → 18/14 → **19/10**（2026-09-28 第三次调整）：
   2026-09-28 知识目录换成组卷网全量树（**6 层**），原来的 14px/层让第 6 层
   累计吃掉 75px，可用宽只剩 147px，而「20 个字符宽」的名称需要 151px ——
   于是短名也被 CSS 再截一次，把"只在超长时截断"的规则架空
   （冒烟与线上只读都会红，失败信息里带 `可用/需要`）。
   深层层级感**靠竖线**，不靠缩进深，所以这里继续收窄：19 + 10×层级。
   配套断言：smoke.js [11e] 与 live-check.js 2c。 */
.knode-list .knode-list {
  margin-left: 12px;
  padding-left: 6px;
  border-left: 1px dashed var(--border-strong);
}
.knode-list .knode-list .knode-list {
  margin-left: 6px;
  padding-left: 4px;
}

/* ---- 折叠：唯一的开关 ---- */
.knode > .knode-list { display: none; }
.knode.is-open > .knode-list { display: block; }

/* ---- 行 ---- */
.knode-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 6px 3px 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
  min-height: 30px;
}
.knode-row:hover { background: var(--surface-2); }
.knode-row.is-selected {
  background: var(--brand-weak);
  box-shadow: inset 0 0 0 1px #c9dcff;
}
.knode-row.is-selected .knode-name { color: var(--brand-dark); font-weight: 600; }

/* 停用节点：灰而不红 —— 这是可逆开关，不是错误。整行降饱和但仍可操作 */
.knode-row.is-off { background: var(--surface-2); }
.knode-row.is-off .knode-name { color: var(--text-3); }
/* 占位节点：自身停用、只因后代可用才被保留，不可勾选 */
.knode-row.is-placeholder { cursor: default; }
.knode-row.is-placeholder .knode-name { color: var(--text-3); font-style: italic; }

.knode-toggle {
  flex: 0 0 auto;
  /* 22 → 20（2026-09-23）：名称点击已改为筛题，箭头成了**唯一**的开合入口，
     但侧栏收窄到 280 后每一像素都要让给名称。20px 见方仍在 30px 行高内，
     触控区靠整行高度兜底，不破行距。 */
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  padding: 0;
  color: var(--text-3);
  font-size: 14px;
  line-height: 1;
  border-radius: 4px;
}
.knode-toggle:not(.is-leaf):hover { background: var(--surface-3); color: var(--text); }
.knode-toggle.is-leaf { visibility: hidden; }

.knode-name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 14px;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.knode-meta {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
/* 药丸样式：现在只剩「未关联知识点」那条哨兵栏目在用
   （知识节点名后的题量数字已按需求移除，题量改走整行 title） */
.knode-count {
  min-width: 20px;
  padding: 0 6px;
  border-radius: 9px;
  background: var(--surface-3);
  color: var(--text-2);
  font-size: 11px;
  line-height: 17px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* ---- 操作区：默认淡出，悬停/选中时显形，避免树上挂满按钮 ---- */
.knode-tools {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  opacity: 0;
  transition: opacity .12s;
}
.knode-row:hover .knode-tools,
.knode-row.is-selected .knode-tools,
.knode-row:focus-within .knode-tools { opacity: 1; }

.knode-act,
.knode-pick {
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-2);
  border-radius: 6px;
  padding: 2px 7px;
  font-size: 12px;
  line-height: 17px;
  cursor: pointer;
}
.knode-act:hover,
.knode-pick:hover { border-color: var(--brand); color: var(--brand); }
.knode-act:disabled { opacity: .4; cursor: not-allowed; }
.knode-act:disabled:hover { border-color: var(--border-strong); color: var(--text-2); }
.knode-act.is-danger { color: var(--bad); border-color: #f3c9cb; }
.knode-act.is-danger:hover { background: var(--bad-weak); border-color: var(--bad); color: var(--bad); }
/* 「启用」用品牌色，与字典页的 .btn.is-revive 保持一致语感 */
.knode-act.is-revive {
  color: var(--brand);
  border-color: #c9dcff;
  background: var(--brand-weak);
}

.knode-check {
  width: 16px;
  height: 16px;
  accent-color: var(--brand);
  cursor: pointer;
}

/* 「全部展开 / 全部折叠」切换按钮：挂在侧栏头部标题右侧 */
.ktree-all-toggle { margin-left: auto; }

/* 多选开关：激活时用品牌色填充，一眼看出当前在哪种模式 */
.ktree-mode-toggle.is-on {
  color: var(--brand-dark);
  background: var(--brand-weak);
  border-color: transparent;
  font-weight: 600;
}

/* 未关联知识点栏目：视觉上是树的延续（同一套行样式），但缩进与
   目录平级、加一条虚线分隔，表明它不是树里的节点 */
.kn-unlinked {
  margin-top: 6px;
  padding-top: 4px;
  border-top: 1px dashed var(--border);
}
.kn-unlinked-row .knode-name { color: var(--text-2); }
.kn-unlinked-row.is-selected .knode-name { color: var(--brand-dark); }
.kn-unlinked-hint {
  font-size: 11px;
  color: var(--text-3);
  background: none;
  border: none;
  padding: 0;
}

/* ---- 浏览页顶部的「知识范围」提示条 ---- */
.kfilter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  padding: 9px 12px;
  border: 1px solid #c9dcff;
  border-radius: var(--radius);
  background: var(--brand-weak);
}
.kfilter-label { font-size: 12px; color: var(--text-2); }
.kfilter-name { font-size: 14px; font-weight: 600; color: var(--brand-dark); }
.kfilter-note { font-size: 12px; color: var(--text-3); }
.kfilter-bar .btn { margin-left: auto; }
.kfilter-bar .btn + .btn { margin-left: 0; }

/* 移动端：树上按钮不做悬停显形（没有 hover），一律常驻；
   缩进收窄，否则深层节点在窄屏上几乎只剩按钮 */
@media (max-width: 640px) {
  .ktree-card { padding: 8px 8px 12px; }
  .knode-tools { opacity: 1; }
  .knode-list .knode-list { margin-left: 10px; padding-left: 7px; }
  .knode-list .knode-list .knode-list { margin-left: 8px; padding-left: 6px; }
  .knode-name { font-size: 13px; }
  .knode-bar-meta { width: 100%; margin-left: 0; }
  .kfilter-bar .btn { margin-left: 0; }
}

/* ============================================================
   题库页 + 知识目录 合并布局（2026-09-22）
   ------------------------------------------------------------
   桌面（>900px）：左树右列表的双栏，树侧栏 sticky 跟随滚动
   （70 个节点比一屏长，不 sticky 的话点一次筛选就找不到树头了）。
   移动（≤900px）：单栏，树默认收起，靠「☰ 知识目录」开关展开 ——
   开关是布局里**第一个**网格子元素，在树前面，收起时也看得见。
   ============================================================ */

.browse-layout {
  display: grid;
  /* 340 → 280（2026-09-23 二次调整）：一行里不再有题量数字徽章、也不再有
     「只看此目录」按钮（那个按钮即使 opacity:0 也照样占位，是当时把侧栏撑到
     340 的主因）。腾出的宽度足够把侧栏收窄 60px，名称位反而更宽。

     唯一的下限没变：**20 个字符宽（10 个汉字 ≈ 140px）在最深一层也得放得下**，
     否则"只在超长时截断"的规则会被 CSS 的容器截断架空（冒烟与线上只读都有断言，
     失败时会打印 `可用/需要`）。配套见 .knode-list / .knode-toggle。 */
  grid-template-columns: 280px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}
.browse-main { min-width: 0; }

.ktree-side {
  position: sticky;
  top: calc(var(--topbar-h, 56px) + 16px);
  max-height: calc(100vh - var(--topbar-h, 56px) - 32px);
  overflow: auto;
  min-width: 0;
}
/* 侧栏这张卡片比管理页的瘦一档：收窄到 280 后，卡片的左右内边距也得让位，
   否则名称位凭空少 4px（管理页不受影响，那边一屏很宽） */
.ktree-side .ktree-card { padding: 10px 10px 12px; }

.ktree-side-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  padding: 0 2px 8px;
}
.ktree-side-title { font-size: 14px; font-weight: 700; color: var(--text); }

/* 「知识目录」标题现在是个筛选入口（看所有已关联知识点的题）：做成按钮，
   但保持标题观感 —— 平时跟文字一样，悬停/激活才露出"可点"的样子。
   （形状前缀 .ktree-all-linked 必须真的在 CSS 里存在，否则静态检查会判
   "JS 用了但 CSS 没定义"。） */
.ktree-all-linked {
  border: none;
  background: none;
  padding: 0 4px;
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  cursor: pointer;
}
.ktree-all-linked:hover { color: var(--brand); background: var(--surface-2); }
.ktree-all-linked.is-on { color: var(--brand-dark); background: var(--brand-weak); }
.ktree-side-sub { font-size: 12px; color: var(--text-3); flex-basis: 100%; }

.ktree-side-toggle { display: none; }

/* 移动端：单栏 + 树默认收起（.is-open 才显示） */
@media (max-width: 900px) {
  .browse-layout { grid-template-columns: 1fr; gap: 10px; }
  .ktree-side {
    position: static;
    max-height: none;
    overflow: visible;
    display: none;
  }
  .ktree-side.is-open { display: block; }
  .ktree-side-toggle { display: inline-flex; }
}

/* ---------------- 站点设置（#/admin/site) ----------------
   左表单右预览：改一个字段就能在旁边看到顶栏/页脚的最终样子。
   预览里的元素刻意**不复用真实外壳的类名**（.pv-*），
   否则改这里的样式会连带影响线上顶栏。 */
.site-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 16px;
  align-items: start;
}
.site-main { min-width: 0; display: flex; flex-direction: column; gap: 14px; }
.site-side { min-width: 0; display: flex; flex-direction: column; gap: 12px; }

.site-group {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 14px 16px 16px;
  box-shadow: var(--shadow-1);
}
.site-group-title {
  margin: 0 0 12px;
  font-size: 13.5px;
  font-weight: 650;
  color: var(--text-2);
  letter-spacing: .2px;
}
.site-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}
.site-tip { font-size: 12.5px; color: var(--text-3); }
.site-textarea { min-height: 74px; resize: vertical; font-family: inherit; }

.field-hint { font-size: 12px; color: var(--text-3); }

/* Logo 字段：预览方块 + 上传按钮 + 说明一行排开 */
.logo-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.logo-preview {
  width: 42px; height: 42px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  overflow: hidden;
}
.logo-preview img { width: 100%; height: 100%; object-fit: contain; display: block; }
.logo-fallback { font-size: 20px; font-weight: 700; color: var(--brand); }

/* 右侧实时预览 */
.site-preview {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 12px 14px 14px;
  box-shadow: var(--shadow-1);
}
.site-preview-title {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-3);
  margin-bottom: 10px;
}
.pv-topbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.pv-topbar strong { font-size: 14.5px; font-weight: 650; }
.pv-mark {
  width: 28px; height: 28px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--brand), #5b8ef7);
  color: #fff;
  font-size: 16px;
  font-weight: 700;
  overflow: hidden;
}
.pv-mark img { width: 100%; height: 100%; object-fit: contain; display: block; background: #fff; }
.pv-foot {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--border);
  text-align: center;
  font-size: 12.5px;
  color: var(--text-3);
  line-height: 1.7;
}
.pv-meta { opacity: .9; }

/* 侧栏里的说明列表（与 .side-card 搭配使用） */
.side-list {
  margin: 0;
  padding-left: 18px;
  font-size: 12.5px;
  color: var(--text-3);
  line-height: 1.8;
}

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



/* ============================================================
   后台版块化布局（2026-09-24）
   ------------------------------------------------------------
   形态：一排横向大胶囊切换管理版块 + 下方通栏内容区。
   **版块清单的唯一真源是 config.js 的 ADMIN_SECTIONS**，这里只管长相 ——
   加一个版块不需要动这份 CSS。

   ⚠️ .sect-pill 的类名是在 JS 里拼出来的（'sect-pill' + ' is-on' + ' is-planned'），
   静态扫描抓不到 `class: '…'` 字面量，所以 scripts/check-css.js 的 DYNAMIC
   表里显式登记了它们，否则会被判成"JS 用了但 CSS 没定义"。
   ============================================================ */

/* ---------------- ① 版块胶囊 ---------------- */

.sect-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: stretch;
  margin-bottom: 18px;
}

.sect-pill {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 205px;
  max-width: 330px;
  padding: 11px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-1);
  color: inherit;
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  appearance: none;
  transition: border-color .15s, background .15s, box-shadow .15s;
}
.sect-pill:hover { border-color: var(--border-strong); box-shadow: var(--shadow-2); }
.sect-pill.is-on {
  border-color: var(--brand);
  background: var(--brand-weak);
  box-shadow: inset 0 0 0 1px var(--brand);
}
.sect-pill.is-on .sect-ico { background: var(--brand); color: #fff; }
.sect-pill.is-on .sect-label { color: var(--brand-dark); }
.sect-pill.is-on .sect-desc { color: var(--brand-dark); opacity: .85; }

/* 预留版块：灰显、不可点、也不参与换行后的宽度争夺（description 直接不渲染） */
.sect-pill.is-planned {
  opacity: .62;
  cursor: default;
  flex: 0 0 auto;
  min-width: 0;
  padding: 11px 14px;
  box-shadow: none;
}
.sect-pill.is-planned:hover { border-color: var(--border); box-shadow: none; }
.sect-pill.is-planned .sect-desc { display: none; }

.sect-ico {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--text-2);
  font-size: 15px;
  line-height: 1;
}

.sect-txt { min-width: 0; display: flex; flex-direction: column; }
.sect-label { font-size: 14px; font-weight: 650; color: var(--text); white-space: nowrap; }
/* 说明单行截断。⚠️ 必须 display:block —— text-overflow 在 inline 元素上不生效，
   曾经漏了这一条，768px 下徽标把文案顶出容器造成横向溢出。 */
.sect-desc {
  display: block;
  font-size: 12px;
  color: var(--text-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------------- ② 通栏内容区 ---------------- */

.sect-body { border-top: 2px solid var(--border); padding-top: 18px; }

.sect-head { margin: 0 0 14px; }
.sect-title { margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -.2px; }
.sect-sub { margin: 5px 0 0; font-size: 13px; color: var(--text-2); line-height: 1.7; }

/* ---------------- ③ 概览统计条（每块可点 = 一次快捷筛选） ---------------- */

.stat-bar { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.stat-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 7px 13px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  box-shadow: var(--shadow-1);
  color: inherit;
  font: inherit;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.stat-chip:hover { border-color: var(--brand); background: var(--brand-weak); }
.stat-num { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--text); }
.stat-txt { font-size: 12.5px; color: var(--text-2); }
.stat-hint { font-size: 12.5px; color: var(--text-3); }
/* 语义色在前、选中态在后：两者同时在场时选中态要赢 */
.stat-chip.is-ok .stat-num { color: var(--ok); }
.stat-chip.is-bad .stat-num { color: var(--bad); }
.stat-chip.is-muted .stat-num { color: var(--text-3); }
.stat-chip.is-on {
  border-color: var(--brand);
  background: var(--brand-weak);
  box-shadow: inset 0 0 0 1px var(--brand);
}
.stat-chip.is-on .stat-num { color: var(--brand-dark); }

/* ---------------- ④ 知识树侧栏的空态 ---------------- */
.ktree-empty { padding: 8px 2px; }

/* ---------------- ⑤ 概览版块 ---------------- */

.ov-grid {
  display: grid;
  gap: 14px;
  /* min(max()) 的写法：窄屏时不至于被 290px 的轨道撑破容器 */
  grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr));
}
.ov-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  padding: 15px 16px;
}
.ov-card-title { margin: 0 0 10px; font-size: 14px; font-weight: 700; }
.ov-kv {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 4px 0;
  font-size: 13px;
}
.ov-kv-label { min-width: 0; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ov-kv-value { flex: 0 0 auto; font-weight: 650; font-variant-numeric: tabular-nums; }
.ov-split { height: 1px; background: var(--border); margin: 8px 0; }

.ov-bar { display: flex; align-items: center; gap: 8px; padding: 3px 0; font-size: 12.5px; }
.ov-bar-name { flex: 0 0 auto; width: 76px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ov-bar-track { flex: 1; min-width: 0; height: 7px; border-radius: 999px; background: var(--surface-3); overflow: hidden; }
.ov-bar-fill { display: block; height: 100%; border-radius: 999px; background: var(--brand); }
.ov-bar-num { flex: 0 0 auto; color: var(--text-3); font-variant-numeric: tabular-nums; }

.ov-note { margin: 8px 0 0; font-size: 12.5px; color: var(--text-3); line-height: 1.7; }
.ov-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

/* ---------------- 移动端：胶囊竖排、预留版块不再独占一行 ---------------- */
@media (max-width: 600px) {
  .sect-pill { min-width: 100%; max-width: none; }
  .sect-pill.is-planned { min-width: 0; }
}

/* ============================================================
   批量导入版块（pages/admin-import.js）
   ------------------------------------------------------------
   三步向导：上传 → 校对 → 报告。解析全在浏览器里做，所以这一页
   除了最后落库，其余交互都是即时的，样式上就不要有"加载中"的重感。
   ============================================================ */

/* ---------------- 步骤指示器 ---------------- */
.imp-steps { display: flex; gap: 10px; margin-bottom: 14px; }
.imp-step {
  flex: 1 1 0; min-width: 0;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); color: var(--text-3);
}
.imp-step-n {
  flex: 0 0 auto;
  width: 22px; height: 22px; line-height: 22px; text-align: center;
  border-radius: 999px; background: var(--surface-3); color: var(--text-2);
  font-size: 12.5px; font-variant-numeric: tabular-nums;
}
.imp-step-txt { min-width: 0; display: flex; flex-direction: column; line-height: 1.4; }
.imp-step-txt b { font-size: 13.5px; font-weight: 600; }
.imp-step-txt span { font-size: 12px; color: var(--text-3); }
.imp-step.is-current { border-color: var(--brand); background: var(--brand-weak); color: var(--brand-dark); }
.imp-step.is-current .imp-step-n { background: var(--brand); color: #fff; }
.imp-step.is-current .imp-step-txt b { color: var(--brand-dark); }
.imp-step.is-done { color: var(--text-2); }
.imp-step.is-done .imp-step-n { background: var(--ok-weak); color: var(--ok); }

.imp-host { display: block; }

/* ---------------- ① 上传 ---------------- */
.imp-drop {
  padding: 34px 22px;
  border: 2px dashed var(--border-strong); border-radius: var(--radius-lg);
  background: var(--surface); text-align: center;
  transition: border-color .15s, background .15s;
}
.imp-drop.is-over { border-color: var(--brand); background: var(--brand-weak); }
.imp-drop.is-off { opacity: .6; }
.imp-drop-ico { font-size: 30px; line-height: 1; color: var(--brand); }
.imp-drop-title { margin-top: 10px; font-size: 15px; font-weight: 600; }
.imp-drop-sub { margin-top: 5px; font-size: 12.5px; color: var(--text-3); }
.imp-drop-act { margin-top: 16px; }
.imp-drop-note { margin-top: 14px; font-size: 12px; color: var(--text-3); line-height: 1.7; }
/* 真正的 <input type=file> 藏起来，由同 id 的 <label class="btn"> 触发 */
.imp-file { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

/* ---------------- ① 本批通用配置卡（试题来源 + 挂载默认知识点） ----------------
   卡里每一项都是"整批生效"的，所以刻意和上面的拖拽区**视觉分区**：
   拖拽区管"文件"，这张卡管"配置"。 */

.imp-src-card {
  margin-top: 14px; padding: 14px 16px;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface); box-shadow: var(--shadow-1);
}
.imp-src-head { display: flex; flex-wrap: wrap; align-items: center; gap: 9px; margin-bottom: 10px; }
.imp-src-title { font-size: 13.5px; font-weight: 600; }
.imp-src-badge {
  padding: 1px 9px; border-radius: 999px;
  background: var(--brand-weak); color: var(--brand-dark); font-size: 11.5px;
}
.imp-src-grid {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}
.imp-src-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
/* 来源名称比来源长得多，宽屏占两列；窄屏由断点收回单列 */
.imp-src-field-wide { grid-column: span 2; }
.imp-src-label { font-size: 12px; font-weight: 600; color: var(--text-2); }
.imp-src-select, .imp-src-input { width: 100%; }

/* ---- 挂载默认知识点（可选）—— 紧贴在「试题来源 / 来源名称」那一行的正下方 ----
   上虚线是刻意的：视觉上从属于同一张"整批生效"的卡，
   但语义上和来源是两件事，不能混成一组无差别的输入框。 */
.imp-kn-field {
  display: flex; flex-direction: column; gap: 5px; max-width: 460px;
  margin-top: 11px; padding-top: 11px; border-top: 1px dashed var(--border);
}
.imp-kn-field .imp-src-label { display: inline-flex; align-items: center; gap: 6px; }
.imp-kn-select { max-width: 320px; }
.imp-kn-note { font-size: 12px; color: var(--text-3); line-height: 1.7; }
/* 「可选」小徽标：**中性灰，别用品牌色** —— 它不是"推荐"，只是"不填也行" */
.imp-opt-badge {
  padding: 1px 8px; border-radius: 999px;
  background: var(--surface-3); color: var(--text-3);
  font-size: 11px; font-weight: 500;
}
/* 卡片最后一段说明自带上分隔线 —— 否则会和上面「挂载默认知识点」的说明
   连成一整段灰字，两条不同主题的说明看起来像同一句话（截图里很明显）。 */
.imp-src-note {
  margin-top: 11px; padding-top: 10px; border-top: 1px dashed var(--border);
  font-size: 12px; color: var(--text-3); line-height: 1.7;
}

/* ---------------- 进度 ---------------- */
.imp-progress { display: none; margin-top: 14px; }
.imp-progress.is-on { display: block; }

/* ---------------- ② 顶部汇总条 ---------------- */
.imp-summary {
  display: grid; gap: 8px; margin-bottom: 12px;
  grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
}
.imp-sum {
  display: flex; align-items: baseline; gap: 8px;
  padding: 9px 12px;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
}
.imp-sum-num { font-size: 17px; font-weight: 650; font-variant-numeric: tabular-nums; }
.imp-sum-txt { font-size: 12.5px; color: var(--text-2); }
.imp-sum.is-warn { border-color: var(--warn); background: var(--warn-weak); }
.imp-sum.is-warn .imp-sum-num { color: var(--warn); }

/* ---------------- 工具条 ---------------- */
.imp-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 12px;
  padding: 10px 12px;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2);
}
.imp-left, .imp-right { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.imp-check { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; }
.imp-tip { font-size: 12.5px; color: var(--text-3); }
.imp-select, .imp-type {
  padding: 5px 8px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text); font-size: 13px; font-family: inherit;
}
.imp-select:focus, .imp-type:focus { outline: 2px solid var(--brand-weak); border-color: var(--brand); }
/* 逐题难度下拉：别抢走题型的宽度，但也别窄到把"较易"折行 */
.imp-diff { min-width: 92px; }
.imp-recheck { flex: 0 0 auto; }

/* ---- 工具条里的批级配置（第二轮）----
   .imp-toolbar 是 flex-wrap，这里用 flex-basis:100% 强制独占一整行，
   **不靠 order / 绝对定位** —— 拖动条本身的两行布局不受影响。 */
.imp-toolbar-src {
  flex: 1 1 100%;
  display: flex; flex-direction: column; gap: 7px;
  margin-top: 2px; padding-top: 9px; border-top: 1px dashed var(--border);
}
/* 两个 .imp-src-inline 天然上下堆叠（父级是 column）——
   所以「挂载默认知识点」就落在「试题来源 / 来源名称」行的正下方 */
.imp-src-inline { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; }
.imp-src-inline .imp-src-select { flex: 0 0 auto; width: 132px; }
.imp-src-inline .imp-src-input { flex: 1 1 200px; min-width: 140px; }
.imp-src-inline .imp-kn-select { flex: 0 0 auto; width: 260px; max-width: 100%; }
/* 挂载那行的徽标跟着标签走，不要被 select 的基线拖低 */
.imp-kn-inline .imp-opt-badge { align-self: center; }

/* ---------------- 提示条 ---------------- */
.imp-warns:empty { display: none; }
.imp-warn-list { margin: 0 0 12px; padding: 10px 14px 10px 30px; list-style: disc;
  border: 1px solid var(--warn); border-radius: var(--radius); background: var(--warn-weak); }
.imp-warn { font-size: 12.5px; color: var(--warn); line-height: 1.75; }

/* ---------------- 题卡 ---------------- */
.imp-list { display: flex; flex-direction: column; gap: 14px; }
.imp-card {
  padding: 14px 16px 16px;
  border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface);
  box-shadow: var(--shadow-1);
}
.imp-card.is-muted { opacity: .5; }

.imp-card-head {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px dashed var(--border);
}
.imp-pick { display: inline-flex; align-items: center; cursor: pointer; }
.imp-idx { font-family: var(--mono); font-size: 12.5px; color: var(--text-3); }
.imp-flags { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }
.imp-flag {
  padding: 2px 8px; border-radius: 999px;
  font-size: 11.5px; line-height: 1.7; white-space: nowrap;
  background: var(--surface-2); color: var(--text-2); border: 1px solid transparent;
}
.imp-flag.is-ok { background: var(--ok-weak); color: var(--ok); }
.imp-flag.is-warn { background: var(--warn-weak); color: var(--warn); border-color: var(--warn); }
.imp-flag.is-bad { background: var(--bad-weak); color: var(--bad); border-color: var(--bad); }
.imp-flag.is-muted { background: transparent; color: var(--text-3); }

.imp-options {
  display: grid; gap: 2px 16px; margin-top: 10px;
  grid-template-columns: repeat(auto-fit, minmax(min(430px, 100%), 1fr));
}
.imp-option { display: flex; align-items: baseline; gap: 7px; min-width: 0; }
.imp-option-label { flex: 0 0 auto; font-weight: 600; color: var(--text-2); }
.imp-option-body { flex: 1 1 auto; min-width: 0; }

/* ---------------- 字段（题干 / 选项 / 答案 / 解析） ---------------- */
.imp-field { margin-top: 10px; }
.imp-field:first-child { margin-top: 0; }
.imp-field-label {
  display: inline-block; margin-bottom: 4px;
  padding: 0 7px; border-radius: 4px;
  background: var(--surface-2); color: var(--text-2);
  font-size: 12px; font-weight: 600;
}

/* ---- 双态可编辑字段（需求⑤）----
   渲染态与源码态**同时存在**：切到源码态时渲染态不消失，
   边打字边往下看渲染结果 —— 这是这一页用得最多的动作。
   「编辑」按钮放在右上角（.imp-ef-tools 的 justify-content:flex-end），
   与页面底部提示条里写的"字段右上角"一致。 */
.imp-ef { min-width: 0; }
.imp-ef-tools { display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
.imp-ef-btn {
  padding: 1px 9px; line-height: 1.7;
  border: 1px dashed var(--border-strong); border-radius: 999px;
  background: transparent; color: var(--text-3);
  font-size: 11.5px; font-family: inherit; cursor: pointer;
}
.imp-ef-btn:hover { color: var(--brand); border-color: var(--brand); }
.imp-ef-edit { display: none; margin-top: 4px; }
.imp-ef-edit.is-on { display: block; }
.imp-ef-area, .imp-ef-input {
  display: block; width: 100%; box-sizing: border-box;
  padding: 7px 10px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text);
  font-size: 13px; font-family: var(--mono); line-height: 1.7;
  resize: vertical;
}
.imp-ef-area:focus, .imp-ef-input:focus { outline: 2px solid var(--brand-weak); border-color: var(--brand); }
.imp-ef-view { margin-top: 4px; font-size: 14px; line-height: 1.95; word-break: break-word; }
.imp-ef-empty { color: var(--text-3); font-size: 12.5px; }
.imp-ef-stem .imp-ef-view { font-size: 14.5px; }
.imp-ef-answer .imp-ef-view { font-size: 14px; }
.imp-ef-parse .imp-ef-view { font-size: 13.5px; color: var(--text-2); }

/* ---------------- 查重条（需求④：与校对同屏，不用等到点导入） ---------------- */
.imp-dup {
  margin: 0 0 14px; padding: 14px 16px;
  border: 1px solid var(--warn); border-radius: var(--radius-lg); background: var(--warn-weak);
}
/* 没查到重复时整条换成中性色：这里用绿色反而像"出错了"，它只是"干净" */
.imp-dup.is-clean { border-color: var(--border); background: var(--surface-2); }
.imp-dup.is-clean .imp-dup-title { color: var(--text-2); }
.imp-dup-title { font-size: 14px; font-weight: 600; color: var(--warn); }
.imp-dup-hint { margin-top: 5px; font-size: 12.5px; color: var(--text-2); line-height: 1.75; }

/* ---------------- ③ 报告 ---------------- */
.imp-report { margin-bottom: 16px; }
.imp-report-nums {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
}
.imp-report-num {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 14px 10px;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
}
.imp-report-value { font-size: 24px; font-weight: 650; font-variant-numeric: tabular-nums; }
.imp-report-label { font-size: 12.5px; color: var(--text-3); }
.imp-report-num.is-ok .imp-report-value { color: var(--ok); }
.imp-report-num.is-warn .imp-report-value { color: var(--warn); }
.imp-report-num.is-bad .imp-report-value { color: var(--bad); }

/* 报告顶部的配置回显：来源 / 来源名称 / 默认知识点 / 默认难度 */
.imp-report-meta { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 12px; }
.imp-chip {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 3px 10px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface-2);
  font-size: 12px; line-height: 1.7;
}
.imp-chip-k { color: var(--text-3); }
.imp-chip-v { color: var(--brand); font-weight: 600; }
/* 「未挂载（可选）」用灰字：没挂载是**正常状态**，不是待办，别用品牌色催人 */
.imp-chip.is-none .imp-chip-v { color: var(--text-3); font-weight: 500; }

.imp-report-group { margin-bottom: 14px; }
.imp-report-group-title { font-size: 13px; font-weight: 600; color: var(--text-2); margin-bottom: 6px; }
.imp-report-group.is-skip .imp-report-group-title { color: var(--warn); }
.imp-report-group.is-fail .imp-report-group-title { color: var(--bad); }
.imp-report-list { margin: 0; padding: 0; list-style: none; }
.imp-report-item {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px;
  padding: 7px 0; border-bottom: 1px solid var(--border);
  font-size: 13px; line-height: 1.7;
}
.imp-report-idx { flex: 0 0 auto; font-family: var(--mono); font-size: 12.5px; color: var(--text-3); }
.imp-report-link { flex: 0 0 auto; color: var(--brand); text-decoration: none; font-size: 12.5px; }
.imp-report-link:hover { text-decoration: underline; }
.imp-report-reason { flex: 0 0 auto; color: var(--text-2); }
.imp-report-brief { min-width: 0; color: var(--text-3); font-size: 12.5px; }

/* 报告里的答案也走 KaTeX 渲染（需求③）—— 填空题 / 解答题光看源码根本核不了 */
.imp-report-ans {
  display: inline-flex; align-items: baseline; gap: 6px;
  min-width: 0; max-width: 100%;
}
.imp-report-ans-k {
  flex: 0 0 auto; padding: 0 6px; border-radius: 4px;
  background: var(--surface-3); color: var(--text-3); font-size: 11.5px;
}
.imp-report-ans-v { min-width: 0; font-size: 13.5px; word-break: break-word; }

.imp-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }

/* 题卡列表下面的一行说明 */
.imp-hint { margin: 14px 0 0; font-size: 12.5px; color: var(--text-3); line-height: 1.75; }

@media (max-width: 600px) {
  .imp-steps { flex-direction: column; gap: 8px; }
  .imp-step-txt span { display: none; }
  .imp-card { padding: 12px 13px 14px; }
  .imp-toolbar { justify-content: flex-start; }
  .imp-right { width: 100%; }
  .imp-right .btn { flex: 1 1 auto; }
  /* 窄屏：来源名称不再占两列；两个下拉都放开宽度，别留半屏空白 */
  .imp-src-field-wide { grid-column: auto; }
  .imp-kn-field { max-width: none; }
  .imp-kn-select { max-width: 100%; }
  .imp-src-inline .imp-src-select,
  .imp-src-inline .imp-kn-select { width: 100%; flex: 1 1 160px; }
  /* 窄屏选项一行一项（与题库页的"纵向"布局口径一致） */
  .imp-options { grid-template-columns: 1fr; }
}

/* ============================================================
   试卷 / 组卷 / 卷面
   ------------------------------------------------------------
   三页共用这一段：组卷台（#/practice）、我的试卷（#/papers）、
   卷面（#/paper/:id）。

   · .paper-sheet 是"印出来的那张纸"：屏幕上模拟 A4 观感，
     打印时由 @page 出 A4，且只留卷面（工具条 / 设置折叠块不印）
   · 卷面里的题**不套 .qitem 卡片**（那是屏幕阅读用的），
     改用 .paper-q 的版式流；选项容器 .qoptions 去掉虚线边框
   ============================================================ */

/* 跨满整行：卷头里"注意事项"是 textarea，不该挤在半列里 */
.field-span2 { grid-column: 1 / -1; }

/* ---------------- 组卷台 ---------------- */

.paper-card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
}
.paper-card-title { font-size: 15px; font-weight: 600; color: var(--text); }
.paper-card-hint { font-size: 12.5px; color: var(--text-3); }

/* 卷头超长提示：没超长时完全不占位 */
.paper-err { display: none; }
.paper-err.is-on {
  display: block; padding: 9px 12px; border-radius: var(--radius-sm);
  border: 1px solid #f3c3c5; background: var(--bad-weak);
  color: var(--bad); font-size: 13px; line-height: 1.7;
}

/* 组卷方式：两个页签，选中态与下方内容连成一片 */
.paper-tabs { display: flex; flex-wrap: wrap; gap: 6px; border-bottom: 1px solid var(--border); }
.paper-tab {
  margin-bottom: -1px; padding: 8px 14px;
  border: 1px solid transparent; border-bottom: none;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  background: transparent; color: var(--text-2);
  font-family: inherit; font-size: 13.5px; font-weight: 500;
  cursor: pointer; transition: background .15s, color .15s;
}
.paper-tab:hover { color: var(--brand); }
.paper-tab.is-on {
  background: var(--surface); border-color: var(--border);
  border-bottom-color: var(--surface);
  color: var(--brand); font-weight: 600;
}
.paper-panes { padding-top: 6px; }
.paper-pane { display: none; }
.paper-pane.is-on { display: block; }

/* 配比表：表头与行共用同一套列宽；"可用题数"是每行的哨兵查询结果 */
.sec-list { display: flex; flex-direction: column; gap: 8px; }
.sec-head, .sec-row {
  display: grid;
  grid-template-columns: minmax(0, 2.2fr) 92px 92px minmax(0, 1.5fr) 108px 58px;
  gap: 10px; align-items: center;
}
.sec-head { padding: 0 2px; font-size: 12.5px; font-weight: 600; color: var(--text-3); }
.sec-cell { min-width: 0; }
/* 表格里的控件整体收一号，行高与删除按钮对齐 */
.sec-cell .field-input { width: 100%; min-height: 34px; padding: 5px 9px; font-size: 13.5px; }
.sec-cell select.field-input { padding-right: 26px; }
.sec-cell-probe { display: flex; align-items: center; }
.sec-probe { font-size: 12.5px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.sec-probe.is-warn { color: var(--warn); font-weight: 600; }
.sec-del { flex: 0 0 auto; padding: 0 9px; }
.sec-foot { margin-top: 12px; }
.sec-head-note { margin-bottom: 12px; font-size: 12.5px; color: var(--text-3); line-height: 1.75; }
/* 这两个下拉没有额外样式，但类名出现在 class 字面量里（check-css 要求有定义） */
.sec-mode, .sec-diff { min-width: 0; }

/* 手动挑题：一行一道，可上下调序 */
.pick-list { display: flex; flex-direction: column; gap: 8px; }
.pick-row {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 12px; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--surface);
}
.pick-idx {
  flex: 0 0 auto; width: 26px; height: 26px;
  display: grid; place-items: center; border-radius: 999px;
  background: var(--brand-weak); color: var(--brand-dark);
  font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.pick-text { flex: 1 1 auto; min-width: 0; display: flex; align-items: baseline; gap: 8px; }
.pick-excerpt {
  flex: 1 1 auto; min-width: 0; font-size: 13px; color: var(--text-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pick-ops { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; }
.pick-op { min-width: 32px; padding: 0 8px; }

/* 卷面设置：勾选项 */
.set-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: 8px 18px; }
.set-item { display: flex; align-items: flex-start; gap: 9px; padding: 4px 0; cursor: pointer; }
.set-check { flex: 0 0 auto; width: 16px; height: 16px; margin: 1px 0 0; accent-color: var(--brand); cursor: pointer; }
.set-text { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.set-label { font-size: 13.5px; color: var(--text); }
.set-hint { font-size: 12px; color: var(--text-3); }

/* 合计条（贴在 .start-bar 里） */
.paper-sum { display: flex; flex-wrap: wrap; align-items: baseline; gap: 16px; font-size: 14px; color: var(--text-2); }
.paper-sum-item { display: inline-flex; align-items: baseline; gap: 3px; }
.paper-sum-item strong { font-size: 17px; color: var(--brand-dark); font-variant-numeric: tabular-nums; }
.paper-sum-warn { color: var(--bad); font-size: 13px; font-weight: 600; }

/* ---------------- 卷面页 ---------------- */

.paper-tools {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap; margin-bottom: 14px;
}
.paper-tools-left, .paper-tools-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* 导出公式格式下拉：压到与 tool-bar 上那排 btn-sm 同高同圆角。
   基类仍是 .field-input（自带下拉箭头与焦点环），这里只改宽度/高度/字号。 */
.paper-fmt {
  width: auto; min-height: 30px; padding-top: 0; padding-bottom: 0;
  font-size: 13px; border-radius: 6px;
}

/* 卷面设置折叠块：summary 复用 .paper-card-title 的字号 */
.paper-edit { padding: 0; }
.paper-edit > summary {
  display: flex; align-items: center; gap: 8px;
  padding: 14px 18px; list-style: none; cursor: pointer;
}
.paper-edit > summary::-webkit-details-marker { display: none; }
.paper-edit > summary::before { content: '▸'; color: var(--text-3); font-size: 12px; }
.paper-edit[open] > summary::before { content: '▾'; }
.paper-edit > .field-grid, .paper-edit > .set-grid { padding: 0 18px; }
.paper-edit-foot { display: flex; justify-content: flex-end; gap: 10px; padding: 12px 18px 16px; }

/* 卷面：屏幕上模拟一张纸 */
.paper-host { margin-top: 16px; }
.paper-sheet {
  max-width: 820px; margin: 0 auto;
  padding: 34px 42px 46px;
  background: #fff; color: #111;
  border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  line-height: 1.85;
}
.paper-head { padding-bottom: 14px; text-align: center; }
.paper-title { margin: 0 0 6px; font-size: 21px; font-weight: 700; letter-spacing: .5px; }
.paper-head-line { font-size: 14px; color: #333; }
.paper-head-meta {
  display: flex; justify-content: center; flex-wrap: wrap; gap: 0 18px;
  margin-top: 4px; font-size: 13.5px; color: #555;
}
.paper-student {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 26px;
  margin-top: 12px; font-size: 14px; color: #222;
}
/* 填写的横线由样式补，三栏等长（不靠用户输入下划线） */
.paper-blank { white-space: nowrap; }
.paper-blank::after { content: '＿＿＿＿＿＿'; letter-spacing: 1px; }
.paper-notice {
  margin-top: 14px; padding: 10px 14px; text-align: left;
  border: 1px solid #d9d9d9; border-radius: 4px; background: #fafafa;
  font-size: 13px; color: #333; line-height: 1.8;
}
.paper-notice-title { margin-bottom: 2px; font-weight: 600; }
.paper-notice-body { white-space: pre-wrap; }

.paper-sec-title {
  display: flex; align-items: baseline; gap: 8px;
  margin: 22px 0 10px; font-size: 16px; font-weight: 700;
}
.paper-sec-score { font-size: 13.5px; font-weight: 400; color: #555; }
.paper-body { margin-top: 4px; }
.paper-q { margin: 0 0 14px; }
.paper-q-head { display: flex; align-items: baseline; gap: 6px; font-weight: 600; }
.paper-q-idx { flex: 0 0 auto; }
.paper-q-score { font-size: 13px; font-weight: 400; color: #555; }
.paper-q-body { min-width: 0; }
.paper-q-missing { color: var(--bad); font-size: 13.5px; }
/* 卷面上的选项不要卡片感：去掉分隔虚线与内边距 */
.paper-q .qoptions { padding: 6px 0 0 22px; border-top: none; gap: 6px 22px; }

/* 含答案版 */
.paper-answer { margin-top: 26px; border-top: 1px dashed var(--border-strong); }
.paper-answer.is-newpage { break-before: page; }
.paper-ans-item { margin: 0 0 10px; }
.paper-ans-line { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.paper-ans-idx { flex: 0 0 auto; font-weight: 600; }
.paper-ans-body { min-width: 0; }
.paper-ans-empty { color: var(--text-3); font-size: 13.5px; }
.paper-ans-parse { margin: 4px 0 0 24px; font-size: 13.5px; color: #444; }
.paper-ans-parse-title { font-weight: 600; color: var(--text-2); }

/* ============================================================
   组卷工作台（手动选题）
   ------------------------------------------------------------
   三栏：左=选题导航（知识目录 + 题型/难度/来源）· 中=筛出来的题 · 右=试题篮。
   与「按题型配比」共用同一套卷头 / 卷面设置 / 合计条 —— 换的只是中段。

   分组键仍是**判分模式**（choice / fill / none），与后端 SECTION_NAME_OF_MODE
   同序同义；右栏「结构」页签按它分段，「分布」页签按它统计。
   ============================================================ */

/* 三栏网格。右栏要够宽：每行都带一个分值输入框 + 两个小按钮 */
.wb {
  display: grid;
  grid-template-columns: 262px minmax(0, 1fr) 342px;
  gap: 14px;
  align-items: start;
}

/* ---- 左栏：选题导航 ---- */
.wb-left { min-width: 0; display: flex; flex-direction: column; gap: 12px; }
/* 知识目录侧栏（共享组件）嵌进工作台：它自带 position:sticky 与上边距
   （题库页要那两个），这里改回普通流式 —— 否则它会脱离左栏、浮在筛选组上面。 */
.wb-left .ktree-side { position: static; margin: 0; }
.wb-left .ktree-card { max-height: 380px; overflow: auto; }

.wb-lcard {
  padding: 12px 13px;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
}
.wb-fgroup + .wb-fgroup { margin-top: 13px; padding-top: 12px; border-top: 1px dashed var(--border); }
.wb-fgroup-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 8px;
}
.wb-fgroup-title { font-size: 13px; font-weight: 600; color: var(--text); }
.wb-fgroup-n { font-size: 12px; font-weight: 400; color: var(--text-3); }
.wb-rc-toggle {
  padding: 0; border: none; background: none;
  color: var(--brand); font-family: inherit; font-size: 12px; cursor: pointer;
}
.wb-rc-toggle:hover { text-decoration: underline; }
.wb-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.wb-chip {
  padding: 3px 10px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); color: var(--text-2);
  font-family: inherit; font-size: 12.5px; line-height: 1.7;
  cursor: pointer; transition: background .13s, border-color .13s, color .13s;
}
.wb-chip:hover { border-color: var(--brand); color: var(--brand); }
.wb-chip.is-on {
  background: var(--brand-weak); border-color: var(--brand);
  color: var(--brand-dark); font-weight: 600;
}
.wb-chip:disabled { opacity: .45; cursor: not-allowed; }

/* ---- 中栏：题池 ---- */
.wb-mid { min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.wb-mid-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  padding: 9px 12px;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface);
}
.wb-mid-stat { font-size: 13px; color: var(--text-2); }
.wb-mid-stat strong { color: var(--brand-dark); font-variant-numeric: tabular-nums; }
.wb-mid-str { font-size: 12.5px; color: var(--text-3); }
.wb-cards { display: flex; flex-direction: column; gap: 10px; }
.wb-empty {
  padding: 30px 16px; text-align: center;
  border: 1px dashed var(--border-strong); border-radius: var(--radius);
  background: var(--surface); color: var(--text-3); font-size: 13.5px; line-height: 1.8;
}
.wb-pager { display: flex; align-items: center; justify-content: center; gap: 8px; }
.wb-page-btn {
  min-width: 34px; height: 32px; padding: 0 10px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text-2);
  font-family: inherit; font-size: 13px; cursor: pointer;
}
.wb-page-btn:hover:not(:disabled) { border-color: var(--brand); color: var(--brand); }
.wb-page-btn:disabled { opacity: .45; cursor: not-allowed; }
.wb-page-btn.is-on { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600; }
.wb-page-info { font-size: 12.5px; color: var(--text-3); font-variant-numeric: tabular-nums; }

/* ---- 右栏：试题篮 ---- */
.wb-right {
  min-width: 0; display: flex; flex-direction: column; gap: 10px;
  position: sticky; top: calc(var(--topbar-h) + 12px);
}
.wb-rtabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); }
.wb-rtab {
  margin-bottom: -1px; padding: 6px 12px;
  border: 1px solid transparent; border-bottom: none;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  background: transparent; color: var(--text-2);
  font-family: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
}
.wb-rtab:hover { color: var(--brand); }
.wb-rtab.is-on {
  background: var(--surface); border-color: var(--border); border-bottom-color: var(--surface);
  color: var(--brand); font-weight: 600;
}
/* ⚠️ 两个类名不能合并：rbody 是右栏的**固定容器**，rinner 是每次重画时塞进去的
   视图根（结构页签 / 分布分析各一个）。同类名嵌套两层会让"数 .wb-rbody"这类断言失真 */
.wb-rbody, .wb-rinner { display: flex; flex-direction: column; gap: 10px; }

/* 一个大题组 */
.wb-group {
  overflow: hidden;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface);
}
.wb-group.is-over { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-weak); }
.wb-group-head {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px;
  background: var(--surface-2); border-bottom: 1px solid var(--border);
}
.wb-group-name {
  flex: 1 1 auto; min-width: 0;
  padding: 3px 6px; border: 1px solid transparent; border-radius: 4px;
  background: transparent; color: var(--text);
  font-family: inherit; font-size: 13px; font-weight: 600;
}
.wb-group-name:hover { border-color: var(--border-strong); }
.wb-group-name:focus { border-color: var(--brand); background: var(--surface); outline: none; }
.wb-group-meta { flex: 0 0 auto; font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }
/* 组内行不重复画卡片边框（组本身已有），行与行之间用虚线分 */
.wb-group .pick-list { padding: 4px 9px 9px; gap: 0; }
.wb-group .pick-row { padding: 7px 1px; border: none; border-radius: 0; background: transparent; }
.wb-group .pick-row + .pick-row { border-top: 1px dashed var(--border); }
.wb-group .pick-row.is-drag { opacity: .4; }
.wb-drag { flex: 0 0 auto; color: var(--text-3); font-size: 13px; cursor: grab; user-select: none; }
.wb-drag:active { cursor: grabbing; }
.wb-score.field-input { flex: 0 0 auto; width: 58px; min-height: 30px; padding: 3px 6px; font-size: 13px; text-align: center; }

/* 分布分析：条形图。⚠️ 值为 0 的组不画最小宽度（否则"空的那一大题"看起来有数据） */
.wb-bars { display: flex; flex-direction: column; gap: 7px; }
.wb-bar { display: grid; grid-template-columns: 104px minmax(0, 1fr) 40px; gap: 8px; align-items: center; }
.wb-bar-lab {
  font-size: 12.5px; color: var(--text-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wb-bar-track { height: 12px; overflow: hidden; border-radius: 999px; background: var(--surface-3); }
.wb-bar-fill { height: 100%; border-radius: 999px; background: var(--brand); transition: width .2s; }
.wb-bar-fill.is-alt { background: var(--purple); }
.wb-bar-val { font-size: 12.5px; color: var(--text-3); text-align: right; font-variant-numeric: tabular-nums; }

/* ---- 工作台的窄屏：先折左栏，再折右栏 ---- */
@media (max-width: 1100px) {
  .wb { grid-template-columns: minmax(0, 1fr) 330px; }
  .wb-left { grid-column: 1 / -1; }
  .wb-left .ktree-card { max-height: 300px; }
}
@media (max-width: 860px) {
  .wb { grid-template-columns: minmax(0, 1fr); }
  .wb-right { position: static; }
  .wb-left .ktree-card { max-height: 260px; }
}

/* ---------------- 窄屏 ---------------- */
@media (max-width: 780px) {
  .paper-sheet { padding: 22px 16px 30px; }
  /* 配比表在窄屏改成两列堆叠：控件一行、"可用题数"与删除一行 */
  .sec-head { display: none; }
  .sec-row {
    grid-template-columns: 1fr 1fr;
    padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  }
  .sec-cell-probe { grid-column: 1 / 2; }
  .sec-del { grid-column: 2 / 3; justify-self: end; }
  .pick-text { flex-wrap: wrap; gap: 2px 8px; }
  .paper-tools-left, .paper-tools-right { width: 100%; }
}

/* ---------------- 打印 ----------------
   卷面页只有 .paper-sheet 该印出来：工具条、设置折叠块、导航与页脚全去掉。
   @page 只在分页媒介生效，屏幕浏览不受影响。 */
@page { size: A4; margin: 14mm 12mm; }

@media print {
  .paper-tools, .paper-edit, .start-bar, .toast-host, .pickbar { display: none !important; }
  body { background: #fff; }
  .app { max-width: none; padding: 0; }
  .paper-host { margin: 0; }
  .paper-sheet {
    max-width: none; margin: 0; padding: 0;
    border: none; border-radius: 0; box-shadow: none;
  }
  /* 题与答案尽量不跨页断开；大题标题不落单在页脚 */
  .paper-q, .paper-ans-item, .paper-notice, .paper-q .qoptions { break-inside: avoid; }
  .paper-sec-title { break-after: avoid; }
}

