@import url('../shared/theme.css');

.narrator-panel { background: var(--bg-card); border-radius: var(--radius); padding: 12px 16px; box-shadow: var(--shadow); margin-bottom: var(--spacing); }
.narrator-prev { color: var(--text-muted); font-size: 13px; min-height: 18px; }
.narrator-curr { color: var(--text-primary); font-size: 15px; font-weight: 600; min-height: 22px; margin-top: 4px; }

.bars-render { display: flex; align-items: flex-end; gap: 2px; height: 260px; padding: 8px; background: var(--bg-card); border-radius: var(--radius); box-shadow: var(--shadow); }
.bars-render .bar { flex: 1; background: var(--accent); border-radius: 2px 2px 0 0; transition: height 0.15s, background 0.15s; min-width: 3px; }
.bars-render .bar.comparing { background: var(--color-comparing); }
.bars-render .bar.swapping { background: var(--color-swapping); }
.bars-render .bar.sorted { background: var(--color-sorted); }
.bars-render .bar.pivot { background: var(--color-visited); }
.bars-render .bar.empty { background: var(--border-color); opacity: 0.4; min-height: 4px; }
.bars-render .bar.cursor { outline: 2px solid var(--accent); outline-offset: 1px; }
.bars-render .bar.found { background: var(--color-sorted); }
.bars-render .bar.checking { background: var(--color-comparing); }
.bars-render .bar.out { opacity: 0.3; }

/* === Graph Render（Dijkstra / Bellman-Ford）=== */
.graph-render { background: var(--bg-card); border-radius: var(--radius); box-shadow: var(--shadow); padding: 8px; }
.graph-render svg { display: block; width: 100%; height: auto; }

.graph-edge { stroke: var(--border-color); stroke-width: 2; transition: stroke 0.15s, stroke-width 0.15s; }
.graph-edge.relaxing { stroke: var(--color-comparing); stroke-width: 4; }
.graph-edge-weight { fill: var(--text-secondary); font-size: 12px; font-family: var(--font-mono); }
.graph-arrow-head { fill: var(--text-muted); }

.graph-node { fill: var(--bg-highlight); stroke: var(--accent); stroke-width: 2; transition: fill 0.15s, stroke 0.15s; }
.graph-node.current { fill: var(--color-comparing); stroke: var(--color-comparing); }
.graph-node.finalized { fill: var(--color-sorted); stroke: var(--color-sorted); }
.graph-node.updated { animation: graph-node-flash 0.6s ease; }

.graph-node-label {
  fill: var(--text-primary);
  font-size: 13px;
  font-weight: 700;
  font-family: var(--font-sans);
  pointer-events: none;
  paint-order: stroke;
  stroke: var(--bg-card);
  stroke-width: 3px;
  stroke-linejoin: round;
}
.graph-dist-label { fill: var(--text-secondary); font-size: 12px; font-family: var(--font-mono); pointer-events: none; }

@keyframes graph-node-flash {
  0%, 100% { stroke-width: 2; filter: drop-shadow(0 0 0 var(--bg-highlight)); }
  50% { stroke-width: 3; filter: drop-shadow(0 0 4px var(--color-highlight)); }
}

/* === Grid Render（Floyd-Warshall 距離矩陣 / A* 格點尋路）=== */
.grid-render { display: grid; gap: 2px; padding: 8px; background: var(--bg-card); border-radius: var(--radius); box-shadow: var(--shadow); }
.grid-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
  min-width: 28px;
  background: var(--bg-highlight);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: 13px;
  transition: background 0.15s, box-shadow 0.15s;
}

/* Floyd-Warshall 用 */
.grid-cell.updating { background: var(--color-comparing); }

/* A* 用 */
.grid-cell.wall { background: var(--text-muted); }
.grid-cell.untouched { background: var(--bg-highlight); }
.grid-cell.closed { background: var(--color-visited); color: var(--text-code); }
.grid-cell.frontier { background: var(--color-comparing); }
.grid-cell.path { background: var(--color-sorted); color: var(--text-code); }
.grid-cell.current { background: var(--color-active); color: var(--text-code); }
.grid-cell.start { background: var(--color-swapping); color: var(--text-code); }
.grid-cell.goal { background: var(--color-highlight); color: var(--text-primary); }

/* 高亮疊加：outline/box-shadow，不覆蓋 cls 主色 */
.grid-cell.active { outline: 2px solid var(--accent); outline-offset: -2px; }
.grid-cell.pivot { box-shadow: 0 0 0 3px var(--color-highlight) inset; }

/* === Text Render（Brute Force / KMP / Rabin-Karp / Z-Function 字串匹配）=== */
.text-render { display: flex; flex-direction: column; gap: 6px; padding: 12px; background: var(--bg-card); border-radius: var(--radius); box-shadow: var(--shadow); overflow-x: auto; }
.text-row { display: grid; gap: 2px; }

.text-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
  min-width: 26px;
  background: var(--bg-highlight);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: 14px;
  transition: background 0.15s, outline 0.15s, box-shadow 0.15s;
}

/* pattern 列超出 text 可視範圍（含 offset 為負時左側溢出）的佔位格：不畫框、不畫字 */
.text-cell.pattern-cell.empty { background: transparent; border-color: transparent; }

/* 高亮疊加：background 為主色（matched/mismatch 互斥），outline/box-shadow 疊加不覆蓋主色 */
.text-cell.matched { background: var(--color-sorted); color: var(--text-code); }
.text-cell.mismatch { background: var(--color-swapping); color: var(--text-code); }
.text-cell.found { box-shadow: 0 0 0 3px var(--color-highlight) inset; font-weight: 700; }
.text-cell.comparing { outline: 3px solid var(--color-comparing); outline-offset: -2px; }

/* === Tree Render（二元樹遍歷：preorder / inorder / postorder / levelorder）=== */
.tree-render { display: flex; justify-content: center; background: var(--bg-card); border-radius: var(--radius); box-shadow: var(--shadow); padding: 8px; }

.tree-edge { stroke: var(--border-color); stroke-width: 2; }

.tree-node { fill: var(--bg-highlight); stroke: var(--accent); stroke-width: 2; transition: fill 0.15s, stroke 0.15s, stroke-width 0.15s; }
/* 主色（fill）：visited 綠、current 橘，同一節點同時符合兩者時 current 需在下方宣告在後，讓 current 勝出 */
.tree-node.visited { fill: var(--color-sorted); }
.tree-node.current { fill: var(--color-comparing); }
/* frontier 疊加：黃色外框（stroke），與 visited/current 的 fill 互不衝突，可同時疊加不覆蓋主色 */
.tree-node.frontier { stroke: var(--color-highlight); stroke-width: 4; }

.tree-node-label {
  fill: var(--text-primary);
  font-size: 13px;
  font-weight: 700;
  font-family: var(--font-sans);
  pointer-events: none;
  paint-order: stroke;
  stroke: var(--bg-card);
  stroke-width: 3px;
  stroke-linejoin: round;
}
.tree-order-label { fill: var(--text-secondary); font-size: 11px; font-family: var(--font-mono); pointer-events: none; }

/* === Geometry Render（Monotone Chain / Gift Wrapping 凸包）=== */
.geometry-render { display: flex; justify-content: center; background: var(--bg-card); border-radius: var(--radius); box-shadow: var(--shadow); padding: 8px; }
.geometry-render svg { display: block; width: 100%; height: auto; max-width: 360px; }

/* hull 邊：綠色實線 */
.geometry-hull-edge { stroke: var(--color-sorted); stroke-width: 2; }

/* candidate 邊：橘色虛線（疊加在 hull 邊之上） */
.geometry-candidate-edge { stroke: var(--color-comparing); stroke-width: 2.5; stroke-dasharray: 5 3; }

/* 點：基礎樣式 -> hull-vertex(綠) -> candidate(橘) -> current(橘) -> removed(紅)，後宣告者優先顯示 */
.geometry-point { fill: var(--bg-highlight); stroke: var(--accent); stroke-width: 1.5; transition: fill 0.15s, stroke 0.15s; }
.geometry-point.hull-vertex { fill: var(--color-sorted); stroke: var(--color-sorted); }
.geometry-point.candidate { fill: var(--color-comparing); stroke: var(--color-comparing); }
.geometry-point.current { fill: var(--color-comparing); stroke: var(--color-comparing); r: 6; }
.geometry-point.removed { fill: var(--color-swapping); stroke: var(--color-swapping); opacity: 0.6; }

.geometry-point-label { fill: var(--text-secondary); font-size: 10px; font-family: var(--font-mono); pointer-events: none; }
