/* ============================================================
   首页 / 作业中心 —— 组件样式
   ------------------------------------------------------------
   设计规范套用 **darwin-ui**（macOS 风格、玻璃拟态）。
   Token 全部照抄其 dist/darwin-ui.css，来源：
     npm pack @pikoloo/darwin-ui@2.1.0  →  package/dist/darwin-ui.css
   官方文档 https://darwin-ui.mandalsuraj.com

   ⚠️ **字号只许用下面这 6 级，不要自己写 font-size: 0.83rem 这种数**。
      2026-09-29 用户反馈「字一下子小一下子大」—— 根因就是第一版这里
      随手写了 12 种字号（0.78 / 0.8 / 0.83 / 0.84 / 0.85 / 0.9 / 0.95 /
      1 / 1.05 / 1.08 / 1.3 / 1.4），毫无规律。darwin-ui 只有 6 级，
      每级有明确语义，见下方 --fs-* 的注释。

   为什么单独起一档 --fs-* 而不是直接用 --text-*：
     本文件与 Bootstrap（JupyterHub 自带）同处一页，Bootstrap 也定义了一套
     --bs-* 变量。为避免与 darwin 的 --text-* 语义混淆，这里用 --fs-* 前缀，
      但**取值与 darwin-ui 完全一致**（0.75/0.875/1/1.125/1.25/1.5）。
   ============================================================ */

/* ------------------------------------------------------------
   Token 定义在 custom-theme.css 的 :root（基础样式表）。
   本文件只补充它没有的几组：圆角、间距、语义色。
   ------------------------------------------------------------ */
:root {
  /* ---------- 圆角（darwin-ui，基准 --radius: 0.75rem） ---------- */
  --r-sm: 8px;    /* calc(0.75rem - 4px) */
  --r-md: 10px;   /* calc(0.75rem - 2px) */
  --r-lg: 12px;   /* 基准 */
  --r-xl: 16px;   /* 基准 + 4px */

  /* ---------- 间距（darwin-ui --spacing: 0.25rem 的倍数） ---------- */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.25rem;
  --sp-6: 1.5rem;
  --sp-8: 2rem;

  /* ---------- 语义色（darwin-ui） ---------- */
  --surface: hsl(240 5% 6%);             /* --card */
  --surface-hover: hsl(240 3.7% 15.9%);  /* --accent */
  --ok: #10b981;                         /* --accent-green */
  --warn: #f97316;                       /* --accent-orange */
  --danger: #ef4444;
  --info: #3b82f6;                       /* --accent-blue */
}

/* ============================================================
   顶部：身份 + 操作
   ============================================================ */
.db-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
  margin-bottom: var(--sp-6);
  padding: var(--sp-6);
  border-radius: var(--r-xl);
  /* 玻璃拟态：darwin-ui 的招牌。半透明底 + 背景模糊 + 极淡描边 */
  border: 1px solid var(--line-default);
  background: color-mix(in srgb, var(--surface) 60%, transparent);
  backdrop-filter: blur(20px) saturate(1.6);
  -webkit-backdrop-filter: blur(20px) saturate(1.6);
}

.db-id {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-width: 0;
}

.db-avatar {
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-lg);
  font-weight: 600;
  color: #fff;
  background: linear-gradient(135deg, var(--ec-accent) 0%, var(--ec-accent-2) 100%);
  box-shadow: 0 6px 18px rgba(124, 92, 255, 0.35);
}

.db-idtext { min-width: 0; }

.db-hello {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-xl);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--fg-primary);
}

.db-sub {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--fg-tertiary);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

.db-dot {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.5;
}

.db-actions {
  display: flex;
  gap: var(--sp-2);
  flex-wrap: wrap;
}

/* 按钮：高度统一 36px，字号统一 --fs-sm */
.db-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  height: 36px;
  padding: 0 var(--sp-4);
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  font-weight: 500;
  border: 1px solid transparent;
  transition: background 0.16s ease, border-color 0.16s ease, transform 0.12s ease;
}
.db-btn:hover { transform: translateY(-1px); }

.db-btn-primary {
  color: #fff;
  background: linear-gradient(135deg, var(--ec-accent) 0%, var(--ec-accent-2) 100%);
  box-shadow: 0 4px 14px rgba(124, 92, 255, 0.3);
}
.db-btn-primary:hover { color: #fff; box-shadow: 0 6px 18px rgba(124, 92, 255, 0.4); }

.db-btn-ghost {
  color: var(--fg-secondary);
  border-color: var(--line-default);
  background: transparent;
}
.db-btn-ghost:hover {
  color: var(--fg-primary);
  background: var(--surface-hover);
}

/* ============================================================
   状态指标
   ============================================================ */
.db-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-6);
}

.db-metric {
  padding: var(--sp-4);
  border-radius: var(--r-lg);
  border: 1px solid var(--line-subtle);
  background: color-mix(in srgb, var(--surface) 50%, transparent);
}

.db-metric-label {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-2);
  font-size: var(--fs-xs);
  color: var(--fg-tertiary);
}

.db-metric-value {
  font-size: var(--fs-lg);
  font-weight: 600;
  color: var(--fg-primary);
}

.db-tag {
  display: inline-block;
  padding: 2px var(--sp-2);
  border-radius: 999px;
  font-size: var(--fs-xs);
  font-weight: 500;
}
.db-tag-on  { color: var(--ok); background: color-mix(in srgb, var(--ok) 16%, transparent); }
.db-tag-off { color: var(--fg-quaternary); background: var(--line-subtle); }

/* ============================================================
   面板
   ============================================================ */
.db-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--sp-4);
  margin-bottom: var(--sp-6);
}

.db-panel {
  padding: var(--sp-6);
  margin-bottom: var(--sp-4);
  border-radius: var(--r-xl);
  border: 1px solid var(--line-default);
  background: color-mix(in srgb, var(--surface) 55%, transparent);
  backdrop-filter: blur(20px) saturate(1.5);
  -webkit-backdrop-filter: blur(20px) saturate(1.5);
}

.db-panel-wide { width: 100%; }

.db-panel-title {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-lg);
  font-weight: 600;
  color: var(--fg-primary);
}

.db-panel-desc {
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--fg-tertiary);
}

.db-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--sp-4);
}
.db-list li {
  display: flex;
  gap: var(--sp-3);
  align-items: flex-start;
}
.db-list li > i {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border-radius: var(--r-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-sm);
  color: #fff;
  background: linear-gradient(135deg, var(--ec-accent) 0%, var(--ec-accent-2) 100%);
}
.db-list li strong {
  display: block;
  margin-bottom: 2px;
  font-size: var(--fs-base);
  font-weight: 500;
  color: var(--fg-secondary);
}
.db-list li span {
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--fg-tertiary);
}

.db-tags { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.db-tagline {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-3);
  border-radius: 999px;
  font-size: var(--fs-sm);
  color: var(--fg-secondary);
  border: 1px solid var(--line-subtle);
  background: var(--line-subtle);
}

.db-table-wrap { overflow-x: auto; }
.db-table {
  margin: 0;
  font-size: var(--fs-sm);
}
.db-table > :not(caption) > * > * { background: transparent; }
.db-table th {
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--fg-tertiary);
  border-bottom-color: var(--line-default) !important;
}
.db-table td {
  color: var(--fg-secondary);
  border-bottom-color: var(--line-subtle) !important;
  vertical-align: middle;
}

.db-foot,
.ec-home-foot {
  margin-top: var(--sp-8);
  padding-top: var(--sp-4);
  font-size: var(--fs-xs);
  color: var(--fg-quaternary);
  border-top: 1px solid var(--line-subtle);
}

/* ============================================================
   作业中心
   ============================================================ */
.ec-warn { color: var(--warn); }

/* 教师端入口卡片 */
.ec-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(224px, 1fr));
  gap: var(--sp-3);
}

.ec-tile {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-5);
  border-radius: var(--r-lg);
  text-decoration: none;
  border: 1px solid var(--line-subtle);
  background: color-mix(in srgb, var(--surface) 45%, transparent);
  transition: background 0.16s ease, border-color 0.16s ease, transform 0.14s ease;
}
.ec-tile:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--ec-accent) 50%, transparent);
  background: var(--surface-hover);
}
.ec-tile > i {
  font-size: var(--fs-lg);
  color: var(--ec-accent);
  margin-bottom: var(--sp-1);
}
.ec-tile > strong {
  font-size: var(--fs-base);
  font-weight: 500;
  color: var(--fg-primary);
}
.ec-tile > span {
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--fg-tertiary);
}

/* 学生端作业表 */
.ec-asg-status {
  min-height: 20px;
  margin-bottom: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--fg-tertiary);
}
.ec-asg-status.is-ok    { color: var(--ok); }
.ec-asg-status.is-warn  { color: var(--warn); }
.ec-asg-status.is-error { color: var(--danger); }

.ec-asg-empty {
  padding: var(--sp-5) 0;
  text-align: center;
  font-size: var(--fs-sm);
  color: var(--fg-quaternary);
}

/* ⚠️ 这个类是给 <td> **里面**那层 div 用的，不是给 <td> 本身用的。
   2026-09-30 用户反馈「按钮下面的横线都上去了」，根因就是当初把它直接加在了
   <td> 上：按 CSS 规范，<td> 的 display 一旦从 table-cell 被改成 flex，
   浏览器会用一个匿名表格单元格把它包起来，这一格于是不再撑满行高，
   它自己的 border-bottom 相对同排其它格子就错位了 —— 表现就是分隔线"跑上去"。
   所以 JS 那边（assignments.js 的 renderRow）会给 td 里套一层 div 再用这个类。
   **改这里时别顺手把它挪回 td 上。** */
.ec-asg-ops { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

.ec-asg-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  height: 32px;
  padding: 0 var(--sp-3);
  border-radius: var(--r-sm);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: #fff;
  border: 1px solid transparent;
  background: linear-gradient(135deg, var(--ec-accent) 0%, var(--ec-accent-2) 100%);
}
.ec-asg-btn:hover { color: #fff; filter: brightness(1.1); }
.ec-asg-btn:disabled { opacity: 0.55; }

.ec-asg-badge {
  display: inline-block;
  padding: 2px var(--sp-2);
  border-radius: 999px;
  font-size: var(--fs-xs);
  font-weight: 500;
}
.ec-asg-badge.is-todo   { color: var(--fg-tertiary); background: var(--line-subtle); }
.ec-asg-badge.is-doing  { color: var(--warn); background: color-mix(in srgb, var(--warn) 16%, transparent); }
.ec-asg-badge.is-done   { color: var(--info); background: color-mix(in srgb, var(--info) 16%, transparent); }
.ec-asg-badge.is-graded { color: var(--ok);   background: color-mix(in srgb, var(--ok) 16%, transparent); }

/* ============================================================
   批改结果浮层（2026-09-30 用户要求「看到作业的反馈就直接展示」）
   ------------------------------------------------------------
   反馈是 generate_feedback 生成的**静态 HTML**（自带 Bootstrap 3 样式和
   <script>），所以用 iframe 载入 —— 样式与脚本在它自己的文档里跑，
   不会污染本页。遮罩层给出焦点隔离，Esc 或点空白处关闭。
   ============================================================ */
.ec-fb-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3vh 3vw;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.ec-fb-box {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 1020px;
  height: 100%;
  overflow: hidden;
  border-radius: var(--r-xl);
  border: 1px solid var(--line-default);
  background: var(--surface);
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.6);
}

.ec-fb-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--line-subtle);
  background: var(--surface-hover);
}
.ec-fb-head > strong {
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--fg-primary);
}

.ec-fb-close {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  height: 32px;
  padding: 0 var(--sp-4);
  border: 1px solid var(--line-default);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--fg-secondary);
  font-size: var(--fs-sm);
  cursor: pointer;
  transition: background 0.16s, color 0.16s;
}
.ec-fb-close:hover { background: var(--surface); color: var(--fg-primary); }

/* iframe 占满剩余空间。反馈 HTML 自带浅色 Bootstrap 样式，
   这里给它一个白底，避免暗色透上来影响可读性。 */
.ec-fb-frame {
  flex: 1 1 auto;
  width: 100%;
  border: 0;
  background: #fff;
}

/* ============================================================
   作业分数列（2026-09-30 用户要求：展示百分比、实际分数、等第 A+~E）
   ------------------------------------------------------------
   数据来自 ec_scores 扩展（服务器端 ec_scores.py），不来自 nbgrader 的
   /assignments —— 那个接口只回状态，不含分数。
   三块信息并排：实际分/满分 → 百分比 → 等第徽章。
   ============================================================ */
.ec-score {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  white-space: nowrap;
}
.ec-score.is-none { color: var(--fg-quaternary); }

/* 等第徽章单独占一格时给大一点，一列看下去整齐（用户要求只显示等第） */
.ec-score > .ec-score-letter { min-width: 40px; font-size: var(--fs-base); }

.ec-score-main {
  font-variant-numeric: tabular-nums;   /* 数字等宽，多行对齐好看 */
  font-weight: 600;
  color: var(--fg-primary);
}

.ec-score-pct {
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-sm);
  color: var(--fg-tertiary);
}

/* 等第徽章：颜色按档位分三组，扫一眼就能看出好坏 */
.ec-score-letter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  padding: 2px var(--sp-2);
  border-radius: 999px;
  font-size: var(--fs-sm);
  font-weight: 700;
  line-height: 1.5;
}
/* A 档 */
.grade-Ap, .grade-A, .grade-Am {
  color: var(--ok);
  background: color-mix(in srgb, var(--ok) 18%, transparent);
}
/* B 档 */
.grade-Bp, .grade-B, .grade-Bm {
  color: var(--info);
  background: color-mix(in srgb, var(--info) 18%, transparent);
}
/* C 档 */
.grade-Cp, .grade-C {
  color: var(--warn);
  background: color-mix(in srgb, var(--warn) 18%, transparent);
}
/* D / E */
.grade-D, .grade-E {
  color: var(--danger);
  background: color-mix(in srgb, var(--danger) 18%, transparent);
}

/* 「待复核」小标记（有题目等人工批改） */
.ec-score-flag {
  padding: 1px var(--sp-2);
  border-radius: 999px;
  font-size: var(--fs-xs);
  color: var(--warn);
  border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent);
}

/* 分数加载失败时的重试按钮（比一个死的「—」有用） */
.ec-score-retry {
  padding: 1px var(--sp-3);
  border-radius: 999px;
  border: 1px solid var(--line-default);
  background: transparent;
  color: var(--fg-tertiary);
  font-size: var(--fs-xs);
  cursor: pointer;
}
.ec-score-retry:hover { color: var(--fg-primary); border-color: var(--line-strong); }
.ec-score-retry:disabled { opacity: 0.6; cursor: default; }

/* 分数格可点击态（用户要求：点分数直接看批改明细，不再放"查看批改"按钮）
   ⚠️ 用 td.is-clickable 而不是给 td 加 flex —— 见上面 ec-asg-ops 那条注释，
   td 的 display 一旦离开 table-cell 会破坏整行布局。这里只加光标和悬停底色。 */
.ec-asg-score.is-clickable {
  cursor: pointer;
  transition: background 0.15s;
}
.ec-asg-score.is-clickable:hover { background: var(--surface-hover); }
.ec-asg-score.is-clickable:hover .ec-score-main { color: var(--nb-accent2); }

/* 正在取回反馈时的样子 */
.ec-asg-score.is-loading { opacity: 0.5; cursor: progress; }
