/* ============================================================
   科德大陆 · 符文试炼 —— 共用主题层（theme.css）

   三个页面（演示页 / 游戏页 / 开号页）共用的调色板、基础与通用组件。

   ⚠️ 依赖 Bootstrap 5.3+：
      按钮层落在 `.btn` / `--bs-btn-*` 上，主题层通过覆盖 `--bs-*` 变量
      实现多主题适配。加载顺序必须是（顺序错会被 Bootstrap 覆盖）：
          vendor/bootstrap.min.css  →  theme.css  →  页面样式

   ── 多主题机制 ──────────────────────────────────────────────
     <html data-theme="dark | light | eye | candy">
       · 调色板定义在 [data-theme] 上；**默认主题（现为 light）** 与 `:root` 写在一起
         ⚠️ 改默认主题要动**三处**：本文件的 `:root` + `theme.js` 的 `DEFAULT_ID`
            + 各 html 的 `data-bs-theme`（那是无 JS 时的兜底 ✓）
       · 派生层（--bs-*）写在 :root，通过 var() 引用调色板
         → 换主题只需替换调色板，Bootstrap 组件自动跟随
       · 切换由 theme.js 完成（写 localStorage + 同步 data-bs-theme）
       · 规则：**页面样式只允许引用变量，不得写死色值**
         （写死色值会导致该处在切换主题时"漏色"）
       · 不变量：**本文件里的每个变量都会随主题变化**。
         不随主题变化的量一律不放这里 —— 例如游戏世界的美术配色
         就放在 game/game.css 的「世界美术调色板」，那份是固定的。

   ── 与 Bootstrap 同名类的处理清单 ─────────────────────────────
     .btn         主动采用 Bootstrap 的（本文件只调参，不另建一套）
     .modal       主动采用 Bootstrap 的（连 JS 行为一起用）
     .placeholder ⚠️ Bootstrap 的同名类是「骨架屏」，语义完全不同，
                    会把占位文字渲染成灰色实心块（实测踩过）
                    → 已改名 .empty-hint 避让
     其余自有类（.panel / .stage / .chip / .phase / .verdict / .task /
     .output / .story / .tag / .layout / .toolbar …）经核对与
     Bootstrap 5.3 无同名冲突。新增类名前建议先对照 bootstrap.min.css。
   ============================================================ */

/* ============================================================
   一、调色板 · **默认主题（明亮 · 天蓝白昼）**

   ★**2026-09-21 修 bug：`:root` 兜底必须排在本文件所有 `[data-theme=...]` 之前** ✗
     被修的正是「**点「深色」毫无反应**」那个真 bug ✓：
       · `:root` 与 `[data-theme="dark"]` 的**特指度相同**（都是 0,1,0 ✓）⇒ **后写的赢** ✓
       · 2026-09-20 把默认主题由「深色」改成「明亮」时，`:root` 兜底被搬到了 dark 块**后面** ✓
         ⇒ **只有 `dark` 被压住** ✗（`eye` / `candy` / `slate` / `sunset` 都在它后面 ⇒ 侥幸没事 ✓）
         ⇒ 症状：属性挂上了、色值没换 ⇒ 看着像"按钮坏了" ✓
     ⇒ **规矩：`:root` 留在最前 ✓ 主题块一律排其后** ✗（新增主题也照此 ✓）
     ⚠️ 自检判据（本轮就是这么抓到的 ✓）：切主题后读
        `getComputedStyle(document.documentElement).getPropertyValue('--bg')` ✓
        —— 必须等于该主题块里写的值 ✓（当时 `dark` 读到的是**浅色**的值 ✗）

   ⚠️ `[data-theme="light"]` 这个**显式**选择器必须留着 ✗：
     主题面板里的「明亮」预览卡带 `data-theme` 属性 ✓，靠它拿**显式**色值 ✓
     （只写 `:root` ⇒ 预览卡会跟着 `<html>` 一起变 ✓）
   ⚠️ 改默认主题时**三处一起动** ✗：本块 ✓ + `theme.js` 的 `DEFAULT_ID` ✓
      + 用户 localStorage 里已存的那个 id ✓
   ============================================================ */
:root,
[data-theme="light"] {
  --bg: #eaf4ff;
  --bg-rgb: 234, 244, 255;
  --bg-glow: #ffffff;
  --bg-panel: #ffffff;
  --bg-panel-2: #f1f7ff;
  --border: #bfdcf5;

  --text: #16324f;
  --text-rgb: 22, 50, 79;
  --text-dim: #4f6d8c;

  --accent: #2f9bff;
  --accent-rgb: 47, 155, 255;
  --accent-2: #ff8a3d;
  --accent2-rgb: 255, 138, 61;

  --ok: #22c55e;
  --ok-rgb: 34, 197, 94;
  --warn: #f5a524;
  --danger: #ef4444;
  --danger-rgb: 239, 68, 68;

  --on-solid: #ffffff;

  --btn-from: #5eb3ff;
  --btn-to: #2f9bff;

  --code-bg: #f4f9ff;
  --code-text: #24405c;
  --compile-text: #c0392b;

  --stage-bg: #dceeff;
}

/* ============================================================
   二、其余主题（只需替换上面的调色板变量）

   ⚠️ 每个主题块都**必须排在 `:root` 之后** ✗（原因见「一、」✓）
   ⚠️ 本文件里的每个变量**都会随主题变化** ✓。
      不随主题变化的量（世界美术配色）一律放在 game/game.css，
      保持这个不变量，以后就不会有人误把美术色当主题色改 ✓
   ============================================================ */

/* ---- 深色 · 星空符文（**原默认主题**；2026-09-20 起是普通主题）---- */
[data-theme="dark"] {
  /* 底色 / 面板 */
  --bg: #0d1117;
  --bg-rgb: 13, 17, 23;
  --bg-glow: #16202f;
  --bg-panel: #161b26;
  --bg-panel-2: #1c2230;
  --border: #2a3242;

  /* 文字 */
  --text: #d7dee8;
  --text-rgb: 215, 222, 232;
  --text-dim: #8b98ab;

  /* 强调色 */
  --accent: #5eead4;
  --accent-rgb: 94, 234, 212;
  --accent-2: #a78bfa;
  --accent2-rgb: 167, 139, 250;

  /* 语义色 */
  --ok: #4ade80;
  --ok-rgb: 74, 222, 128;
  --warn: #fbbf24;
  --danger: #f87171;
  --danger-rgb: 248, 113, 113;

  /* 实色块上的前景色（按钮 / 状态徽标） */
  --on-solid: #06251f;

  /* 主按钮渐变 */
  --btn-from: #2dd4bf;
  --btn-to: #14b8a6;

  /* 代码 / 等宽面板 */
  --code-bg: #0a0e15;
  --code-text: #c9d7e8;
  --compile-text: #ffb4b4;

  /* 游戏舞台底衬（画框层：跟随主题）
     ⚠️ 世界内的美术配色**不在本文件**，见 game/game.css 的
        「世界美术调色板」——那份是固定的，不随主题切换。 */
  --stage-bg: #0b1014;
}

/* ---- 护眼 · 豆沙绿（低蓝光，长时间阅读友好）---- */
[data-theme="eye"] {
  --bg: #d6ecd2;
  --bg-rgb: 214, 236, 210;
  --bg-glow: #eaf8e6;
  --bg-panel: #f2faf0;
  --bg-panel-2: #e3f2e0;
  --border: #a8d3a2;

  --text: #26402b;
  --text-rgb: 38, 64, 43;
  --text-dim: #527056;

  --accent: #3f9142;
  --accent-rgb: 63, 145, 66;
  --accent-2: #b08b3e;
  --accent2-rgb: 176, 139, 62;

  --ok: #43a047;
  --ok-rgb: 67, 160, 71;
  --warn: #c9971b;
  --danger: #c65a5a;
  --danger-rgb: 198, 90, 90;

  --on-solid: #ffffff;

  --btn-from: #6dbf6f;
  --btn-to: #3f9142;

  --code-bg: #e8f3e5;
  --code-text: #2c4a30;
  --compile-text: #a94242;

  --stage-bg: #c9e4c4;
}

/* ---- 糖果 · 粉紫（明亮卡通风）---- */
[data-theme="candy"] {
  --bg: #fff0f7;
  --bg-rgb: 255, 240, 247;
  --bg-glow: #ffe3f1;
  --bg-panel: #ffffff;
  --bg-panel-2: #ffe8f4;
  --border: #ffc9e2;

  --text: #4a2340;
  --text-rgb: 74, 35, 64;
  --text-dim: #8c5b81;

  --accent: #ff5fa2;
  --accent-rgb: 255, 95, 162;
  --accent-2: #9b6bff;
  --accent2-rgb: 155, 107, 255;

  --ok: #2ecc71;
  --ok-rgb: 46, 204, 113;
  --warn: #ffb020;
  --danger: #ff4d4f;
  --danger-rgb: 255, 77, 79;

  --on-solid: #ffffff;

  --btn-from: #ff8ec0;
  --btn-to: #ff5fa2;

  --code-bg: #fff5fa;
  --code-text: #5b3050;
  --compile-text: #d6336c;

  --stage-bg: #ffe0f0;
}

/* ---- 石墨 · 中性灰（无色彩偏好，低调不抢眼，适合专注）---- */
[data-theme="slate"] {
  --bg: #eef1f4;
  --bg-rgb: 238, 241, 244;
  --bg-glow: #ffffff;
  --bg-panel: #ffffff;
  --bg-panel-2: #f5f7f9;
  --border: #d3d9e0;

  --text: #232a33;
  --text-rgb: 35, 42, 51;
  --text-dim: #636e7c;

  --accent: #5c6570;
  --accent-rgb: 92, 101, 112;
  --accent-2: #8c94a0;
  --accent2-rgb: 140, 148, 160;

  --ok: #3f9e5a;
  --ok-rgb: 63, 158, 90;
  --warn: #c98a1e;
  --danger: #c8544f;
  --danger-rgb: 200, 84, 79;

  --on-solid: #ffffff;

  --btn-from: #6b7480;
  --btn-to: #4a525c;

  --code-bg: #f4f6f8;
  --code-text: #2c3540;
  --compile-text: #b23b3b;

  --stage-bg: #dfe4ea;
}

/* ---- 暖阳 · 暖橙米色 ---- */
[data-theme="sunset"] {
  --bg: #fff6e9;
  --bg-rgb: 255, 246, 233;
  --bg-glow: #fffdf8;
  --bg-panel: #fffdf9;
  --bg-panel-2: #fdefdb;
  --border: #f2d9b0;

  --text: #4a3520;
  --text-rgb: 74, 53, 32;
  --text-dim: #7e6449;

  --accent: #e8722c;
  --accent-rgb: 232, 114, 44;
  --accent-2: #c9a227;
  --accent2-rgb: 201, 162, 39;

  --ok: #3f9e5a;
  --ok-rgb: 63, 158, 90;
  --warn: #d99b1f;
  --danger: #d1503f;
  --danger-rgb: 209, 80, 63;

  --on-solid: #ffffff;

  --btn-from: #f59a55;
  --btn-to: #e8722c;

  --code-bg: #fff8ee;
  --code-text: #5a4028;
  --compile-text: #c0392b;

  --stage-bg: #ffe9cf;
}

/* ============================================================
   二·附、判题阶段用色（四个阶段各一种色相）

   ── 为什么单独一组 ─────────────────────────────────────────
   这四个值**只被「判题阶段指示器」使用**（提交 → 编译 → 评测 → 结果）。
   集中放一处便于横向对照调色；若散进上面的主题块，
   为核一处颜色要在 6 个块之间来回翻。

   ── 为什么四色不同，而不是统一用主色 ───────────────────────
   原先的做法是「只按状态变色」（待机暗 / 进行中主色 / 完成绿 / 失败红），
   四个胶囊因此都落在同一色系里，只有亮暗差别 ——
   学生看不出「现在走到第几步」。

   四个阶段是**流程身份**，不是成败语义。按第十一节的配色分层原则，
   它属于「数据色随主题」那一类，所以每个主题各给一套。

   ⚠️ 成败仍由 --ok / --danger 表达（语义色固定、不随主题）：
      出错时 `.phase.is-error` 会用 --danger 覆盖下面的阶段色。

   ⚠️ 选择器必须同时写 `:root` 与 `[data-theme="..."]`，理由同前 ——
      主题面板的预览卡带 data-theme 属性，靠它拿显式色值。
   ★**2026-09-21 同「一、」那条：`:root` 兜底必须排在所有主题块之前** ✗ ——
      原先 `:root` 排在 `dark` / `slate` 之后 ⇒ 这两套阶段色也被压住 ✗
      （真机症状同前：切主题后阶段胶囊不变色 ✓ 本轮一并修掉 ✓）
   ============================================================ */
:root,
[data-theme="light"] {
  --ph-submit: #2f9bff;
  --ph-compile: #f5a524;
  --ph-judge: #8b5cf6;
  --ph-done: #22c55e;
}
[data-theme="dark"] {
  --ph-submit: #5eead4;    /* ① 提交 —— 主题主色：出发 */
  --ph-compile: #fbbf24;   /* ② 编译 —— 琥珀：处理中 */
  --ph-judge: #a78bfa;     /* ③ 评测 —— 紫：运行测试 */
  --ph-done: #4ade80;      /* ④ 结果 —— 绿：收束 */
}
[data-theme="slate"] {
  --ph-submit: #7c8798;
  --ph-compile: #c98a1e;
  --ph-judge: #6f8fd6;
  --ph-done: #3f9e5a;
}
[data-theme="sunset"] {
  --ph-submit: #e8722c;
  /* 比主题的 --warn 更深一档：橙(#e8722c)与金(#d99b1f)色距只有 69，
     在 12px 胶囊上偏难分辨，压深后拉开到 81 */
  --ph-compile: #c07f10;
  /* 暖色主题里唯一的冷色，让「评测」这一步最显眼 */
  --ph-judge: #3f7fd1;
  --ph-done: #3f9e5a;
}
[data-theme="eye"] {
  --ph-submit: #3f9142;
  --ph-compile: #c9971b;
  --ph-judge: #4a7fbf;
  /* 本主题主色与 --ok 都是纯绿，①④原本几乎同色；
     这里把"结果"偏向青绿拉开色距（74 → 86），仍属绿色系，
     不会破坏"绿=通过"的直觉。 */
  --ph-done: #25907d;
}
[data-theme="candy"] {
  --ph-submit: #ff5fa2;
  --ph-compile: #ffb020;
  --ph-judge: #9b6bff;
  --ph-done: #2ecc71;
}

/* ============================================================
   三、派生层（所有主题共用，只引用上面的调色板）
   ============================================================ */
:root {
  --mono: "Cascadia Code", "JetBrains Mono", Consolas, "Courier New", monospace;

  /* ---- Bootstrap 映射 ----
     覆盖这些变量后，Bootstrap 的 card / badge / form-control /
     modal / nav-tabs 等组件自动跟随主题，无需逐个组件重写。

     ⚠️ 顺序依赖：`:root` 与 Bootstrap 的 `[data-bs-theme=dark]` 同为
        (0,1,0) 特异性，靠"后加载者胜"生效 —— bootstrap.min.css 必须在前。 */
  --bs-body-bg: var(--bg);
  --bs-body-bg-rgb: var(--bg-rgb);
  --bs-body-color: var(--text);
  --bs-body-color-rgb: var(--text-rgb);
  --bs-secondary-color: var(--text-dim);
  --bs-secondary-bg: var(--bg-panel);
  --bs-tertiary-bg: var(--bg-panel-2);
  --bs-border-color: var(--border);
  --bs-border-radius: 8px;
  --bs-border-radius-lg: 10px;
  --bs-primary: var(--accent);
  --bs-primary-rgb: var(--accent-rgb);
  --bs-success: var(--ok);
  --bs-danger: var(--danger);
  --bs-warning: var(--warn);
  --bs-link-color: var(--accent);
  --bs-link-hover-color: var(--accent);
  --bs-font-monospace: var(--mono);
  --bs-focus-ring-color: rgba(var(--accent-rgb), .35);
  /* Reboot 默认把 <code> 渲成粉色，统一改为强调色 */
  --bs-code-color: var(--accent);
}

/* 表单控件原生外观（滚动条 / 输入框）跟随主题明暗
   ⚠️ 新增主题时务必在此分组，否则滚动条 / 输入框会停留在上一主题的明暗 */
[data-theme="dark"] { color-scheme: dark; }
[data-theme="light"],
[data-theme="slate"],
[data-theme="sunset"],
[data-theme="eye"],
[data-theme="candy"] { color-scheme: light; }

/* ============================================================
   四、基础
   （`* { box-sizing }` 与 `body { margin }` 由 Bootstrap Reboot 提供）
   ============================================================ */
html, body {
  margin: 0;
  height: 100%;
  background: radial-gradient(circle at 20% 0%, var(--bg-glow) 0%, var(--bg) 55%);
  color: var(--text);
  font-family: system-ui, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
  font-size: 14px;
}

/* ============================================================
   五、按钮
   基础样式与尺寸体系来自 Bootstrap，这里只调参 + 定主色，
   不再自建一套 .btn（避免与 Bootstrap 的 .btn 互相覆盖）。
   ============================================================ */
.btn {
  --bs-btn-padding-y: 8px;
  --bs-btn-padding-x: 16px;
  --bs-btn-font-size: 13px;
  --bs-btn-font-family: inherit;
  --bs-btn-disabled-opacity: .45;
}

.btn-primary {
  --bs-btn-color: var(--on-solid);
  --bs-btn-bg: var(--btn-to);
  --bs-btn-border-color: transparent;
  --bs-btn-hover-color: var(--on-solid);
  --bs-btn-hover-bg: var(--btn-from);
  --bs-btn-hover-border-color: transparent;
  --bs-btn-active-color: var(--on-solid);
  --bs-btn-active-bg: var(--btn-to);
  --bs-btn-active-border-color: transparent;
  --bs-btn-disabled-color: var(--on-solid);
  --bs-btn-disabled-bg: var(--btn-to);
  --bs-btn-disabled-border-color: transparent;
  --bs-btn-font-weight: 700;
  --bs-btn-focus-shadow-rgb: var(--accent-rgb);
  /* 保留原设计的渐变质感（背景图盖在背景色之上） */
  background-image: linear-gradient(135deg, var(--btn-from), var(--btn-to));
}
.btn-primary:hover { filter: brightness(1.1); }

/* ============================================================
   六、状态胶囊
   ============================================================ */
.chip {
  padding: 4px 10px;
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 12px;
  color: var(--text-dim);
}
.chip b { color: var(--text); }

/* ============================================================
   七、判题阶段指示器（提交 → 编译 → 评测 → 结果）
   ============================================================ */
.phases { display: flex; gap: 8px; flex-wrap: wrap; }

/* 每个阶段各挂一种**身份色**，下面的状态规则统一取 --ph。
   四色的取值在每个主题里定义，见「二·附、判题阶段用色」。 */
.phase[data-phase="SUBMITTING"] { --ph: var(--ph-submit); }
.phase[data-phase="COMPILING"]  { --ph: var(--ph-compile); }
.phase[data-phase="JUDGING"]    { --ph: var(--ph-judge); }
.phase[data-phase="DONE"]       { --ph: var(--ph-done); }

.phase {
  /* 半透明版本：50% 的描边 + 呼吸光晕都用它。
     ⚠️ 这里用 color-mix 而非项目常规的 rgba(var(--x-rgb), α)：
        阶段色是 4×6 = 24 个值，再配一套 -rgb 变量会直接翻倍；
        而 color-mix 能直接从 --ph 派生，故只此一处偏离约定。
        （不支持 color-mix 的浏览器会丢掉这两条声明 ——
          表现为没有淡描边与光晕，颜色本身照常生效。） */
  --ph-mix: color-mix(in srgb, var(--ph) 50%, transparent);

  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 12px;
  color: var(--text-dim);
  border: 1px solid var(--border);
  transition: all .2s;
}

/* 编号圆点：**未开始时也带上阶段色** ——
   这样四个胶囊在任何时刻都能分辨"哪一步是哪个"，
   而不是提交前四个长得一模一样、只有亮暗差别。 */
.phase i {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--bg-panel-2);
  color: var(--ph);
  border: 1px solid var(--ph-mix);
  font-style: normal;
  font-size: 10px;
}

/* 已完成：整颗胶囊亮起该阶段的身份色 */
.phase.is-done { color: var(--ph); border-color: var(--ph-mix); }
.phase.is-done i { background: var(--ph); color: var(--on-solid); border-color: transparent; }

/* 进行中（呼吸动画）：同色描边 + 同色光晕 */
.phase.is-active {
  color: var(--ph);
  border-color: var(--ph);
  /* 动画起点值，避免首帧跳动 */
  box-shadow: 0 0 0 0 var(--ph-mix);
  animation: pulse 1.2s infinite;
}
.phase.is-active i { background: var(--ph); color: var(--on-solid); border-color: transparent; }

/* 失败：**语义色固定**，覆盖阶段身份色 ——
   "红=出错"要跨主题一致，否则这条教学约定会在换主题时失效。 */
.phase.is-error { color: var(--danger); border-color: rgba(var(--danger-rgb), .5); }
.phase.is-error i { background: var(--danger); color: var(--on-solid); border-color: transparent; }

@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 var(--ph-mix); }
  70%  { box-shadow: 0 0 0 8px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* ============================================================
   八、代码 / 等宽内容面板
   编辑器、编译输出、名单预览共用同一套外观。
   用法：元素同时挂 .code-surface（外观）+ 各自的尺寸类。

   ⚠️ 页面样式在 theme.css 之后加载，因此 .compile 等
      单类选择器可直接覆盖本文件的 font-size / color / padding。
   ============================================================ */
.code-surface {
  padding: 12px;
  background: var(--code-bg);
  color: var(--code-text);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.7;
}

/* 编辑器：占满剩余高度 + 自身滚动
   `min-width: 0` / `min-height: 0` 是必需的：
   textarea 有固有宽度，不归零会撑破 Grid / Flex 轨道。 */
#codeInput {
  flex: 1;
  min-width: 0;
  min-height: 0;
  line-height: 1.65;
  resize: none;
  outline: none;
  tab-size: 4;
}
#codeInput:focus { border-color: var(--accent); }

/* ============================================================
   九、Bootstrap 组件覆盖（只调参，不重写结构）
   ============================================================ */

/* ---- 结果弹层 ---- */
.modal {
  --bs-modal-width: 620px;
  --bs-modal-bg: var(--bg-panel);
  --bs-modal-color: var(--text);
  --bs-modal-border-color: var(--border);
  --bs-modal-border-radius: 14px;
}

.modal-backdrop {
  --bs-backdrop-opacity: .78;
  backdrop-filter: blur(3px);
}

/* 原设计是「缩放弹出」，Bootstrap 默认是「下滑进入」，这里改回缩放 */
.modal.fade .modal-dialog {
  transform: scale(.94);
  transition: transform .22s ease-out;
}
.modal.show .modal-dialog { transform: scale(1); }

.modal-body {
  padding: 26px;
  max-height: 86vh;
  overflow-y: auto;
  text-align: center;
}

/* ---- 表单控件 ----
   Bootstrap 的焦点态是蓝色（#86b7fe 描边 + 蓝色光晕），与主题不符。
   这里统一改成强调色，之后任何 .form-control / .form-select 都自动生效。 */
.form-control:focus,
.form-select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 .2rem rgba(var(--accent-rgb), .25);
}

/* ---- 标签页（nav-tabs）----
   Bootstrap 默认让所有页签继承 --bs-link-color（= 强调色），
   会把**未选中**页签也染成强调色；默认还是「卡片式」上边框。
   这里改成与游戏页 .tab 一致的规则：
     未选中 = 次要文字色，选中 = 强调色 + 2px 底部描边，其余边框一律透明。
   容器底边单独收细到 1px —— 该变量同时管页签与容器，不单独覆盖会一起变粗。 */
.nav-tabs {
  --bs-nav-link-color: var(--text-dim);
  --bs-nav-link-hover-color: var(--text);
  --bs-nav-link-padding-y: 8px;
  --bs-nav-link-padding-x: 16px;
  --bs-nav-tabs-border-width: 2px;
  --bs-nav-tabs-border-color: var(--border);
  --bs-nav-tabs-link-hover-border-color: transparent;
  --bs-nav-tabs-link-active-color: var(--accent);
  --bs-nav-tabs-link-active-bg: transparent;
  --bs-nav-tabs-link-active-border-color: transparent transparent var(--accent);
  border-bottom-width: 1px;
}

/* ============================================================
   十、主题选择器
   HTML 由 theme.js 生成；工具栏只放一个 .theme-anchor 容器。
   ============================================================ */
.theme-anchor {
  position: relative;
  display: inline-block;
}

.theme-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-panel-2);
  color: var(--text);
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
  transition: all .15s;
}
.theme-trigger:hover { border-color: var(--accent); color: var(--accent); }

.theme-trigger__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 2px rgba(var(--accent-rgb), .3);
}

.theme-picker {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 60;
  width: 360px;
  max-height: 78vh;
  overflow-y: auto;
  padding: 14px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 14px 36px rgba(0, 0, 0, .30);
}
.theme-picker[hidden] { display: none; }

.theme-picker__title {
  margin: 0 0 10px;
  font-size: 12px;
  letter-spacing: 1px;
  color: var(--text-dim);
}

/* 3 列 × 2 行：新增主题时网格自动换行，无需改这里 */
.theme-picker__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.theme-card {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 8px;
  border: 2px solid var(--border);
  border-radius: 11px;
  background: var(--bg-panel-2);
  color: var(--text);
  font-family: inherit;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
  transition: transform .15s, border-color .15s, box-shadow .15s;
}
.theme-card:hover { transform: translateY(-2px); border-color: var(--accent); }
.theme-card.is-active {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .22);
}

/* 迷你预览：元素自带 data-theme，因此直接复用该主题的调色板，
   无需在 JS 里重复维护一份色值 */
.theme-card__preview {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px;
  height: 42px;
  padding: 5px;
  border-radius: 7px;
  background: var(--bg);
  border: 1px solid var(--border);
}
.theme-card__preview i { border-radius: 3px; }
.theme-card__preview i:nth-child(1) { grid-column: span 2; background: var(--bg-panel); }
.theme-card__preview i:nth-child(2) { background: var(--accent); }
.theme-card__preview i:nth-child(3) { background: var(--accent-2); }

.theme-card__name { font-weight: 700; }
.theme-card__desc { font-size: 11px; color: var(--text-dim); }

/* ============================================================
   十一、结果展示（判定卡 / 指标卡 / 编译输出 / 奖励）
   演示页的结果弹层与游戏页的「运行结果」标签**共用这一套**，
   避免两处各写一份、日久走形。

   ── 配色分层原则（可复用于其他"展示型"组件）────────────
     · 语义色固定：成败用 --ok / --danger，跨主题保持一致 ——
       否则"绿=通过"这类教学约定会在换主题时失效
     · 数据色随主题：得分用 --accent、耗时用 --accent-2 ——
       让结果区也跟着主题变化，而不是清一色
   ============================================================ */

/* 纵向节奏：子块统一间距。
   ⚠️ 刻意用 gap 而不是给每块写 margin ——
      后者极易漏写某一侧（实测踩过：.verdict 只有下边距，与上方 .phases 紧贴）。 */
.result-stack {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* ---------------- 判定卡 ---------------- */
.verdict {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  border: 1px solid var(--border);
  border-left-width: 4px;      /* 左侧色条：一眼看出成败 */
  border-radius: 10px;
  background: var(--bg-panel-2);
}
.verdict.is-ok {
  border-left-color: var(--ok);
  background: linear-gradient(90deg, rgba(var(--ok-rgb), .16), transparent 70%);
}
.verdict.is-fail {
  border-left-color: var(--danger);
  background: linear-gradient(90deg, rgba(var(--danger-rgb), .16), transparent 70%);
}
/* 中性提示（★2026-09-24 加 ✓）：既不是通过、也不是出错 ——
   如"还不能提交：请先选择至少一个选项"、"没有可跳的环节了" ✓
   ⚠️ 用 `--accent`（**主题数据色**）而不是 ok / danger 那两个**语义色** ✗ ——
      它要说的是"这是在跟你说话"，**不是**一种成败判定 ✓ */
.verdict.is-info {
  border-left-color: var(--accent);
}

.verdict__icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  font-size: 16px;
  font-weight: 700;
}
.verdict.is-ok .verdict__icon { background: var(--ok); color: var(--on-solid); }
.verdict.is-fail .verdict__icon { background: var(--danger); color: var(--on-solid); }
.verdict.is-info .verdict__icon { background: var(--accent); color: var(--on-solid); }

.verdict__body {
  flex: 1;
  min-width: 0;
  /* 弹层父级是 text-align: center，这里显式左对齐，保证两页观感一致 */
  text-align: left;
}

.verdict__title {
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 1px;
  line-height: 1.3;
}
.verdict.is-ok .verdict__title { color: var(--ok); }
.verdict.is-fail .verdict__title { color: var(--danger); }
.verdict.is-info .verdict__title { color: var(--accent); }

/* 面向学生的中文说明：初学者最需要的是"错在哪、去看什么" */
.verdict__desc {
  margin-top: 2px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--text-dim);
}

.verdict__score {
  flex-shrink: 0;
  text-align: right;
  white-space: nowrap;
}
.verdict__score-value {
  font-family: var(--mono);
  font-size: 24px;
  font-weight: 800;
  line-height: 1;
  color: var(--accent);   /* ⭐ 主题主色：换主题时这块会明显变化 */
}
.verdict__score-label {
  margin-left: 2px;
  font-size: 11px;
  color: var(--text-dim);
}

/* ---------------- 指标卡（耗时 / 内存）---------------- */
.stats {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.stat {
  flex: 1;
  min-width: 88px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-panel-2);
}

.stat__label {
  display: block;
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--text-dim);
}

.stat__value {
  display: block;
  margin-top: 1px;
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--text);
}
.stat__value i {
  margin-left: 2px;
  font-style: normal;
  font-size: 10px;
  font-weight: 400;
  color: var(--text-dim);
}

.stat--time .stat__value { color: var(--accent-2); }
.stat--mem .stat__value { color: var(--text); }

/* ---------------- 编译错误输出 ----------------
   外观（底色 / 边框 / 圆角 / 等宽字体）来自本文件第八节的 .code-surface，
   这里只写结果场景下的差异项 */
.compile {
  margin: 0;              /* 间距交给 .result-stack 的 gap */
  padding: 10px;
  text-align: left;
  color: var(--compile-text);
  font-size: 12px;
  line-height: 1.6;
  white-space: pre-wrap;
  max-height: 180px;
  overflow-y: auto;
}

/* ---------------- 奖励提示 ---------------- */
.reward {
  padding: 11px 14px;
  border: 1px dashed var(--accent);
  border-radius: 8px;
  background: rgba(var(--accent-rgb), .07);
  color: var(--accent);
  font-size: 12px;
  line-height: 1.8;
}

/* ============================================================
   十二、题面正文（Markdown 渲染结果）
   OJ 题面是 Markdown，由 marked 渲染成 HTML（vendor/marked.min.js）。
   演示页与游戏页共用，故放主题层。

   ⚠️ 安全前提：题面由**教师**在 OJ 侧撰写，信任级别等同 OJ 自身
      （Hydro 自己的界面也是直接渲染题面 HTML）。
      若将来题面开放给学生编辑，必须在此前引入 HTML 白名单净化。
   ============================================================ */
.problem-body {
  font-size: 13px;
  line-height: 1.85;
  color: var(--text);
  overflow-wrap: break-word;
}
/* 首尾元素不撑出多余留白 */
.problem-body > :first-child { margin-top: 0; }
.problem-body > :last-child { margin-bottom: 0; }

/* 分节标题：左侧小色条，让"输入格式 / 输出格式 / 样例"一眼可辨 */
.problem-body h1,
.problem-body h2,
.problem-body h3,
.problem-body h4 {
  margin: 16px 0 8px;
  padding-left: 8px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .5px;
  color: var(--accent);
  border-left: 3px solid var(--accent);
}

/* 段间距：8px → 4px（★2026-09-25 ✓ 老值注释保留 ✓ 方便回滚）
   —— 题面限高 46%（见 `game/game.css` 的 `.task` ✓）⇒ 段间留白是全页最"贵"的
      空间：`8px` 上下相加 = 16px ≈ 段落自身行高（13px × 1.85 ≈ 24px）的 2/3 ✓
   ⚠️ 本条只动**段间**：标题 / 列表 / 表格的 margin 一律不动 ✗ ——
      它们自带边框或色条，是"结构"而非"换气"，压缩会糊成一片 ✓
      （代码块的 margin 后来单独收过了 ✓ 见下面 `.problem-body pre` ✓）
   ⚠️ 首尾段不受影响 ✓：`.problem-body > :first-child / :last-child` 已把外边距归零 ✓ */
.problem-body p { margin: 4px 0; }

.problem-body ul,
.problem-body ol { margin: 8px 0; padding-left: 20px; }
.problem-body li { margin: 3px 0; }

/* 行内代码 */
.problem-body code {
  padding: 1px 5px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--code-bg);
  font-family: var(--mono);
  font-size: 12px;
  color: var(--accent);
}

/* 代码块（覆盖上面的行内代码样式） */
.problem-body pre {
  /* ★2026-09-25：上下外边距 10px → 4px、上下内边距 10px → 4px
     （✓ 老值注释保留 ✓ 回滚只需把两个 4px 改回 10px）
     —— 两道留白本该"同一件事"，此前外 10 + 内 10 = 20px，比段间距（`p` 现为 4px）
        宽出五倍 ⇒ 代码块像"悬"在半空、和上下段落脱节 ✓
        块内还有 `line-height: 1.65`（见下面 `pre code` ✓）自带行距，
        内外都收到 4px 后：代码块与段落同属"一段"，靠边框和底色划线即可 ✓
     ⚠️ 左右**一律不动** ✗：外边距由父面板的 padding 决定，内边距 12px 是给
        `overflow-x: auto`（横向滚动）留的呼吸位 —— 滚到最右时末字符不贴边框 ✓ */
  margin: 4px 0;
  padding: 4px 12px;
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--code-bg);
}
.problem-body pre code {
  padding: 0;
  border: none;
  background: none;
  color: var(--code-text);
  font-size: 12px;
  line-height: 1.65;
}

.problem-body table {
  width: 100%;
  margin: 10px 0;
  border-collapse: collapse;
  font-size: 12px;
}
.problem-body th,
.problem-body td {
  padding: 5px 10px;
  border: 1px solid var(--border);
  text-align: left;
}
.problem-body th {
  background: var(--bg-panel-2);
  color: var(--text-dim);
  font-weight: 600;
}

.problem-body blockquote {
  margin: 10px 0;
  padding: 4px 12px;
  border-left: 3px solid var(--border);
  color: var(--text-dim);
}

.problem-body hr {
  margin: 14px 0;
  border: none;
  border-top: 1px dashed var(--border);
}

.problem-body a { color: var(--accent); }

/* 题面区的占位 / 加载中 / 失败提示 */
.problem-note {
  margin: 0;
  font-size: 12px;
  line-height: 1.8;
  color: var(--text-dim);
  white-space: pre-wrap;
}

/* 题面顶部限制条（时间 / 内存 / 测试点数；数据全部来自 OJ 的 config，不在 Node 侧另存一份） */
.problem-limits {
  margin: 0 0 10px;
  padding: 4px 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-panel-2);
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-dim);
}

/* ============================================================
   十三、胶囊导航链接
   顶栏 / 工具栏里的小圆角描边链接：游戏页「代码版演示」、
   演示页「← 返回游戏」共用，保证两页导航观感一致。

   颜色规范：默认 --text-dim，hover 转 --accent。

   ⚠️ 页面若要改成强调色，请用**两条类选择器**覆盖，
      例如 game.css 的 `.toolbar__nav .link--demo`；
      不要写 `.topbar .navlink` 这类「父级 + 单类」规则 ——
      它与 `.navlink:hover` 恰好同为 (0,2,0)，
      会因页面样式后加载而被反压，表现为「鼠标悬停没反应」。
   ============================================================ */
.navlink {
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 12px;
  color: var(--text-dim);
  text-decoration: none;
  white-space: nowrap;
  transition: color .15s, border-color .15s;
}
.navlink:hover {
  color: var(--accent);
  border-color: var(--accent);
}
