/* ============================================================
   学情报表页（/report.html · 2026-09-21 加 ✓ 见 `Plan/5` §9.46）

   ⚠️ 本文件只管**本页特有**的东西（表格 / 卡点榜 / 元信息行 ✓）——
      外壳（.app / .topbar / .console / .panel / .btn / .chip / .options）
      一律来自 `admin-common.css` 与 `style.css` ✗ 别在这里重写 ✓
   ⚠️ 颜色一律引用变量（`theme.css` 的 --text / --border / --warn …）✗ 不写死色值 ✓
   ============================================================ */

/* 元信息行：截至时刻 + 汇总数字（★"截至"必须显眼 ✗ —— 报表最忌不知道数据多新 ✓） */
.report__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 6px 0 10px;
  font-size: 12px;
  color: var(--text-dim);
}

.report__totals { display: flex; flex-wrap: wrap; gap: 6px; }

.report__h3 {
  margin: 14px 0 6px;
  font-size: 13px;
  letter-spacing: .5px;
}

.report__sub {
  margin-left: 6px;
  font-size: 11px;
  font-weight: 400;
  color: var(--text-dim);
}

/* ---------- 卡点榜 ---------- */
.report__stuck {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.stuck {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-panel-2);
  font-size: 12px;
}

.stuck__idx {
  width: 18px;
  color: var(--text-dim);
  font-family: var(--mono);
}

.stuck__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 通过率色条：越低越红 —— 一眼看出"这题有问题" ✓（数值同时给出 ✓ 不只靠颜色 ✗） */
.stuck__rate {
  min-width: 46px;
  text-align: right;
  font-family: var(--mono);
  font-weight: 600;
}
.stuck__rate[data-level="bad"] { color: var(--danger); }
.stuck__rate[data-level="mid"] { color: var(--warn); }

/* ---------- 表格 ---------- */
.report__scroll {
  max-height: 42vh;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
}

.rpt {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}

.rpt th, .rpt td {
  padding: 6px 9px;
  border-bottom: 1px solid var(--border);
  text-align: left;
  white-space: nowrap;
}

.rpt thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg-panel);
  color: var(--text-dim);
  font-weight: 600;
  cursor: pointer;
  user-select: none;
  /* ⚠️★表头吸顶时**边框会消失** ✗ —— `border-collapse: collapse` + `position: sticky` 的老毛病：
     下边框属于单元格、会跟着滚走 ⇒ 表头与第一行之间那条线**滚一下就没了** ✓
     ⇒ 用 `box-shadow` 画这条线（它跟着元素走 ✓ 不参与折叠 ✓）
     ⚠️ 现在班里只有 1 行，**看不出来** ✗ ⇒ 是"人多了才会暴露"的那类坑 ✓ */
  box-shadow: inset 0 -1px 0 var(--border);
}
.rpt thead th[data-nosort] { cursor: default; }

/* 数字列右对齐 + 等宽：竖着扫一列才快 ✓ */
.rpt td.num { text-align: right; font-family: var(--mono); }

/* ⚠️★**表头也要一起右对齐** ✗ —— 2026-09-21 真机实测踩到：
   只给 `td.num` 写右对齐 ⇒ 表头仍被上方 `.rpt th, .rpt td { text-align: left }` 管着
   ⇒ **表头在左、数字在右**，看起来"没对齐" ✓（实测 `th_align=left / td_align=right` ✗）
   ⚠️ 加规则时**表头与单元格必须成对** ✗：这两行是一个整体，删其一就会退回原样
   （字体不加等宽：中文表头用等宽会显得松散 ✓，数字由 `td.num` 保证对齐足够 ✓） */
.rpt th.num { text-align: right; }

/* ★补通行标黄 ✗ —— 老师补过的学生**不许**看起来像学会了 ✓ */
.rpt tr.is-helped td { background: rgba(var(--accent-rgb), .10); }

/* ⚠️★`补` 徽标的两个落点**都要覆盖** ✗：
   ① 班级表里（`td` 内 ✓）② ★明细里的任务头（**不在表格内** ✓）
   原先只写了 `.rpt td .helped` ✗ ⇒ 明细里那个徽标会是**没有样式的裸字** ✓
   （2026-09-21 加明细时踩到 ✓：**复用类名之前先看它的选择器限定在哪儿** ✗） */
.rpt td .helped,
.dtask .helped {
  margin-left: 5px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--warn);
  color: #3a2a00;
  font-size: 10px;
}

/* ★「支线」徽标 ✗（2026-09-22 加 ✓）—— ★它**只出现在明细的任务头**里 ✓
   （班级表**不列支线** ✓）⇒ 所以这里**只需要 `.dtask` 一个选择器** ✓ ——
   ⚠️ 与上面 `.helped` 的处境**不同** ✗（那个要在两处出现 ✓ 见那条注释 ✓）
   ⚠️ 颜色刻意用**中性的强调色** ✓（**不用** `--warn` ✗）：支线**不是**"要留意的异常" ✓
      —— 它是**课后练习** ✓；用警告色会误导老师以为**出了问题** ✓ */
.dtask .dtask__side {
  margin-left: 5px;
  padding: 0 5px;
  border-radius: 999px;
  background: rgba(var(--accent-rgb), .18);
  color: var(--accent);
  font-size: 10px;
}

/* "还没注册"：中性灰，不吓人也不忽略 ✓ */
.rpt tr.is-unregistered td { color: var(--text-dim); }

.report__fold {
  margin-top: 14px;
}

/* ⚠️ 只有**已鉴权后**的失败才用红字 ✓（未鉴权一律中性文案 —— 与四页同一原则 ✗） */
.empty-hint.is-error { color: var(--danger); }
.report__fold > summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--text);
}

/* ============================================================
   学生明细（P1 下钻 ✓ 2026-09-21 加 ✓ 见 `Plan/5` §9.46 ⑦）
   ============================================================ */

/* ★可点的行必须**看起来**能点 ✗ —— 否则这个功能没人会发现 ✓ */
.rpt tbody tr[data-player] { cursor: pointer; }
.rpt tbody tr[data-player]:hover td { background: rgba(var(--accent-rgb), .06); }
.rpt tbody tr.is-selected td { background: rgba(var(--accent-rgb), .15); }
/* 整行可点 ⇒ 也要能用键盘 ✓（行上有 `tabindex="0"` ✓） */
.rpt tbody tr[data-player]:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

#detailWrap { margin-top: 16px; }
.report__close { margin-left: 8px; padding: 1px 9px; font-size: 11px; }

.dtask { margin: 10px 0 14px; }
.dtask__head { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 600; }
.dtask__cleared { color: var(--ok); font-size: 11px; }
.dtask__qs {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.dq {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 9px;
  border: 1px solid var(--border);
  border-left-width: 3px;          /* 左侧色条：三态一眼可辨 ✓ */
  border-radius: 6px;
  background: var(--bg-panel-2);
  font-size: 12px;
}
.dq__seq { min-width: 76px; color: var(--text-dim); font-family: var(--mono); }
.dq__type { min-width: 50px; color: var(--text-dim); }
.dq__state { min-width: 66px; font-weight: 600; }

/* ★三态用**语义色** ✓（跨主题固定 —— 与 `.verdict` 同一条原则 ✓）
   ⚠️ 颜色只是**加强** ✗，文字（已通过 / 试过没过 / 未碰）在任何主题下都在 ✓ */
.dq[data-state="passed"] { border-left-color: var(--ok); }
.dq[data-state="passed"] .dq__state { color: var(--ok); }
.dq[data-state="tried"] { border-left-color: var(--danger); }
.dq[data-state="tried"] .dq__state { color: var(--danger); }
/* ⚠️ 未碰 = **中性灰** ✓ —— 它既不是成功也不是错误，只是"还没到那儿" ✓ */
.dq[data-state="untouched"] { border-left-color: var(--border); }
.dq[data-state="untouched"] .dq__state { color: var(--text-dim); }

/* ---------- OJ 提交列表 ---------- */
.dsubs {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.dsub {
  padding: 7px 9px;
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: 6px;
  background: var(--bg-panel-2);
  font-size: 12px;
}
.dsub[data-ac="true"] { border-left-color: var(--ok); }
.dsub[data-ac="false"] { border-left-color: var(--danger); }
.dsub__head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.dsub__status { font-weight: 600; }
.dsub[data-ac="true"] .dsub__status { color: var(--ok); }
.dsub[data-ac="false"] .dsub__status { color: var(--danger); }

.dsub__fold { margin-top: 5px; }
.dsub__fold > summary { cursor: pointer; font-size: 11px; color: var(--text-dim); }
.dsub__code {
  margin: 5px 0 0;
  padding: 8px 10px;
  max-height: 260px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-panel);
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.6;
  white-space: pre-wrap;
  /* ★学生代码可能有**超长行** ✗ ⇒ 不强制换行会把面板撑破 ✓ */
  word-break: break-all;
}
