/* 知政星 · Web 控制台
 * 「雾蓝·档案纸」主题（M3 blue 派生）：雾白纸面 #E9EEF4（冷调，去黄）+ 实心主蓝 #2E5FAF
 * （实心填充配白字；暗主题填充提亮为 #3F6FD0）；浅长春花蓝仅作暗主题链接/描边。
 * 语义色 已验证=翠绿 / 待核实=琥珀 / 偏离·错误=红。
 * 令牌取自 dataviz 参考 palette：surface / ink / border / status，
 * 明暗两套（prefers-color-scheme + data-theme 双作用域）。 */

:root {
  --bg: #E9EEF4;   /* 锚A·雾白纸面（冷调） */
  --card: #ffffff;
  --card-2: #EEF2F8;
  /* 章节卡片浅色低饱和底色（与页面/详情白底区分） */
  --sec-tint: #E4ECF8;
  --sec-tint-2: #D5E1F4;
  --ink: #1E2B44;
  --ink-2: #44536E;
  --muted: #5A6A83;
  --grid: #D8DEE8;
  --baseline: #B2BDCF;
  --border: rgba(30, 43, 68, 0.13);
  --good: #059669;
  --warning: #c97f00;
  --serious: #e0642f;
  --critical: #c62744;
  --accent: #2E5FAF;       /* 交互长春花蓝：文字/链接/描边/焦点环 */
  --accent-fill: #2E5FAF;  /* 锚B·实心主蓝：主按钮/激活态（配 --on-accent 白字） */
  --on-accent: #FFFFFF;
  --accent-soft: #D5E1F4;  /* 选中/悬浮淡底 */
  --ph-bg: #fffbeb;
  --ph-ink: #b45309;
  /* 溯源高亮（申论炼题专用）：**非语义色**，不参与 good/warning/serious/critical 语义。
     刻意不复用 --warning——那是「待核实」色，用来标「已验证的出处」正好把语义反过来。 */
  --hl-q: #2E5FAF;  /* 题目出处（沿 accent 家族） */
  --hl-a: #0E7C6B;  /* 答案要点出处（青绿，与四个语义色都拉开距离） */
  --shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  /* 关系槽（dataviz 固定顺序，不循环；仅作为图例/单关系聚焦着色用） */
  --rel-1: #2a78d6; /* 上位 blue */
  --rel-2: #eb6834; /* 推动 orange */
  --rel-3: #1baf7a; /* 体现 aqua */
  --rel-4: #eda100; /* 支撑 yellow */
  --rel-5: #e87ba4; /* 联动 magenta */
  --rel-6: #008300; /* 并列 green（预留） */
  --rel-7: #7b5ea7; /* 包含 purple */
  /* 圆角层级（设计：6/8/12/16） */
  --r-xs: 6px;
  --r: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --mono: ui-monospace, "Cascadia Code", Consolas, "Courier New", monospace;
  --sans: system-ui, -apple-system, "Segoe UI", "Microsoft YaHei", sans-serif;
}

[data-theme="dark"] {
  --bg: #141A26;
  --card: #1E2533;
  --card-2: #262E3E;
  --sec-tint: #222B3B;
  --sec-tint-2: #2C3649;
  --ink: #E9EEF7;
  --ink-2: #B4C0D4;
  --muted: #8B96AB;
  --grid: #222B3B;
  --baseline: #2F3A4F;
  --border: rgba(255, 255, 255, 0.10);
  --good: #34d399;
  --warning: #f0b429;
  --serious: #ff9a6b;
  --critical: #ff7a8e;
  --accent: #A4C2F0;       /* 交互长春花蓝（暗） */
  --accent-fill: #3F6FD0;  /* 锚B·实心主蓝（暗，提亮一档，配白字） */
  --on-accent: #FFFFFF;
  --accent-soft: #2A3550;
  --ph-bg: #3a2f10;
  --ph-ink: #ffd76a;
  --hl-q: #A4C2F0;  /* 溯源高亮·题目出处（暗） */
  --hl-a: #4FD1B0;  /* 溯源高亮·答案出处（暗） */
  --shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  --rel-1: #5a9be6;
  --rel-2: #e0764a;
  --rel-3: #2bb489;
  --rel-4: #d9a020;
  --rel-5: #e876a8;
  --rel-6: #3ba55d;
  --rel-7: #9a7cc4;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #141A26;
    --card: #1E2533;
    --card-2: #262E3E;
    --sec-tint: #222B3B;
    --sec-tint-2: #2C3649;
    --ink: #E9EEF7;
    --ink-2: #B4C0D4;
    --muted: #8B96AB;
    --grid: #222B3B;
    --baseline: #2F3A4F;
    --border: rgba(255, 255, 255, 0.10);
    --good: #34d399;
    --warning: #f0b429;
    --serious: #ff9a6b;
    --critical: #ff7a8e;
    --accent: #A4C2F0;       /* 交互长春花蓝（暗） */
    --accent-fill: #3F6FD0;  /* 锚B·实心主蓝（暗，提亮一档，配白字） */
    --on-accent: #FFFFFF;
    --accent-soft: #2A3550;
    --ph-bg: #3a2f10;
    --ph-ink: #ffd76a;
    --hl-q: #A4C2F0;  /* 溯源高亮·题目出处（暗，跟随系统深色） */
    --hl-a: #4FD1B0;  /* 溯源高亮·答案出处（暗，跟随系统深色） */
    --rel-1: #5a9be6;
    --rel-2: #e0764a;
    --rel-3: #2bb489;
    --rel-4: #d9a020;
    --rel-5: #e876a8;
    --rel-6: #3ba55d;
    --rel-7: #9a7cc4;
  }
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 500; /* 全局字重整体上调一档：正文基底 400→500 */
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
}

/* ── 布局 ─────────────────────────────────────────────── */
#app { display: flex; flex-direction: column; height: 100vh; }

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  height: 52px; padding: 0 16px;
  border-bottom: 1px solid var(--border);
  background: var(--card);
  flex: none;
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand-mark {
  display: block;
  width: 28px; height: 28px; border-radius: 6px;
  object-fit: cover;
}
.brand-name { font-weight: 800; font-size: 15px; }
.brand-art { display: block; height: 24px; width: auto; }
.topbar-right { display: flex; gap: 8px; }

.shell { flex: 1; display: flex; min-height: 0; position: relative; }

.sidebar {
  width: 168px; flex: none;
  padding: 12px 8px; display: flex; flex-direction: column; gap: 4px;
  border-right: 1px solid var(--border);
  background: var(--card);
}
.nav-item {
  text-align: left; font: inherit; color: var(--ink-2);
  padding: 8px 12px; border-radius: 6px; border: none; cursor: pointer;
  background: transparent;
}
.nav-item[href] { display: block; text-decoration: none; }
.nav-item:hover { background: var(--card-2); color: var(--ink); }
.nav-item.active { background: var(--card-2); color: var(--ink); font-weight: 700; }

.content { flex: 1; overflow: auto; padding: 20px 24px; min-width: 0; }

.panel { display: none; }
.panel.active { display: block; animation: fadein .15s ease; }
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }

/* 推演画布：面板占满内容区，iframe 撑满余下高度（自带滚动）。
   注意 base 不设 display，否则 ID 特异性会盖过 .panel 的 display:none 导致面板常显 */
#panel-canvas { height: 100%; min-height: 0; }
#panel-canvas.active { display: flex; flex-direction: column; }
.canvas-frame {
  flex: 1; min-height: 0; width: 100%;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--bg); display: block;
}

.panel-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.panel-head h2 { margin: 0; font-size: 18px; }
.graph-sub { width: 100%; margin-top: 2px; font-size: 12px; color: var(--muted); }
.panel-tools { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: wrap; }
.muted { color: var(--muted); font-size: 12px; }

/* ── 控件 ─────────────────────────────────────────────── */
.btn {
  font: inherit; font-weight: 600; cursor: pointer;
  padding: 6px 14px; border-radius: 6px;
  border: 1px solid var(--baseline); background: var(--card);
  color: var(--ink);
}
.btn:hover { border-color: var(--muted); }
.btn.primary {
  background-color: var(--accent-fill);
  background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0) 45%);
  border-color: var(--accent-fill);
  color: var(--on-accent);
}
.btn.ghost { background: transparent; }
.btn.small { padding: 3px 9px; font-size: 12px; }
.btn.icon { padding: 4px 9px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.input, .textarea, select.input {
  font: inherit; color: var(--ink);
  background: var(--card); border: 1px solid var(--baseline); border-radius: 6px;
  padding: 6px 10px;
}
.input { min-width: 0; }
.input.num { width: 74px; }
.textarea { width: 100%; resize: vertical; }
.input:focus, .textarea:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: transparent; }
.input::placeholder, .textarea::placeholder { color: var(--muted); }

.inline-label { display: inline-flex; align-items: center; gap: 6px; color: var(--ink-2); font-size: 13px; }
.field-label { display: flex; flex-direction: column; gap: 4px; color: var(--ink-2); font-size: 13px; }
.field-label select.input, .field-label input.input { color: var(--ink); }

.check { display: inline-flex; align-items: center; gap: 6px; color: var(--ink-2); font-size: 13px; cursor: pointer; }
.check input { accent-color: var(--accent); }

.row { display: flex; align-items: center; gap: 10px; }
.tmpl-row { display: flex; align-items: center; gap: 8px; margin: 6px 0; }

.result { font-size: 13px; }
.result.ok { color: var(--good); }
.result.err { color: var(--critical); }

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 10px; border-radius: 999px; font-size: 12px;
  border: 1px solid var(--baseline); color: var(--ink-2);
}
.badge.ok { color: var(--good); border-color: var(--good); }
.badge.err { color: var(--critical); border-color: var(--critical); }
.badge.warn { color: var(--serious); border-color: var(--serious); }
.badge.neutral { color: var(--muted); }

/* ── 图谱 ─────────────────────────────────────────────── */
.graph-wrap { display: flex; gap: 16px; height: 700px; margin-bottom: 14px; }
.graph-canvas {
  flex: 1; min-width: 0; position: relative;
  border: 1px solid var(--border); border-radius: 8px; overflow: hidden;
  background: var(--card);
}
.graph-canvas svg { width: 100%; height: 100%; display: block; }
.graph-canvas .hint {
  position: absolute; left: 10px; bottom: 8px; margin: 0;
  color: var(--muted); font-size: 12px; pointer-events: none;
}

.graph-side { width: 290px; flex: none; display: flex; flex-direction: column; gap: 12px; overflow: auto; }
.side-block {
  border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; background: var(--card);
}
.side-block h4 { margin: 0 0 8px; font-size: 13px; }
.legend-note { margin: 0 0 8px; color: var(--muted); font-size: 12px; }

.legend { display: flex; flex-direction: column; gap: 6px; }
.legend-chip {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 8px; border-radius: 6px; cursor: pointer;
  border: 1px solid transparent; font-size: 13px; color: var(--ink-2);
}
.legend-chip:hover { background: var(--card-2); }
.legend-chip.active { border-color: var(--baseline); color: var(--ink); font-weight: 700; }
.legend-chip.reserved { opacity: .5; cursor: default; }
.legend-chip.reserved:hover { background: transparent; }
.legend-swatch {
  width: 12px; height: 12px; border-radius: 3px; flex: none;
  border: 1px solid var(--border);
}

/* 图谱 SVG 元素 */
.g-node { cursor: grab; }
.g-node.dragging { cursor: grabbing; }
.g-node circle { fill: var(--card); stroke: var(--ink-2); stroke-width: 1.5; cursor: grab; }
.g-node.dragging circle { cursor: grabbing; }
.g-node.dim circle { opacity: .3; }
/* 焦点用「实心环 + 虚线外环」编码，不靠与 rel-1 同色的实心填充——聚焦节点与
   着色边同时出现时靠形状（环 + 虚线 + 加粗文字）区分，颜色不单独承担身份 */
.g-node.focus circle:not(.hit) { fill: var(--card); stroke: var(--accent); stroke-width: 3; }
.g-node.focus circle.hit { fill: transparent; stroke: var(--accent); stroke-width: 1.5; stroke-dasharray: 4 3; }
.g-node.near circle { stroke-width: 2.5; stroke: var(--accent); }
.g-node text {
  fill: var(--ink); font-size: 12px; text-anchor: middle;
  paint-order: stroke; stroke: var(--bg); stroke-width: 3px; stroke-linejoin: round;
  pointer-events: none;
}
.g-node.dim text { opacity: .35; }
.g-node.focus text, .g-node.near text { font-weight: 700; }
.g-node:focus-visible circle { outline: 2px solid var(--accent); outline-offset: 3px; }
.legend-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.g-edge line, .g-edge path {
  stroke: var(--ink-2); stroke-width: 1.6; opacity: .75;
}
.g-edge.dim line, .g-edge.dim path, .g-edge.dim .edge-label { opacity: .12; }
.g-edge.facet line, .g-edge.facet path { opacity: .95; stroke-width: 2.4; }
.g-edge.facet .edge-label { opacity: 1; font-weight: 700; }
.g-edge:hover line, .g-edge:hover path { stroke-width: 2.6; }
.edge-label {
  fill: var(--ink-2); font-size: 10px; text-anchor: middle;
  paint-order: stroke; stroke: var(--bg); stroke-width: 3px; stroke-linejoin: round;
  pointer-events: none;
}
.edge-label.facet { fill: var(--ink); }
.g-edge.dim .edge-label { stroke: transparent; }

/* 图谱探索（概念模式；关系分析低置信度边虚线） */
.g-edge.low line { stroke-dasharray: 5 3; opacity: .6; }
.tool-status { font-size: 12px; color: var(--muted); }
.graph-empty { padding: 40px 20px; text-align: center; }

/* ── 待核实 高亮 ──────────────────────────────────────── */
.ph {
  background: var(--ph-bg); color: var(--ph-ink);
  border-radius: 3px; padding: 0 2px; font-style: normal;
}

.tag { display: inline-block; background: var(--card-2); border-radius: 4px; padding: 0 6px; font-size: 11px; color: var(--ink-2); margin-right: 4px; }

/* ── 素材库 ───────────────────────────────────────────── */
.knav { display: flex; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
.knav .kcat {
  padding: 4px 12px; border-radius: 999px; border: 1px solid var(--baseline);
  background: var(--card); color: var(--ink-2); cursor: pointer; font: inherit; font-size: 13px;
}
.knav .kcat.active { background: var(--accent-fill); border-color: var(--accent-fill); color: var(--on-accent); }
.kview { display: grid; grid-template-columns: 340px 1fr; gap: 16px; align-items: start; }
/* #klist 与 .klist 都生效（历史 HTML 只有 id，防再次失配导致卡片零间距贴死） */
.klist, #klist { display: flex; flex-direction: column; gap: 10px; }
.kitem {
  border: 1px solid var(--border); border-radius: 6px; padding: 8px 12px;
  background: var(--card); cursor: pointer;
  display: flex; align-items: center; gap: 8px;
}
.kitem:hover { border-color: var(--baseline); }
.kitem.active { border-color: var(--accent); }
.kitem-info { flex: 1; min-width: 0; }
.kitem .kt { font-weight: 700; display: block; }
.kitem .km { color: var(--muted); font-size: 12px; display: block; margin-top: 2px; }
.kitem .kdel {
  flex: none; color: var(--critical); opacity: 0;
  transition: opacity .15s; border-color: transparent;
}
.kitem:hover .kdel { opacity: 1; }
.kdel:focus-visible { opacity: 1; }
/* 素材库 · 来源分组：同一份导入文件 / 同一栏目的条目收进一个 <details>。
   组头只报「来源名 + 条数」，条目样式不变，组内缩进一格表示从属关系。 */
.kgroup { border: 1px solid var(--border); border-radius: 6px; background: var(--card); }
.kgroup-sum {
  display: flex; align-items: center; gap: 8px; padding: 7px 12px;
  cursor: pointer; list-style: none; font-size: 12px; color: var(--ink-2);
}
.kgroup-sum::-webkit-details-marker { display: none; }  /* 收起浏览器默认三角，自己画一个 */
.kgroup-sum::before { content: '\25B8'; flex: none; color: var(--muted); }
.kgroup[open] > .kgroup-sum::before { content: '\25BE'; }
.kgroup-sum:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.kgroup-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kgroup-n { flex: none; color: var(--muted); font-variant-numeric: tabular-nums; }
.kgroup[open] > .kgroup-sum { border-bottom: 1px solid var(--border); margin-bottom: 8px; }
.kgroup > .kitem { margin: 0 8px 8px 18px; }
/* 素材库 · 批量选择：工具栏 + 条目勾选框。
   勾选框常显（不像 .kdel 只在 hover 时露脸）——多选是个能力，藏起来用户就不知道有。
   选中态只上浅底、不改描边：.active（当前打开的那条）已经占了 accent 描边，
   描边再抢就分不清「打开」和「选中」。 */
.kbar { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
/* display:flex 会盖过 UA 的 [hidden]{display:none}（本文件前面已踩过同样的坑） */
.kbar[hidden] { display: none; }
.kcheck { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-size: 13px; color: var(--ink-2); }
.kcheck input, .kitem .kpick input {
  width: 15px; height: 15px; margin: 0; cursor: pointer;
  accent-color: var(--accent-fill);  /* 用系统控件，但染成主蓝，免得默认蓝跟主题打架 */
}
.kbar-n { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.kbar-msg { color: var(--muted); font-size: 12px; }
.kbar-msg.err { color: var(--critical); }
#kbar-del { margin-left: auto; }  /* 危险动作推到最右，离「全选」远一点 */
.kitem .kpick { flex: none; display: inline-flex; align-items: center; cursor: pointer; }
.kitem.sel { background: color-mix(in srgb, var(--accent) 8%, var(--card)); }
.kdetail { border: 1px solid var(--border); border-radius: 8px; background: var(--card); padding: 16px; }
.kdetail h3 { margin-top: 0; }
.kdetail .tag-row { margin: 8px 0 12px; }
.md-body h1, .md-body h2, .md-body h3, .md-body h4, .md-body h5 { margin: 1.1em 0 .4em; }
.md-body p { margin: .4em 0; }
.md-body blockquote { margin: .6em 0; padding: 2px 12px; border-left: 3px solid var(--baseline); color: var(--ink-2); }
.md-body ul, .md-body ol { margin: .4em 0; padding-left: 1.6em; }

/* 知识条目章节卡片：## 大节 → 可折叠卡片，降低长文阅读负担 */
.md-body .sec-card {
  margin: 10px 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--sec-tint);
  overflow: hidden;
}
.md-body .sec-card > .sec-h {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--sec-tint-2);
  color: var(--ink);
  font-size: 14px;
  font-weight: 800;
  user-select: none;
  border-bottom: 1px solid var(--border);
}
.md-body .sec-card > .sec-h::-webkit-details-marker { display: none; }
.md-body .sec-card > .sec-h::before {
  content: '▸';
  flex: none;
  color: var(--accent);
  font-size: 12px;
  transition: transform .12s ease;
}
.md-body .sec-card[open] > .sec-h::before { transform: rotate(90deg); }
.md-body .sec-card:not([open]) > .sec-h { border-bottom-color: transparent; }
.md-body .sec-card > .sec-h:hover { background: color-mix(in srgb, var(--accent) 9%, var(--sec-tint-2)); }
.md-body .sec-card > .sec-h:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.md-body .sec-card .sec-body { padding: 4px 14px 12px; }
.md-body .sec-card .sec-body h4, .md-body .sec-card .sec-body h5 {
  margin: .9em 0 .3em;
  font-size: 13px;
  color: var(--accent);
}
.md-body .sec-card .sec-body hr { border: 0; border-top: 1px dashed var(--border); margin: 10px 0; }
/* 条目开头的提示/使用说明（首块引用）→ 顶部呼出卡 */
.md-body > blockquote:first-child {
  margin: 0 0 4px;
  padding: 8px 12px;
  border-left: 3px solid var(--accent);
  border-radius: 0 6px 6px 0;
  background: color-mix(in srgb, var(--accent) 8%, var(--card));
}

/* ── 申论炼题 ────────────────────────────────────────── */
.essay-config { display: flex; gap: 16px; margin-bottom: 12px; }
.essay-config .field-label { min-width: 110px; }
.essay-config .field-label:last-child { min-width: 80px; }
.config-hint {
  border: 1px solid var(--warning); background: color-mix(in srgb, var(--warning) 10%, transparent);
  color: var(--ink); border-radius: 8px; padding: 10px 14px; margin-bottom: 12px; font-size: 13px;
}
.eg-output { display: flex; flex-direction: column; gap: 12px; margin-top: 12px; }
.eq-note { border: 1px dashed var(--baseline); border-radius: 8px; padding: 10px 14px; background: var(--card); color: var(--muted); font-size: 13px; white-space: pre-wrap; }
.eq-note.warn { border-color: var(--warning); color: var(--warning); }
.eq-card { border: 1px solid var(--border); border-radius: 8px; background: var(--card); padding: 12px 14px; }
.eq-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.eq-type { background: var(--accent-fill); color: var(--on-accent); border-radius: 4px; padding: 0 8px; font-size: 12px; line-height: 20px; }
/* 题干突出：题目是面板主焦点，放大加粗；其余辅助文本降到 --muted 弱化 */
.eq-stem-row { display: flex; align-items: flex-start; gap: 8px; }
.eq-stem { font-size: 15px; line-height: 1.8; font-weight: 700; color: var(--ink); }
/* 材料信号提示：题目后浅黄感叹号，悬停/聚焦才显示 tooltip，不直接展开 */
.eq-signal-btn {
  flex: none; margin-top: 2px;
  width: 18px; height: 18px; border-radius: 50%;
  border: none; cursor: help;
  display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--warning) 18%, transparent);
  color: var(--ph-ink); font-size: 12px; line-height: 1; font-weight: 800;
}
.eq-signal-btn:hover { background: color-mix(in srgb, var(--warning) 32%, transparent); }
.eq-meta { color: var(--muted); font-size: 12px; margin-top: 6px; }
.eq-refbar { margin-top: 10px; }
/* 参考答案（按需生成，非官方）：要点与范文都保留换行，弱化于题干之下 */
.eq-ref-wrap {
  margin-top: 8px; padding: 8px 12px;
  border-left: 3px solid var(--accent);
  border-radius: 0 8px 8px 0;
  background: color-mix(in srgb, var(--accent) 6%, transparent);
}
.eq-ref-note { font-size: 11px; color: var(--muted); margin-bottom: 6px; }
.eq-ref-pane {
  font-size: 13px; line-height: 1.8; color: var(--ink-2);
  white-space: pre-wrap;
}
.eq-ref-actions { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.eq-essay {
  margin-top: 10px; padding-top: 10px;
  border-top: 1px dashed var(--border);
  font-size: 14px; line-height: 1.9; color: var(--ink);
  white-space: pre-wrap;
}
.eq-ref-pane.err, .eq-essay.err { color: var(--critical); }

/* ── 申论炼题 · 左材料 / 右题目+答案 工作区 ──────────────
   左栏在「编辑态」(#essay-edit 内的 textarea) 与「查看态」(.essay-pane，带出处高亮)
   之间切换，两者共用同一份文本，不是两份真相。 */
.essay-workspace {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 14px;
  /* 必须 start：grid 项默认 stretch 会把左栏拉伸到整行高，position:sticky 就无处可动 */
  align-items: start;
}
.essay-left {
  /* 左栏是材料镜（可能很长），独立滚动并吸顶，右栏出题时材料始终在视野里 */
  position: sticky; top: 12px;
  display: flex; flex-direction: column; gap: 8px; min-width: 0;
}
.essay-right { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.essay-right .eg-output { margin-top: 0; }  /* 抵消 .eg-output 的 margin-top，避免双间距 */
.essay-src-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.essay-src-head .result { margin-left: auto; }
.essay-src-title { font-weight: 700; color: var(--ink); }
.essay-file-hint { font-size: 12px; margin-top: 4px; }
.essay-pane {
  max-height: calc(100vh - 200px); overflow: auto;
  /* contain：否则滚轮在 pane 到底后会「链式」传给外层 .content，页面突然跳走 */
  overscroll-behavior: contain;
  white-space: pre-wrap; word-break: break-word;
  font-size: 13px; line-height: 1.9;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--card); padding: 10px 12px; color: var(--ink-2);
}
/* 材料标记行（材料一/材料二…）：分段排版后左栏一眼能定位到每段材料 */
.essay-mat-head {
  font-weight: 800; font-size: 14px; color: var(--ink);
  background: linear-gradient(transparent 62%, color-mix(in srgb, var(--accent) 22%, transparent) 62%);
}
/* 作者样式里的 display 会盖过 UA 的 [hidden]{display:none}（本文件前面已踩过同样的坑），
   凡是用 hidden 切换、而基类又写了 display 的元素都要显式补一条。 */
.essay-pane[hidden], .essay-edit[hidden], .essay-cleanbar[hidden],
.essay-legend[hidden], .essay-stale[hidden] { display: none; }

/* 出处高亮：两通道可同时出现（题目=蓝底 / 答案=青绿底+下划线），靠 JS 按字符合并后
   落到 .mh-q / .mh-a / .mh-qa 三种类上，重叠区间不靠 mark 嵌套解决。 */
mark.mh { background: transparent; color: inherit; padding: 0; border-radius: 2px; }
/* 必须显式重置背景：UA 对 mark 有默认黄底，会透过下面这层浅色 color-mix 露出来 */
mark.mh-q { background: color-mix(in srgb, var(--hl-q) 18%, transparent); }
mark.mh-a {
  background: color-mix(in srgb, var(--hl-a) 18%, transparent);
  box-shadow: inset 0 -2px 0 color-mix(in srgb, var(--hl-a) 55%, transparent);
}
mark.mh-qa {
  background: color-mix(in srgb, var(--hl-q) 12%, color-mix(in srgb, var(--hl-a) 16%, transparent));
  box-shadow: inset 0 -2px 0 color-mix(in srgb, var(--hl-a) 55%, transparent);
}
mark.mh-dim { background: transparent; box-shadow: none; }   /* 有高亮但不属于当前聚焦项 */
mark.mh-on { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 35%, transparent); }
/* 聚焦环不能把答案通道的下划线顶掉（box-shadow 只有一条，后者覆盖前者）——两者并存。 */
mark.mh-a.mh-on, mark.mh-qa.mh-on {
  box-shadow: inset 0 -2px 0 color-mix(in srgb, var(--hl-a) 55%, transparent),
              inset 0 0 0 1px color-mix(in srgb, var(--ink) 35%, transparent);
}

.essay-legend { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; font-size: 12px; color: var(--muted); }
.essay-sw { display: inline-block; width: 11px; height: 11px; border-radius: 3px; vertical-align: -1px; margin-right: 4px; }
.essay-sw.q { background: color-mix(in srgb, var(--hl-q) 32%, transparent); }
.essay-sw.a { background: color-mix(in srgb, var(--hl-a) 32%, transparent); }
.essay-cleanbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12px; color: var(--muted); }
.essay-removed { flex-basis: 100%; border: 1px dashed var(--baseline); border-radius: var(--r); padding: 8px 10px; font-size: 12px; }
.essay-rm-item { margin: 5px 0; }
.essay-rm-reason { color: var(--muted); margin-right: 6px; }
.essay-stale {
  border: 1px solid var(--warning); background: color-mix(in srgb, var(--warning) 10%, transparent);
  color: var(--ink); border-radius: var(--r); padding: 8px 10px; font-size: 12px; line-height: 1.6;
}

/* 参考要点：骨架行（无出处）+ 得分点（可点，点亮该点的材料出处） */
.eq-step { font-size: 13px; line-height: 1.8; color: var(--ink-2); white-space: pre-wrap; }
.eq-pt {
  border-left: 2px solid var(--border); padding: 3px 0 3px 8px; margin: 6px 0;
  cursor: pointer; font-size: 13px; line-height: 1.8; color: var(--ink-2);
}
.eq-pt:hover, .eq-pt.on { border-left-color: var(--accent); background: color-mix(in srgb, var(--accent) 5%, transparent); }
.eq-para { font-size: 14px; line-height: 1.9; color: var(--ink); }
.eq-para + .eq-para { margin-top: 10px; }
.eq-para-h { font-size: 15px; font-weight: 700; color: var(--ink); margin-bottom: 8px; }

/* 出处标签：点它 → 左侧材料亮出对应原句；未定位的走虚线，点开可看模型声称引用的原文 */
.eq-src-row { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
.eq-src {
  font-size: 11px; color: var(--muted); background: var(--card-2);
  border: 1px solid var(--border); border-radius: var(--r-xs); padding: 1px 6px;
  cursor: pointer; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.eq-src:hover { border-color: var(--accent); color: var(--ink); }
.eq-src.miss { border-style: dashed; cursor: help; }
.eq-src.miss:hover { border-color: var(--warning); }
.eq-src.plain { cursor: default; border-style: dashed; }
.eq-src.plain:hover { border-color: var(--border); color: var(--muted); }
.eq-src-label { font-size: 11px; color: var(--muted); align-self: center; }
/* 未定位片段点开后摊出的「模型声称引用的原文」：把候选摊平给用户核对，
   而不是因为它对不上就藏起来——溯源的价值在可核验，不在显得有据。 */
.eq-src-claim {
  margin-top: 4px; padding: 6px 8px; font-size: 12px; line-height: 1.7;
  border-left: 2px solid var(--warning); color: var(--ink-2);
  background: color-mix(in srgb, var(--warning) 7%, transparent);
}
.eq-src-claim-h { color: var(--muted); margin-right: 4px; }
.eq-src-claim-t { word-break: break-word; }
.eq-src-none { margin-top: 6px; font-size: 11px; color: var(--muted); }
.eq-pt-text, .eq-para-text { white-space: pre-wrap; word-break: break-word; }
.eq-card.on { border-color: var(--accent); }   /* 右栏回声：左栏此刻亮的是这一题 */

/* 答题 + 批改区：每张题卡上「我的作答」→「提交批改」→ 批改结果 */
.eq-ans-wrap { margin-top: 10px; border-top: 1px dashed var(--grid); padding-top: 10px; }
.eq-ans-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
.eq-ans-label { font-size: 13px; font-weight: 700; color: var(--ink); }
.eq-ans-count { font-size: 11px; color: var(--muted); }
.eq-ans-count.over { color: var(--critical); font-weight: 700; }
.eq-ans-input {
  width: 100%; box-sizing: border-box; resize: vertical; min-height: 72px;
  font: inherit; font-size: 14px; line-height: 1.8; color: var(--ink);
  background: var(--card); border: 1px solid var(--border); border-radius: 6px; padding: 8px 10px;
}
.eq-ans-input:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: transparent; }
.eq-ans-actions { display: flex; gap: 8px; margin-top: 8px; }
.eq-review { margin-top: 10px; }
.eq-review.err { color: var(--critical); }
.eq-review-score { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.eq-review-total {
  font-size: 18px; font-weight: 800; color: var(--accent);
  padding: 2px 10px; border-radius: 6px; background: var(--accent-soft);
}
.eq-review-overall { font-size: 13px; line-height: 1.8; color: var(--ink-2); margin-bottom: 8px; white-space: pre-wrap; }
.eq-line-table { display: flex; flex-direction: column; gap: 6px; }
.eq-line-row { display: flex; gap: 8px; align-items: flex-start; }
.eq-line-mark {
  flex: none; width: 20px; text-align: center; font-size: 13px; font-weight: 700;
  border-radius: 4px; padding: 1px 0;
}
.eq-line-mark.ok { color: var(--good); background: color-mix(in srgb, var(--good) 10%, transparent); }
.eq-line-mark.half { color: var(--warning); background: color-mix(in srgb, var(--warning) 10%, transparent); }
.eq-line-mark.no { color: var(--critical); background: color-mix(in srgb, var(--critical) 9%, transparent); }
.eq-line-body { flex: 1; min-width: 0; }
.eq-line-text { font-size: 13px; line-height: 1.8; color: var(--ink); white-space: pre-wrap; word-break: break-word; }
.eq-line-note { font-size: 12px; line-height: 1.7; color: var(--muted); }
.eq-cov-row { display: flex; gap: 6px; flex-wrap: wrap; }
.eq-cov-chip {
  font-size: 12px; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border);
  color: var(--ink-2); background: var(--card);
}
.eq-cov-chip.full { color: var(--good); border-color: color-mix(in srgb, var(--good) 45%, transparent); }
.eq-cov-chip.half { color: var(--warning); border-color: color-mix(in srgb, var(--warning) 45%, transparent); }
.eq-cov-chip.miss { color: var(--critical); border-color: color-mix(in srgb, var(--critical) 40%, transparent); }
.eq-lost { font-size: 13px; line-height: 1.8; color: var(--ink-2); }
.eq-ans-hrow { display: flex; align-items: center; gap: 10px; }
.eq-ans-hrow .eq-para-h { margin-bottom: 4px; }
.eq-full-ans {
  font-size: 13px; line-height: 1.9; color: var(--ink); white-space: pre-wrap; word-break: break-word;
  border-left: 3px solid var(--sec-tint-2); padding: 6px 12px; background: var(--card-2); border-radius: 0 6px 6px 0;
}
.eq-upg-table { display: flex; flex-direction: column; gap: 4px; }
.eq-upg-row { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: baseline; font-size: 13px; line-height: 1.7; }
.eq-upg-orig { color: var(--muted); text-decoration: line-through; }
.eq-upg-arrow { color: var(--baseline); }
.eq-upg-better { color: var(--good); font-weight: 600; }
.eq-upg-why { color: var(--muted); font-size: 12px; flex-basis: 100%; }
.eq-errtype { margin-bottom: 8px; }
.eq-errtype-main { font-size: 13px; line-height: 1.7; color: var(--ink-2); }
.eq-recur {
  margin-top: 4px; padding: 6px 10px; font-size: 12px; line-height: 1.7;
  border-left: 3px solid var(--warning); color: var(--warning);
  background: color-mix(in srgb, var(--warning) 7%, transparent); border-radius: 0 6px 6px 0;
}
.eq-duo-head { display: flex; align-items: baseline; gap: 8px; margin: 8px 0 6px; }
.eq-duo-name { font-size: 14px; font-weight: 800; color: var(--accent); }

.essay-legend-item { display: inline-flex; align-items: center; }
/* 超出出题窗口的那截：明说"没参与溯源"，否则用户会以为高亮漏了。 */
.essay-outwin {
  margin-top: 10px; padding: 8px 10px; font-size: 12px; line-height: 1.6;
  border: 1px dashed var(--baseline); border-radius: var(--r);
  color: var(--muted); background: var(--card-2);
}
.essay-clean-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.essay-clean-count { color: var(--ink-2); }
.essay-rm-text { color: var(--ink-2); word-break: break-word; }

/* ── tooltip ──────────────────────────────────────────── */
.tooltip {
  position: fixed; z-index: 100; max-width: 340px;
  background: var(--ink); color: var(--bg);
  border-radius: 6px; padding: 8px 10px; font-size: 12px; line-height: 1.5;
  pointer-events: none; box-shadow: var(--shadow);
}
.tooltip .tt-title { font-weight: 800; }
.tooltip .tt-meta { opacity: .8; margin-top: 2px; }

/* ── 素材库：上传生成 ─────────────────────────────────── */
.kimport {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 12px; padding: 10px 12px;
  border: 1px dashed var(--baseline); border-radius: 8px;
  flex-wrap: wrap;
}
.kimport #kimp-cat { min-width: 120px; }

/* 素材库 · 文件选择器：原生 input 视觉隐藏（可聚焦、可 Tab），样式全走胶囊按钮 */
.kimport .file-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.kimport .kimp-pick {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 3px 13px 3px 4px; border-radius: 999px;
  background: var(--card); color: var(--ink-2);
  border: 1px solid var(--border); cursor: pointer;
  font-size: 13px; white-space: nowrap; user-select: none;
  transition: border-color .15s, color .15s, background-color .15s;
}
.kimport .kimp-pick:hover { border-color: var(--accent); color: var(--accent); background: var(--sec-tint); }
.kimport .kimp-pick-ic {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent);
  font-size: 13px; font-weight: 800; line-height: 1;
  transition: background-color .15s, color .15s;
}
.kimport .kimp-pick:hover .kimp-pick-ic { background: var(--accent-fill); color: var(--on-accent); }
#kimp-file:focus-visible + .kimp-pick {
  outline: 2px solid var(--accent); outline-offset: 2px; border-color: transparent;
}
.kimport .kimp-chip {
  display: inline-flex; align-items: center; gap: 8px;
  max-width: 300px; padding: 3px 6px 3px 13px; border-radius: 999px;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
  font-size: 13px; color: var(--ink); white-space: nowrap;
}
.kimport .kimp-chip[hidden] { display: none; }
.kimport .kimp-chip-name { overflow: hidden; text-overflow: ellipsis; font-weight: 700; }
.kimport .kimp-chip-size { font: 11px var(--mono); color: var(--muted); flex: none; }
.kimport .kimp-chip-x {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: var(--muted);
  font-size: 14px; line-height: 1; cursor: pointer;
  transition: background-color .15s, color .15s;
}
.kimport .kimp-chip-x:hover { background: var(--critical); color: #fff; }
.kimp-preview {
  grid-column: 1 / -1;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--card); padding: 16px;
}
.kimp-preview .kimp-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.kimp-preview .kimp-head h3 { margin: 0 0 8px; }
.kimp-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px 14px; margin: 12px 0;
}
.kimp-grid .wide { grid-column: 1 / -1; }
.kimp-area-label { color: var(--ink-2); font-size: 13px; }
.textarea.code { font-family: var(--mono); font-size: 13px; }
#kimp-md-preview { margin-top: 12px; border-top: 1px dashed var(--border); padding-top: 8px; }

/* ── 账号登录/注册遮罩 ────────────────────────────────── */
/* 注意：display:flex 会盖过 UA 的 [hidden]{display:none}，需显式补回 */
.auth-overlay {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  background: rgba(11, 11, 11, 0.42);
  backdrop-filter: blur(2px);
  padding: 16px;
}
.auth-overlay[hidden] { display: none; }
[data-theme="dark"] .auth-overlay { background: rgba(0, 0, 0, 0.55); }
.auth-card {
  width: 360px; max-width: 100%;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: var(--shadow);
  padding: 24px 26px;
  display: flex; flex-direction: column; gap: 12px;
}
.auth-brand { display: flex; align-items: center; gap: 10px; }
.auth-title { margin: 0; font-size: 17px; }
.auth-submit { margin-top: 4px; }
/* 手机号+验证码登录：验证码输入框与发送按钮同行 */
.auth-code-row { display: flex; gap: 8px; align-items: stretch; }
.auth-code-row .input { flex: 1; min-width: 0; }
.auth-send { white-space: nowrap; align-self: stretch; }
.user-name { color: var(--ink-2); font-size: 13px; align-self: center; }

/* ── 右上角账号按钮 + 账号弹窗 ────────────────────────── */
.account-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 6px;
}
.account-btn:hover { background: var(--card-2); border-color: var(--muted); }
.account-btn[hidden] { display: none; }  /* 覆盖 display:inline-flex，未登录时真正隐藏 */
.account-btn .user-name { align-self: center; max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-avatar { font-size: 16px; line-height: 1; }

.account-card {
  width: 440px; max-width: 100%;
  position: relative;
  padding: 22px 24px 18px;
  gap: 4px; /* 覆盖 .auth-card 的 12px，间距由 .account-section 的 margin 控制 */
}
.account-close {
  position: absolute; top: 12px; right: 12px;
  padding: 2px 9px; font-size: 13px; line-height: 1.4;
  border-color: transparent; color: var(--ink-2);
}
.account-close:hover { background: var(--card-2); border-color: var(--border); color: var(--ink); }

.account-section { margin-bottom: 18px; }
.account-section:last-child { margin-bottom: 0; }
.account-h3 {
  margin: 0 0 10px;
  font-size: 13px; font-weight: 700; color: var(--ink-2);
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}

.stat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.stat-tile {
  background: var(--card-2); border: 1px solid var(--border);
  border-radius: 8px; padding: 12px; min-width: 0;
}
.stat-num { font-size: 20px; font-weight: 800; line-height: 1.2; }
.stat-label { font-size: 12px; color: var(--muted); margin-top: 2px; }
.stat-sub { font-size: 11px; color: var(--muted); margin-top: 4px; line-height: 1.5; }

.pref-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 12px;
}
.pref-row:last-child { margin-bottom: 0; }
.pref-row label { font-size: 13px; color: var(--ink-2); flex: none; }
.pref-row .input { flex: 1 1 auto; min-width: 0; }

.seg { display: inline-flex; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; flex: none; }
.seg button {
  padding: 5px 14px; font: inherit; font-size: 13px;
  background: transparent; border: none; cursor: pointer;
  color: var(--ink-2);
}
.seg button:hover { background: var(--card-2); color: var(--ink); }
.seg button.active { background: var(--accent-fill); color: var(--on-accent); }

/* ── 响应式 ───────────────────────────────────────────── */
@media (max-width: 1100px) {
  .graph-wrap { flex-direction: column; height: auto; }
  .graph-canvas { height: 420px; }
  .graph-side { width: 100%; }
  .kview { grid-template-columns: 1fr; }
  /* 申论炼题：窄屏塌成单列（材料在上、题目在下），左栏不能再吸顶 */
  .essay-workspace { grid-template-columns: 1fr; }
  .essay-left { position: static; }
  .essay-pane { max-height: 45vh; }
}

/* ══「雾蓝·档案纸」精修层 ═════════════════════════════════
 * 叠加在既有规则之后，仅补视觉、不动结构。 */

/* 圆角层级：标准控件 8 / 容器卡 12 / 浮层 16 */
.btn, .input, .textarea, select.input, .seg { border-radius: var(--r); }
.side-block, .graph-canvas, .kdetail { border-radius: var(--r-md); }
.kitem { border-radius: var(--r); }

/* 输入聚焦：长春花蓝 2px 描边 + 柔和外环（替代生硬 outline） */
.input:focus, .textarea:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
}

/* 主按钮 hover 提亮（渐变高光在 .btn.primary 定义处） */
.btn.primary:hover { filter: brightness(0.95); }

/* KPI 指标卡：白卡 + 顶边长春花蓝彩条 + 12px 圆角 + 低阴影 */
.stat-tile {
  background: var(--card);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
  padding: 12px 14px;
}
.stat-tile:hover { transform: translateY(-1px); box-shadow: 0 2px 6px -1px rgba(0, 0, 0, 0.06); }
.stat-num { font-size: 24px; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }

/* 图谱图例：关系条数计数（右侧 mono，右对齐） */
.legend-chip .count {
  margin-left: auto; font: 11px var(--mono);
  color: var(--muted); font-variant-numeric: tabular-nums;
}

/* 主题化确认弹窗（替代 window.confirm，见 app.js appConfirm） */
.btn.danger {
  background: var(--critical); border-color: var(--critical); color: #fff;
}
.btn.danger:hover { filter: brightness(1.08); }
.app-confirm-mask {
  position: fixed; inset: 0; z-index: 2000;
  background: rgba(12, 20, 40, 0.55);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.app-confirm {
  width: min(420px, 100%);
  background: var(--card); color: var(--ink);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: 0 8px 24px -4px rgba(0, 0, 0, 0.25);
  padding: 18px 18px 14px;
}
.app-confirm-title { margin: 0 0 6px; font-size: 15px; font-weight: 700; }
.app-confirm-msg {
  margin: 0 0 16px; color: var(--ink-2); font-size: 13px; line-height: 1.7;
  word-break: break-word;
}
.app-confirm-actions { display: flex; justify-content: flex-end; gap: 8px; }

/* ══ 质感二期 · reactbits 风格移植（磨砂玻璃 / 渐变光边 / 动效点缀）══
 * 仅追加视觉层：不改结构、不动 markup；颜色一律走既有令牌；明暗自动。
 * keyframes pzRise/pzFade/pzPop 与 canvas-app/src/index.css 同名块逐字同步；
 * 本文件同时服务控制台 + /home/ + /admin/（三者均链 style.css）。 */

/* ── 入场 / 弹出（display 切换即自动重放）────────────── */
@keyframes pzRise { from { opacity: 0; transform: translateY(8px) } to { opacity: 1; transform: none } }
@keyframes pzFade { from { opacity: 0 } to { opacity: 1 } }
@keyframes pzPop  { from { opacity: 0; transform: translateY(6px) scale(.96) } to { opacity: 1; transform: none } }

.panel.active { animation: pzRise .22s cubic-bezier(.2,.7,.3,1) both; }
.auth-overlay:not([hidden]) { animation: pzFade .18s ease; }
.app-confirm-mask { animation: pzFade .16s ease; }
.auth-card, .account-card, .app-confirm { animation: pzPop .2s cubic-bezier(.2,.7,.3,1) both; }

/* 列表/题目卡入场 stagger（仅新建节点，封顶前 7 个延迟，≥7 不延迟） */
.klist .kitem, #eg-output .eq-card { animation: pzRise .3s cubic-bezier(.2,.7,.3,1) both; }
.klist .kitem:nth-child(2),  #eg-output .eq-card:nth-child(2)  { animation-delay: 24ms; }
.klist .kitem:nth-child(3),  #eg-output .eq-card:nth-child(3)  { animation-delay: 48ms; }
.klist .kitem:nth-child(4),  #eg-output .eq-card:nth-child(4)  { animation-delay: 72ms; }
.klist .kitem:nth-child(5),  #eg-output .eq-card:nth-child(5)  { animation-delay: 96ms; }
.klist .kitem:nth-child(6),  #eg-output .eq-card:nth-child(6)  { animation-delay: 120ms; }
.klist .kitem:nth-child(7),  #eg-output .eq-card:nth-child(7)  { animation-delay: 144ms; }

/* ── 磨砂玻璃 + 浮层光晕（不支持 backdrop-filter 退纯卡色）────── */
.topbar, .sidebar, .auth-card, .account-card, .app-confirm,
.home-page .gzw-topbar, .admin-page .gzw-topbar {
  box-shadow: var(--shadow), 0 10px 30px -12px color-mix(in srgb, var(--accent) 20%, transparent);
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .topbar, .sidebar, .auth-card, .account-card, .app-confirm,
  .home-page .gzw-topbar, .admin-page .gzw-topbar {
    background: color-mix(in srgb, var(--card) 88%, transparent);
    -webkit-backdrop-filter: blur(12px) saturate(1.15);
    backdrop-filter: blur(12px) saturate(1.15);
  }
}
/* 遮罩磨砂加深（原 2px → 4px），浮层卡下有内容模糊更明显 */
.auth-overlay, .app-confirm-mask {
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

/* ── 交互件：平滑过渡 / 按压态 ────────────────────────── */
.btn {
  position: relative;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease,
              box-shadow .15s ease, filter .15s ease, transform .12s ease;
}
.btn:active:not(:disabled) { transform: translateY(1px) scale(.99); }
.knav .kcat, .seg button, .legend-chip, .kitem {
  transition: background-color .15s ease, color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.kitem:hover { border-color: color-mix(in srgb, var(--accent) 40%, transparent); }

/* 侧栏导航：hover 淡 tint；激活 = 浅填充胶囊 + 左侧长春花蓝圆点 */
.nav-item {
  position: relative;
  border-radius: var(--r);
  transition: background-color .15s ease, color .15s ease, box-shadow .15s ease;
}
.nav-item:hover { background: color-mix(in srgb, var(--accent) 9%, var(--card-2)); }
.nav-item.active { background: color-mix(in srgb, var(--accent) 13%, var(--card-2)); }
.nav-item.active::before {
  content: ''; position: absolute; left: -6px; top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 14px; border-radius: 2px;
  background: var(--accent);
}

/* ── 焦点环（键盘导航可见）───────────────────────────── */
.btn:focus-visible, .nav-item:focus-visible,
.seg button:focus-visible, .knav .kcat:focus-visible, a:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
}

/* ── 渐变光边 spotlight（masked-pseudo 1px 渐变描边 + 柔辉光）──── */
@supports ((-webkit-mask-composite: xor) or (mask-composite: exclude)) {
  .btn::before {
    content: ''; position: absolute; inset: -1px; border-radius: inherit; padding: 1px;
    background: linear-gradient(135deg,
      color-mix(in srgb, var(--accent-fill) 70%, transparent),
      color-mix(in srgb, var(--accent) 24%, transparent) 42%,
      color-mix(in srgb, var(--accent) 10%, transparent) 60%,
      color-mix(in srgb, var(--accent-fill) 85%, transparent));
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
    opacity: 0; transition: opacity .18s ease; pointer-events: none;
  }
  .btn:not(:disabled):hover::before, .btn:focus-visible::before { opacity: 1; }
  .btn:hover, .btn:focus-visible {
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 12%, transparent),
                0 5px 16px -6px color-mix(in srgb, var(--accent) 30%, transparent);
  }
}
@supports not ((-webkit-mask-composite: xor) or (mask-composite: exclude)) {
  .btn:hover, .btn:focus-visible {
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
  }
}
/* 渐变描边精确覆盖原 border 位（inset:-1px 扩展至 border-box）：hover/聚焦时隐藏实线避免双线 */
.btn:not(:disabled):hover, .btn:focus-visible { border-color: transparent; }

/* ── 卡片 hover：秒变 → 平滑微抬 + 光晕描边 ───────────── */
.stat-tile { transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; }
.stat-tile:hover {
  box-shadow: var(--shadow), 0 0 0 1px color-mix(in srgb, var(--accent) 26%, transparent),
              0 6px 18px -8px color-mix(in srgb, var(--accent) 30%, transparent);
}
.gzw-card { transition: box-shadow .15s ease, border-color .15s ease; }
.gzw-card:hover {
  box-shadow: var(--shadow), 0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent),
              0 6px 18px -10px color-mix(in srgb, var(--accent) 28%, transparent);
}

/* ── 关运动（与 canvas index.css 同名块逐字同步）────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ══════════════════════════════════════════════════════════
 * 磨砂玻璃 · 登录遮罩 + 登录成功欢迎页（服务 控制台 / 与 /home/）
 * 视觉原则：背景就是真实网站页面（无霓虹/纯色艺术底），只在其上叠
 *      一层毛玻璃 + 明暗纱；欢迎页手写 "Hello" 浮在磨砂页面上，
 *      笔迹颜色随明暗主题自适应（--ink），配同调光晕保证可读。
 *      reduced-motion 由文件尾部全局 kill 兜底。
 * ══════════════════════════════════════════════════════════ */

/* 登录/账号遮罩：磨砂增强——真实页面透出后被打散成毛玻璃（覆盖 L731 的 4px） */
.auth-overlay {
  -webkit-backdrop-filter: blur(12px) saturate(1.2);
  backdrop-filter: blur(12px) saturate(1.2);
}

/* ── 登录成功欢迎页（一次性，播完自动淡出）──────────────
 * 半透 + backdrop 磨砂：底下真实页面（已登录的控制台/看板）透出成毛玻璃，
 * 手写 Hello 直接浮在上层；明暗自适应、主题色随 --ink。 */
.hello-overlay {
  position: fixed; inset: 0; z-index: 400;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--bg) 46%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  backdrop-filter: blur(14px) saturate(1.3);
}
.hello-overlay[hidden] { display: none; }
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .hello-overlay { background: color-mix(in srgb, var(--bg) 76%, transparent); }
}
.hello-stage {
  display: flex; flex-direction: column; align-items: center; gap: 22px;
  width: min(70vw, 760px);
  text-align: center;
}
#lx-hello-svg { width: 100%; height: auto; overflow: visible; display: block; }
#lx-hello-svg path {
  fill: var(--ink);
  fill-opacity: 0;
  stroke: var(--ink);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  filter:
    drop-shadow(0 0 5px color-mix(in srgb, var(--bg) 70%, transparent))
    drop-shadow(0 0 12px rgba(255, 255, 255, 0.30))
    drop-shadow(0 2px 6px rgba(0, 0, 0, 0.22));
}
.hello-sub { margin: 0; color: var(--ink-2); font-size: 15px; letter-spacing: 0.12em; }
@media (max-width: 640px) { .hello-stage { width: 82vw; } }
