import { useState, useRef, useEffect, useCallback } from "react";

const styles = `
  @import url('https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=DM+Sans:wght@300;400;500&family=DM+Mono:wght@400;500&display=swap');

  * { margin: 0; padding: 0; box-sizing: border-box; }

  :root {
    --bg: #0d1117;
    --surface: #161b22;
    --surface2: #1c2330;
    --border: #21262d;
    --teal: #2dd4bf;
    --teal-dark: #0d9488;
    --indigo: #818cf8;
    --muted: #5a7a96;
    --text: #cdd9e5;
    --text-dim: #8b949e;
    --red: #f85149;
    --amber: #d29922;
    --green: #3fb950;
  }

  body { background: var(--bg); font-family: 'DM Sans', sans-serif; }

  .shell { display: flex; height: 100vh; overflow: hidden; background: var(--bg); }

  .sidebar {
    width: 220px; min-width: 220px;
    background: var(--surface);
    border-right: 1px solid var(--border);
    display: flex; flex-direction: column;
  }

  .logo-area { padding: 20px 18px 16px; border-bottom: 1px solid var(--border); }
  .logo-word { font-family: 'Syne', sans-serif; font-weight: 800; font-size: 18px; color: var(--teal); letter-spacing: -0.5px; }
  .logo-sub { font-family: 'DM Mono', monospace; font-size: 10px; color: var(--muted); letter-spacing: 2px; text-transform: uppercase; margin-top: 2px; }

  .nav { padding: 12px 10px; flex: 1; }
  .nav-section { font-family: 'DM Mono', monospace; font-size: 9px; letter-spacing: 2px; text-transform: uppercase; color: var(--muted); padding: 12px 10px 6px; }
  .nav-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 6px; font-size: 13px; color: var(--text-dim); cursor: pointer; transition: all 0.15s; margin-bottom: 2px; border: none; background: none; width: 100%; text-align: left; }
  .nav-item:hover { background: var(--surface2); color: var(--text); }
  .nav-item.active { background: rgba(45,212,191,0.08); color: var(--teal); }
  .nav-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--muted); flex-shrink: 0; }
  .nav-item.active .nav-dot { background: var(--teal); box-shadow: 0 0 6px var(--teal); }

  .main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }

  .topbar { height: 52px; border-bottom: 1px solid var(--border); display: flex; align-items: center; padding: 0 20px; gap: 12px; background: var(--surface); }
  .topbar-title { font-family: 'Syne', sans-serif; font-weight: 700; font-size: 14px; color: var(--text); flex: 1; }

  .badge { font-family: 'DM Mono', monospace; font-size: 10px; padding: 3px 8px; border-radius: 4px; letter-spacing: 0.5px; }
  .badge-teal { background: rgba(45,212,191,0.1); color: var(--teal); border: 1px solid rgba(45,212,191,0.2); }
  .badge-red { background: rgba(248,81,73,0.1); color: var(--red); border: 1px solid rgba(248,81,73,0.2); }
  .badge-amber { background: rgba(210,153,34,0.1); color: var(--amber); border: 1px solid rgba(210,153,34,0.2); }
  .badge-muted { background: rgba(90,122,150,0.1); color: var(--muted); border: 1px solid rgba(90,122,150,0.2); }
  .badge-indigo { background: rgba(129,140,248,0.1); color: var(--indigo); border: 1px solid rgba(129,140,248,0.2); }

  .session-bar {
    padding: 10px 20px;
    border-bottom: 1px solid var(--border);
    display: flex; gap: 8px; align-items: center;
    background: var(--bg);
  }

  .session-chip {
    font-family: 'DM Mono', monospace;
    font-size: 11px;
    padding: 4px 12px;
    border-radius: 4px;
    border: 1px solid var(--border);
    background: none; color: var(--text-dim);
    cursor: pointer; transition: all 0.15s;
  }
  .session-chip:hover, .session-chip.active { border-color: var(--teal); color: var(--teal); background: rgba(45,212,191,0.06); }

  .graph-area {
    flex: 1; position: relative; overflow: hidden;
    background:
      radial-gradient(ellipse at 20% 30%, rgba(45,212,191,0.03) 0%, transparent 60%),
      radial-gradient(ellipse at 80% 70%, rgba(129,140,248,0.03) 0%, transparent 60%),
      var(--bg);
  }

  .graph-canvas {
    position: absolute; inset: 0;
    background-image:
      linear-gradient(rgba(33,38,45,0.4) 1px, transparent 1px),
      linear-gradient(90deg, rgba(33,38,45,0.4) 1px, transparent 1px);
    background-size: 40px 40px;
  }

  /* NODES */
  .node {
    position: absolute;
    border-radius: 10px;
    cursor: pointer;
    transition: all 0.2s;
    user-select: none;
  }

  .node:hover { transform: translateY(-2px); filter: brightness(1.15); }
  .node.selected { filter: brightness(1.2); }

  .node-agent {
    border: 1.5px solid rgba(45,212,191,0.4);
    background: linear-gradient(135deg, rgba(22,27,34,0.95), rgba(28,35,48,0.95));
    box-shadow: 0 0 20px rgba(45,212,191,0.1), 0 4px 16px rgba(0,0,0,0.4);
    min-width: 140px;
  }

  .node-agent.selected {
    border-color: var(--teal);
    box-shadow: 0 0 30px rgba(45,212,191,0.25), 0 4px 16px rgba(0,0,0,0.4);
  }

  .node-tool {
    border: 1.5px solid rgba(129,140,248,0.35);
    background: linear-gradient(135deg, rgba(22,27,34,0.95), rgba(25,28,45,0.95));
    box-shadow: 0 0 16px rgba(129,140,248,0.08), 0 4px 12px rgba(0,0,0,0.4);
    min-width: 120px;
  }
  .node-tool.selected { border-color: var(--indigo); box-shadow: 0 0 24px rgba(129,140,248,0.2), 0 4px 12px rgba(0,0,0,0.4); }

  .node-llm {
    border: 1.5px solid rgba(210,153,34,0.35);
    background: linear-gradient(135deg, rgba(22,27,34,0.95), rgba(32,28,20,0.95));
    box-shadow: 0 0 16px rgba(210,153,34,0.08), 0 4px 12px rgba(0,0,0,0.4);
    min-width: 120px;
  }

  .node-block {
    border: 1.5px solid rgba(248,81,73,0.5);
    background: linear-gradient(135deg, rgba(22,27,34,0.95), rgba(40,22,22,0.95));
    box-shadow: 0 0 20px rgba(248,81,73,0.15), 0 4px 12px rgba(0,0,0,0.4);
    min-width: 120px;
  }

  .node-header {
    padding: 10px 12px 8px;
    border-bottom: 1px solid rgba(33,38,45,0.8);
    display: flex; align-items: center; gap: 8px;
  }

  .node-icon {
    width: 24px; height: 24px; border-radius: 6px;
    display: flex; align-items: center; justify-content: center;
    font-size: 12px; flex-shrink: 0;
  }

  .icon-agent { background: rgba(45,212,191,0.15); }
  .icon-tool { background: rgba(129,140,248,0.15); }
  .icon-llm { background: rgba(210,153,34,0.15); }
  .icon-block { background: rgba(248,81,73,0.15); }

  .node-name {
    font-family: 'DM Sans', sans-serif;
    font-weight: 500; font-size: 12px;
    color: var(--text);
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .node-body { padding: 8px 12px 10px; }

  .node-meta {
    font-family: 'DM Mono', monospace;
    font-size: 10px;
    color: var(--muted);
    line-height: 1.6;
  }

  .node-metric {
    display: flex; justify-content: space-between;
    font-family: 'DM Mono', monospace; font-size: 10px;
    margin-top: 2px;
  }

  .node-metric-val { color: var(--teal); }
  .node-metric-val.indigo { color: var(--indigo); }
  .node-metric-val.amber { color: var(--amber); }
  .node-metric-val.red { color: var(--red); }

  /* SVG EDGES */
  .edges-svg {
    position: absolute; inset: 0;
    pointer-events: none;
    overflow: visible;
  }

  .edge-path { fill: none; stroke-width: 1.5; }
  .edge-normal { stroke: rgba(90,122,150,0.4); }
  .edge-teal { stroke: rgba(45,212,191,0.5); stroke-dasharray: none; }
  .edge-block { stroke: rgba(248,81,73,0.5); stroke-dasharray: 4 3; }
  .edge-handoff { stroke: rgba(129,140,248,0.5); stroke-dasharray: 6 3; }

  .edge-label {
    font-family: 'DM Mono', monospace;
    font-size: 9px;
    fill: var(--muted);
    text-anchor: middle;
  }

  /* DETAIL PANEL */
  .detail-panel {
    position: absolute;
    right: 16px; top: 16px;
    width: 300px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 8px 32px rgba(0,0,0,0.5);
    animation: slideIn 0.2s ease;
  }

  @keyframes slideIn {
    from { opacity: 0; transform: translateX(12px); }
    to { opacity: 1; transform: translateX(0); }
  }

  .detail-header { padding: 14px 16px; border-bottom: 1px solid var(--border); display: flex; align-items: flex-start; justify-content: space-between; }
  .detail-title { font-family: 'Syne', sans-serif; font-weight: 700; font-size: 13px; color: var(--text); }
  .detail-kind { font-family: 'DM Mono', monospace; font-size: 10px; margin-top: 3px; }
  .close-btn { background: none; border: 1px solid var(--border); color: var(--muted); width: 22px; height: 22px; border-radius: 4px; cursor: pointer; font-size: 13px; display: flex; align-items: center; justify-content: center; transition: all 0.15s; }
  .close-btn:hover { border-color: var(--teal); color: var(--teal); }

  .detail-body { padding: 14px 16px; }
  .kv-row { display: flex; justify-content: space-between; padding: 4px 0; font-size: 11px; gap: 12px; }
  .kv-key { color: var(--muted); font-family: 'DM Mono', monospace; font-size: 10px; flex-shrink: 0; }
  .kv-val { color: var(--text); text-align: right; font-family: 'DM Mono', monospace; font-size: 10px; word-break: break-all; }

  .detail-section-label { font-family: 'DM Mono', monospace; font-size: 9px; letter-spacing: 2px; text-transform: uppercase; color: var(--muted); margin-bottom: 8px; margin-top: 14px; padding-bottom: 5px; border-bottom: 1px solid var(--border); }

  .code-block { background: var(--bg); border: 1px solid var(--border); border-radius: 5px; padding: 8px 10px; font-family: 'DM Mono', monospace; font-size: 10px; color: var(--text-dim); line-height: 1.5; white-space: pre-wrap; word-break: break-all; max-height: 80px; overflow-y: auto; }

  /* LEGEND */
  .legend {
    position: absolute; bottom: 16px; left: 16px;
    background: rgba(22,27,34,0.92);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 12px 14px;
    backdrop-filter: blur(8px);
  }

  .legend-title { font-family: 'DM Mono', monospace; font-size: 9px; letter-spacing: 2px; text-transform: uppercase; color: var(--muted); margin-bottom: 8px; }

  .legend-item { display: flex; align-items: center; gap: 8px; font-family: 'DM Mono', monospace; font-size: 10px; color: var(--text-dim); margin-bottom: 5px; }
  .legend-dot { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }

  /* CONTROLS */
  .controls {
    position: absolute; bottom: 16px; right: 16px;
    display: flex; gap: 6px;
  }

  .ctrl-btn {
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text-dim);
    width: 32px; height: 32px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 16px;
    display: flex; align-items: center; justify-content: center;
    transition: all 0.15s;
    font-family: 'DM Mono', monospace;
  }
  .ctrl-btn:hover { border-color: var(--teal); color: var(--teal); }

  .live-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--green); margin-right: 6px; animation: pulse 1.5s infinite; }
  @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }

  /* CLUSTER */
  .cluster-label {
    position: absolute;
    font-family: 'DM Mono', monospace;
    font-size: 9px;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--muted);
    pointer-events: none;
  }
`;

// Graph data for session: sess_marathon_01 (multi-agent)
const NODES = [
  // Planner cluster
  { id: "planner", kind: "agent", name: "PlannerAgent", x: 80, y: 120, meta: "LangGraph", metrics: { latency: "4.82s", spans: "14 spans" }, input: "Plan market analysis pipeline for EV sector", output: "4 subtasks decomposed" },
  { id: "llm_plan", kind: "llm", name: "llm.reason", x: 80, y: 270, meta: "claude-3-5-sonnet", metrics: { latency: "980ms", tokens: "1.2k" }, input: "Decompose task into subtasks", output: "Research, sentiment, financials, synthesis" },
  { id: "web_search", kind: "tool", name: "web_search", x: 280, y: 200, meta: "SerpAPI", metrics: { latency: "1.24s", calls: "3 calls" }, input: "EV market 2024 overview", output: "14 results retrieved" },

  // Handoff → Executor
  { id: "handoff_1", kind: "tool", name: "handoff", x: 380, y: 120, meta: "→ ExecutorAgent", metrics: { latency: "820ms", type: "async" }, input: "Subtask bundle", output: "Transferred to executor" },

  // Executor cluster
  { id: "executor", kind: "agent", name: "ExecutorAgent", x: 520, y: 120, meta: "LangGraph", metrics: { latency: "1.23s", spans: "3 spans" }, input: "Execute: delete users last_login < 90d", output: "BLOCKED by policy" },
  { id: "db_query", kind: "tool", name: "db.query_plan", x: 520, y: 280, meta: "PostgreSQL", metrics: { latency: "340ms", rows: "est 42k" }, input: "EXPLAIN DELETE FROM users...", output: "Query plan returned" },
  { id: "guard_block", kind: "block", name: "guard.evaluate", x: 700, y: 200, meta: "plyra-guard", metrics: { latency: "80ms", policy: "destructive_db_ops" }, input: "Tool call: db.delete, scope: 42k rows", output: "BLOCKED — escalated to human" },

  // Synthesizer
  { id: "synthesizer", kind: "agent", name: "SynthAgent", x: 520, y: 420, meta: "LangGraph", metrics: { latency: "640ms", spans: "2 spans" }, input: "Summarize all research outputs", output: "3-page report generated" },
  { id: "llm_synth", kind: "llm", name: "llm.synthesize", x: 700, y: 420, meta: "gpt-4o", metrics: { latency: "580ms", tokens: "2.1k" }, input: "All retrieved data", output: "Synthesis complete" },
  { id: "file_write", kind: "tool", name: "file.write", x: 880, y: 420, meta: "local fs", metrics: { latency: "120ms", size: "18kb" }, input: "report.md", output: "Written to disk" },
];

const EDGES = [
  { from: "planner", to: "llm_plan", type: "teal", label: "" },
  { from: "planner", to: "web_search", type: "teal", label: "search" },
  { from: "planner", to: "handoff_1", type: "handoff", label: "handoff" },
  { from: "llm_plan", to: "web_search", type: "normal", label: "" },
  { from: "handoff_1", to: "executor", type: "handoff", label: "" },
  { from: "executor", to: "db_query", type: "teal", label: "" },
  { from: "db_query", to: "guard_block", type: "block", label: "policy check" },
  { from: "handoff_1", to: "synthesizer", type: "handoff", label: "handoff" },
  { from: "synthesizer", to: "llm_synth", type: "teal", label: "" },
  { from: "llm_synth", to: "file_write", type: "teal", label: "" },
];

const KIND_COLOR = {
  agent: "#2dd4bf",
  tool: "#818cf8",
  llm: "#d29922",
  block: "#f85149",
};

const KIND_ICON = {
  agent: "◈",
  tool: "⬡",
  llm: "◎",
  block: "⊗",
};

const SCALE = 1.1;
const OFFSET_X = 20;
const OFFSET_Y = 30;

function getNodeCenter(node) {
  const w = 148, h = 76;
  return {
    x: node.x * SCALE + OFFSET_X + w / 2,
    y: node.y * SCALE + OFFSET_Y + h / 2,
  };
}

function CubicEdge({ from, to, type, label }) {
  const f = getNodeCenter(from);
  const t = getNodeCenter(to);
  const dx = t.x - f.x;
  const cx1 = f.x + dx * 0.5;
  const cx2 = t.x - dx * 0.5;
  const d = `M ${f.x} ${f.y} C ${cx1} ${f.y} ${cx2} ${t.y} ${t.x} ${t.y}`;
  const mx = (f.x + t.x) / 2;
  const my = (f.y + t.y) / 2;

  const strokeClass = type === "block" ? "edge-block" : type === "handoff" ? "edge-handoff" : type === "teal" ? "edge-teal" : "edge-normal";

  return (
    <g>
      <defs>
        <marker id={`arrow-${type}`} markerWidth="6" markerHeight="6" refX="5" refY="3" orient="auto">
          <path d="M0,0 L0,6 L6,3 z" fill={type === "block" ? "#f85149" : type === "handoff" ? "#818cf8" : type === "teal" ? "#2dd4bf" : "#5a7a96"} opacity="0.7" />
        </marker>
      </defs>
      <path className={`edge-path ${strokeClass}`} d={d} markerEnd={`url(#arrow-${type})`} />
      {label && (
        <text className="edge-label" x={mx} y={my - 6}>{label}</text>
      )}
    </g>
  );
}

export default function PlyrTraceGraph() {
  const [selected, setSelected] = useState(null);
  const [session, setSession] = useState("sess_marathon_01");

  const nodeMap = Object.fromEntries(NODES.map(n => [n.id, n]));

  return (
    <>
      <style>{styles}</style>
      <div className="shell">
        {/* SIDEBAR */}
        <div className="sidebar">
          <div className="logo-area">
            <div className="logo-word">plyra</div>
            <div className="logo-sub">trace</div>
          </div>
          <div className="nav">
            <div className="nav-section">observe</div>
            {["Traces", "Sessions", "Agents", "Tools"].map((item) => (
              <button key={item} className="nav-item">
                <span className="nav-dot" />
                {item}
              </button>
            ))}
            <div className="nav-section">analyze</div>
            {[["Graph View", true], ["Spans", false], ["Policies", false]].map(([item, active]) => (
              <button key={item} className={`nav-item ${active ? "active" : ""}`}>
                <span className="nav-dot" />
                {item}
              </button>
            ))}
            <div className="nav-section">system</div>
            {["Settings", "Exporters"].map((item) => (
              <button key={item} className="nav-item">
                <span className="nav-dot" />
                {item}
              </button>
            ))}
          </div>
        </div>

        {/* MAIN */}
        <div className="main">
          <div className="topbar">
            <div className="topbar-title">
              <span className="live-dot" />
              Graph View
            </div>
            <span className="badge badge-teal">3 agents</span>
            <span className="badge badge-red">1 blocked</span>
            <span className="badge badge-muted">sess_marathon_01</span>
          </div>

          {/* SESSION SELECTOR */}
          <div className="session-bar">
            <span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: "var(--muted)", letterSpacing: 1, textTransform: "uppercase", marginRight: 4 }}>session</span>
            {["sess_marathon_01", "sess_coding_44", "sess_research_12"].map(s => (
              <button key={s} className={`session-chip ${session === s ? "active" : ""}`} onClick={() => setSession(s)}>{s}</button>
            ))}
          </div>

          {/* GRAPH */}
          <div className="graph-area">
            <div className="graph-canvas" />

            {/* CLUSTER LABELS */}
            <div className="cluster-label" style={{ left: 80 * SCALE + OFFSET_X, top: OFFSET_Y - 16 }}>PLANNER CLUSTER</div>
            <div className="cluster-label" style={{ left: 500 * SCALE + OFFSET_X, top: OFFSET_Y - 16 }}>EXECUTOR CLUSTER</div>
            <div className="cluster-label" style={{ left: 500 * SCALE + OFFSET_X, top: 390 * SCALE + OFFSET_Y - 16 }}>SYNTH CLUSTER</div>

            {/* CLUSTER BG RECTS */}
            <svg style={{ position: "absolute", inset: 0, pointerEvents: "none", overflow: "visible" }}>
              <rect x={70 * SCALE + OFFSET_X - 10} y={OFFSET_Y - 10} width={330} height={240} rx={12} fill="rgba(45,212,191,0.02)" stroke="rgba(45,212,191,0.06)" strokeWidth={1} strokeDasharray="6 4" />
              <rect x={490 * SCALE + OFFSET_X - 10} y={OFFSET_Y - 10} width={310} height={260} rx={12} fill="rgba(129,140,248,0.02)" stroke="rgba(129,140,248,0.06)" strokeWidth={1} strokeDasharray="6 4" />
              <rect x={490 * SCALE + OFFSET_X - 10} y={400 * SCALE + OFFSET_Y - 10} width={460} height={120} rx={12} fill="rgba(45,212,191,0.02)" stroke="rgba(45,212,191,0.06)" strokeWidth={1} strokeDasharray="6 4" />
            </svg>

            {/* EDGES */}
            <svg className="edges-svg">
              {EDGES.map((e, i) => {
                const fromNode = nodeMap[e.from];
                const toNode = nodeMap[e.to];
                if (!fromNode || !toNode) return null;
                return <CubicEdge key={i} from={fromNode} to={toNode} type={e.type} label={e.label} />;
              })}
            </svg>

            {/* NODES */}
            {NODES.map(node => {
              const color = KIND_COLOR[node.kind];
              const isSelected = selected?.id === node.id;
              return (
                <div
                  key={node.id}
                  className={`node node-${node.kind} ${isSelected ? "selected" : ""}`}
                  style={{
                    left: node.x * SCALE + OFFSET_X,
                    top: node.y * SCALE + OFFSET_Y,
                    width: 148,
                  }}
                  onClick={() => setSelected(isSelected ? null : node)}
                >
                  <div className="node-header">
                    <div className={`node-icon icon-${node.kind}`} style={{ color }}>
                      {KIND_ICON[node.kind]}
                    </div>
                    <span className="node-name">{node.name}</span>
                  </div>
                  <div className="node-body">
                    <div className="node-meta">{node.meta}</div>
                    <div style={{ marginTop: 4 }}>
                      {Object.entries(node.metrics).map(([k, v]) => (
                        <div key={k} className="node-metric">
                          <span style={{ color: "var(--muted)", fontFamily: "'DM Mono',monospace", fontSize: 9 }}>{k}</span>
                          <span className={`node-metric-val ${node.kind === "tool" ? "indigo" : node.kind === "llm" ? "amber" : node.kind === "block" ? "red" : ""}`}>{v}</span>
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
              );
            })}

            {/* DETAIL PANEL */}
            {selected && (
              <div className="detail-panel">
                <div className="detail-header">
                  <div>
                    <div className="detail-title">{selected.name}</div>
                    <div className="detail-kind" style={{ color: KIND_COLOR[selected.kind] }}>{selected.kind} span · {selected.meta}</div>
                  </div>
                  <button className="close-btn" onClick={() => setSelected(null)}>×</button>
                </div>
                <div className="detail-body">
                  <div className="detail-section-label">metrics</div>
                  {Object.entries(selected.metrics).map(([k, v]) => (
                    <div key={k} className="kv-row">
                      <span className="kv-key">{k}</span>
                      <span className="kv-val" style={{ color: KIND_COLOR[selected.kind] }}>{v}</span>
                    </div>
                  ))}
                  <div className="detail-section-label">input</div>
                  <div className="code-block">{selected.input}</div>
                  <div className="detail-section-label">output</div>
                  <div className="code-block" style={{ color: selected.kind === "block" ? "var(--red)" : "var(--green)" }}>{selected.output}</div>
                </div>
              </div>
            )}

            {/* LEGEND */}
            <div className="legend">
              <div className="legend-title">span kinds</div>
              {[["agent", "#2dd4bf", "Agent"], ["tool", "#818cf8", "Tool"], ["llm", "#d29922", "LLM Call"], ["block", "#f85149", "Blocked"]].map(([k, c, label]) => (
                <div key={k} className="legend-item">
                  <div className="legend-dot" style={{ background: c, opacity: 0.7 }} />
                  {label}
                </div>
              ))}
              <div style={{ borderTop: "1px solid var(--border)", marginTop: 8, paddingTop: 8 }}>
                <div className="legend-item"><svg width="24" height="8"><line x1="0" y1="4" x2="24" y2="4" stroke="rgba(45,212,191,0.5)" strokeWidth="1.5" /></svg>flow</div>
                <div className="legend-item"><svg width="24" height="8"><line x1="0" y1="4" x2="24" y2="4" stroke="rgba(129,140,248,0.5)" strokeWidth="1.5" strokeDasharray="5 3" /></svg>handoff</div>
                <div className="legend-item"><svg width="24" height="8"><line x1="0" y1="4" x2="24" y2="4" stroke="rgba(248,81,73,0.5)" strokeWidth="1.5" strokeDasharray="4 3" /></svg>blocked</div>
              </div>
            </div>

            {/* CONTROLS */}
            <div className="controls">
              <button className="ctrl-btn">−</button>
              <button className="ctrl-btn">+</button>
              <button className="ctrl-btn" style={{ fontSize: 11, width: 48 }}>fit</button>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}
