/* GameBox 接手站 —— 图与动画共享样式
 * 与 assets/course.css 配套使用；颜色全部复用 course.css 里已有的 CSS 变量，
 * 因此深浅色主题自动跟随，无需重复定义调色板。
 *
 * 设计原则：
 * 1. 图在 JS 不执行时必须完整可读（默认全景态，所有元素可见）。
 * 2. 动画只做「强调」，不承载信息；prefers-reduced-motion 下全部关闭。
 * 3. SVG 用 viewBox 缩放，窄屏交给外层容器横向滚动，页面本身不横向滚。
 */

/* ---------- 图容器 ---------- */

.figure {
  margin: 0 0 2.75rem;
}

.figure-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  margin-bottom: 0.75rem;
}

.figure-title {
  font-family: var(--serif);
  font-size: 1.15rem;
  font-weight: 700;
  margin: 0;
}

.figure-title .figure-num {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  color: var(--accent);
  display: block;
  margin-bottom: 0.15rem;
}

.figure-stage {
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--bg);
  padding: 0.75rem;
  overflow-x: auto;
  overflow-y: hidden;
}

.figure-stage svg {
  display: block;
  width: 100%;
  min-width: 560px;
  height: auto;
}

.figure-caption {
  margin: 0.75rem 0 0;
  font-size: 0.9rem;
  color: var(--fg-muted);
}

/* ---------- 步进控制条 ---------- */

.figure-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.75rem;
}

/* 无 JS 时控制条毫无意义，默认藏起来，由 diagram.js 打开 */
.figure-controls[hidden] {
  display: none;
}

.figure-btn {
  font-family: var(--mono);
  font-size: 0.78rem;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--code-bg);
  color: var(--fg);
  cursor: pointer;
  line-height: 1.4;
}

.figure-btn:hover:not([disabled]) {
  border-color: var(--accent);
  color: var(--accent);
}

.figure-btn[disabled] {
  opacity: 0.4;
  cursor: default;
}

.figure-btn[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
}

.figure-step-label {
  font-size: 0.85rem;
  color: var(--fg-muted);
  margin-left: 0.3rem;
  flex: 1 1 12rem;
  min-width: 0;
}

.figure-step-label b {
  color: var(--fg);
  font-weight: 600;
}

/* ---------- SVG 基础元素 ---------- */

.dg {
  font-family: var(--serif);
}

/* 方块节点 */
.dg-box {
  fill: var(--bg);
  stroke: var(--fg-muted);
  stroke-width: 1.5;
}

.dg-box.is-accent {
  stroke: var(--accent);
  fill: var(--accent-soft);
}

.dg-box.is-ok {
  stroke: var(--ok);
  fill: var(--ok-bg);
}

.dg-box.is-warn {
  stroke: var(--warn);
  fill: var(--warn-bg);
}

.dg-box.is-bad {
  stroke: var(--bad);
  fill: var(--bad-bg);
}

/* 缺席 / 不存在的东西：虚线空框 */
.dg-box.is-absent {
  stroke: var(--bad);
  stroke-dasharray: 5 4;
  fill: none;
}

/* 分区底板 */
.dg-zone {
  fill: var(--rule-soft);
  stroke: var(--rule);
  stroke-width: 1;
  stroke-dasharray: 3 3;
  opacity: 0.55;
}

/* 文字 */
.dg-label {
  fill: var(--fg);
  font-size: 13px;
  font-weight: 600;
  dominant-baseline: middle;
}

.dg-sub {
  fill: var(--fg-muted);
  font-family: var(--mono);
  font-size: 10.5px;
  dominant-baseline: middle;
}

.dg-zone-title {
  fill: var(--fg-muted);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  dominant-baseline: middle;
}

.dg-note {
  fill: var(--fg-muted);
  font-size: 11.5px;
  dominant-baseline: middle;
}

.dg-note.is-bad {
  fill: var(--bad);
}

.dg-note.is-warn {
  fill: var(--warn);
}

.dg-note.is-ok {
  fill: var(--ok);
}

/* 连线 */
.dg-edge {
  fill: none;
  stroke: var(--fg-muted);
  stroke-width: 1.6;
}

.dg-edge.is-accent {
  stroke: var(--accent);
}

.dg-edge.is-ok {
  stroke: var(--ok);
}

.dg-edge.is-warn {
  stroke: var(--warn);
}

.dg-edge.is-bad {
  stroke: var(--bad);
}

/* 箭头（marker 定义在页面顶部的 .dg-defs 里，全页共用） */
.dg-arrowhead {
  fill: var(--fg-muted);
}

.dg-arrowhead.is-accent {
  fill: var(--accent);
}

.dg-arrowhead.is-ok {
  fill: var(--ok);
}

.dg-arrowhead.is-warn {
  fill: var(--warn);
}

.dg-arrowhead.is-bad {
  fill: var(--bad);
}

.dg-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* 连线上的序号徽标 */
.dg-badge {
  fill: var(--bg);
  stroke: var(--accent);
  stroke-width: 1.4;
}

.dg-badge-text {
  fill: var(--accent);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  text-anchor: middle;
  dominant-baseline: central;
}

/* ---------- 流动动画 ---------- */

/* 加了 is-flow 的连线会有一条虚线顺着方向跑 */
.dg-flow {
  fill: none;
  stroke-width: 2.2;
  stroke-dasharray: 7 9;
  stroke-linecap: round;
  opacity: 0.9;
  animation: dg-dash 1.4s linear infinite;
}

@keyframes dg-dash {
  to {
    stroke-dashoffset: -32;
  }
}

/* 反向流动（用于回传箭头） */
.dg-flow.is-reverse {
  animation-name: dg-dash-reverse;
}

@keyframes dg-dash-reverse {
  to {
    stroke-dashoffset: 32;
  }
}

/* 节点脉冲，用来点出「当前这一步发生在哪」 */
.dg-pulse {
  animation: dg-pulse 1.8s ease-in-out infinite;
  transform-box: fill-box;
  transform-origin: center;
}

@keyframes dg-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.45;
  }
}

/* ---------- 步进高亮 ---------- */

/* 全景态（data-step 未设置或为 0）：一切正常显示，不做任何压暗。
 * 一旦进入某一步，非当前步的元素压暗，当前步的元素提亮。 */

.dg-step {
  transition:
    opacity 0.25s ease,
    stroke-width 0.25s ease;
}

.dg[data-step]:not([data-step="0"]) .dg-step {
  opacity: 0.16;
}

.dg[data-step="1"] .dg-step[data-s="1"],
.dg[data-step="2"] .dg-step[data-s="2"],
.dg[data-step="3"] .dg-step[data-s="3"],
.dg[data-step="4"] .dg-step[data-s="4"],
.dg[data-step="5"] .dg-step[data-s="5"],
.dg[data-step="6"] .dg-step[data-s="6"],
.dg[data-step="7"] .dg-step[data-s="7"],
.dg[data-step="8"] .dg-step[data-s="8"] {
  opacity: 1;
}

/* 已经走过的步骤保持半亮，让人看得出「走到哪了」 */
.dg[data-step="2"] .dg-step[data-s="1"],
.dg[data-step="3"] .dg-step[data-s="1"],
.dg[data-step="3"] .dg-step[data-s="2"],
.dg[data-step="4"] .dg-step[data-s="1"],
.dg[data-step="4"] .dg-step[data-s="2"],
.dg[data-step="4"] .dg-step[data-s="3"],
.dg[data-step="5"] .dg-step[data-s="1"],
.dg[data-step="5"] .dg-step[data-s="2"],
.dg[data-step="5"] .dg-step[data-s="3"],
.dg[data-step="5"] .dg-step[data-s="4"],
.dg[data-step="6"] .dg-step[data-s="1"],
.dg[data-step="6"] .dg-step[data-s="2"],
.dg[data-step="6"] .dg-step[data-s="3"],
.dg[data-step="6"] .dg-step[data-s="4"],
.dg[data-step="6"] .dg-step[data-s="5"],
.dg[data-step="7"] .dg-step[data-s="1"],
.dg[data-step="7"] .dg-step[data-s="2"],
.dg[data-step="7"] .dg-step[data-s="3"],
.dg[data-step="7"] .dg-step[data-s="4"],
.dg[data-step="7"] .dg-step[data-s="5"],
.dg[data-step="7"] .dg-step[data-s="6"],
.dg[data-step="8"] .dg-step[data-s="1"],
.dg[data-step="8"] .dg-step[data-s="2"],
.dg[data-step="8"] .dg-step[data-s="3"],
.dg[data-step="8"] .dg-step[data-s="4"],
.dg[data-step="8"] .dg-step[data-s="5"],
.dg[data-step="8"] .dg-step[data-s="6"],
.dg[data-step="8"] .dg-step[data-s="7"] {
  opacity: 0.5;
}

/* 步进模式下，只让当前步的连线流动，避免满屏乱跑 */
.dg[data-step]:not([data-step="0"]) .dg-flow {
  animation-play-state: paused;
}

.dg[data-step="1"] .dg-step[data-s="1"] .dg-flow,
.dg[data-step="2"] .dg-step[data-s="2"] .dg-flow,
.dg[data-step="3"] .dg-step[data-s="3"] .dg-flow,
.dg[data-step="4"] .dg-step[data-s="4"] .dg-flow,
.dg[data-step="5"] .dg-step[data-s="5"] .dg-flow,
.dg[data-step="6"] .dg-step[data-s="6"] .dg-flow,
.dg[data-step="7"] .dg-step[data-s="7"] .dg-flow,
.dg[data-step="8"] .dg-step[data-s="8"] .dg-flow {
  animation-play-state: running;
}

/* ---------- 图例 ---------- */

.dg-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.82rem;
  color: var(--fg-muted);
}

.dg-legend li {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0;
}

.dg-legend i {
  width: 0.9rem;
  height: 0.9rem;
  border-radius: 3px;
  border: 1.5px solid var(--fg-muted);
  background: var(--bg);
  flex-shrink: 0;
}

.dg-legend .lg-accent {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.dg-legend .lg-ok {
  border-color: var(--ok);
  background: var(--ok-bg);
}

.dg-legend .lg-warn {
  border-color: var(--warn);
  background: var(--warn-bg);
}

.dg-legend .lg-bad {
  border-color: var(--bad);
  background: var(--bad-bg);
}

.dg-legend .lg-absent {
  border-color: var(--bad);
  border-style: dashed;
  background: none;
}

/* ---------- 目录树（map/structure.html） ---------- */

.tree,
.tree ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.tree {
  margin: 0 0 2rem;
  font-size: 0.95rem;
}

.tree ul {
  margin-left: 0.75rem;
  padding-left: 0.9rem;
  border-left: 1px solid var(--rule);
}

.tree li {
  margin: 0;
  padding: 0.28rem 0;
}

.tree summary {
  cursor: pointer;
  padding: 0.28rem 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 0.6rem;
}

.tree summary::-webkit-details-marker {
  display: none;
}

.tree summary::before {
  content: "▸";
  color: var(--accent);
  font-size: 0.8em;
  flex-shrink: 0;
  transition: transform 0.15s ease;
  display: inline-block;
}

.tree details[open] > summary::before {
  transform: rotate(90deg);
}

.tree-leaf {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 0.6rem;
  padding-left: 1.1rem;
}

.tree code {
  font-family: var(--mono);
  font-size: 0.86rem;
  background: var(--code-bg);
  padding: 0.1rem 0.35rem;
  border-radius: 3px;
  flex-shrink: 0;
}

.tree-role {
  color: var(--fg-muted);
  font-size: 0.88rem;
  flex: 1 1 14rem;
  min-width: 0;
}

.tree-size {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--fg-muted);
  opacity: 0.75;
  flex-shrink: 0;
}

.tag {
  font-family: var(--mono);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
  border: 1px solid;
  flex-shrink: 0;
  white-space: nowrap;
}

.tag-hot {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-soft);
}

.tag-avoid {
  color: var(--bad);
  border-color: var(--bad);
  background: var(--bad-bg);
}

.tag-dead {
  color: var(--fg-muted);
  border-color: var(--rule);
  background: var(--rule-soft);
}

.tag-ext {
  color: var(--warn);
  border-color: var(--warn);
  background: var(--warn-bg);
}

.tag-ok {
  color: var(--ok);
  border-color: var(--ok);
  background: var(--ok-bg);
}

/* ---------- 可访问性与打印 ---------- */

@media (prefers-reduced-motion: reduce) {
  .dg-flow,
  .dg-pulse {
    animation: none !important;
  }
  .dg-step {
    transition: none;
  }
}

@media print {
  .figure-controls {
    display: none !important;
  }
  /* 打印时强制回到全景态，免得只印出高亮的那一步 */
  .dg[data-step] .dg-step {
    opacity: 1 !important;
  }
  .figure-stage {
    break-inside: avoid;
    overflow: visible;
  }
  .figure-stage svg {
    min-width: 0;
  }
}
