---
import Base from '../../layouts/Base.astro';
import DriftGate from '../../components/DriftGate.astro';
---

<Base title="Compare Agents — Kredo Drift" description="Compare AI agent identities side by side. See per-dimension differences or track a single agent's drift over time.">
  <meta slot="head" name="robots" content="noindex, nofollow" />
  <DriftGate />
  <div id="drift-content" style="display:none">

  <link rel="stylesheet" href="/css/aura-animations.css" />

  <div class="compare-page">

    <!-- Back link -->
    <a href="/drift/dashboard" class="back-link">&larr; Back to Dashboard</a>

    <!-- Header -->
    <div class="compare-header">
      <h1>Compare</h1>
      <p class="compare-sub">Side-by-side identity comparison across 14 behavioral dimensions. See exactly where two agents differ — drift scores, trust ratings, and per-dimension breakdowns.</p>
    </div>

    <!-- Mode tabs -->
    <div class="mode-tabs">
      <button class="mode-tab active" data-mode="versus" id="tab-versus">Agent vs Agent</button>
      <button class="mode-tab" data-mode="timeline" id="tab-timeline">Timeline</button>
    </div>

    <!-- ============================================================
         MODE: Agent vs Agent
         ============================================================ -->
    <div class="mode-panel" id="panel-versus">

      <!-- Agent selectors -->
      <div class="selector-row">
        <div class="selector-group">
          <label for="agent-a">Agent A</label>
          <select id="agent-a" class="agent-select">
            <option value="">Select an agent...</option>
          </select>
        </div>
        <div class="vs-divider">vs</div>
        <div class="selector-group">
          <label for="agent-b">Agent B</label>
          <select id="agent-b" class="agent-select">
            <option value="">Select an agent...</option>
          </select>
        </div>
      </div>

      <!-- Comparison display -->
      <div class="comparison-container" id="comparison-container" style="display: none;">
        <div class="comparison-grid">
          <!-- Aura A -->
          <div class="comparison-col">
            <div class="col-header">
              <h3 id="label-a">Agent A</h3>
              <div class="col-meta">
                <span class="drift-score" id="score-a">--</span>
                <span class="drift-class" id="class-a"></span>
              </div>
              <div class="col-trust" id="trust-row-a" style="display: none;">
                <span class="trust-label">Trust</span>
                <span class="trust-score" id="trust-score-a">--</span>
                <span class="trust-badge" id="trust-badge-a"></span>
              </div>
            </div>
            <div class="aura-frame">
              <div class="aura-container" id="aura-a"></div>
            </div>
          </div>

          <!-- Diff column -->
          <div class="diff-col" id="diff-col">
            <h4>Dimensions</h4>
            <div class="diff-bars" id="diff-bars"></div>
          </div>

          <!-- Aura B -->
          <div class="comparison-col">
            <div class="col-header">
              <h3 id="label-b">Agent B</h3>
              <div class="col-meta">
                <span class="drift-score" id="score-b">--</span>
                <span class="drift-class" id="class-b"></span>
              </div>
              <div class="col-trust" id="trust-row-b" style="display: none;">
                <span class="trust-label">Trust</span>
                <span class="trust-score" id="trust-score-b">--</span>
                <span class="trust-badge" id="trust-badge-b"></span>
              </div>
            </div>
            <div class="aura-frame">
              <div class="aura-container" id="aura-b"></div>
            </div>
          </div>
        </div>
      </div>

      <!-- Empty state -->
      <div class="empty-state" id="empty-versus">
        <p>Select two agents above to compare their identities.</p>
      </div>
    </div>

    <!-- ============================================================
         MODE: Timeline
         ============================================================ -->
    <div class="mode-panel" id="panel-timeline" style="display: none;">

      <!-- Agent selector -->
      <div class="selector-row timeline-selector">
        <div class="selector-group">
          <label for="agent-timeline">Agent</label>
          <select id="agent-timeline" class="agent-select">
            <option value="">Select an agent...</option>
          </select>
        </div>
      </div>

      <!-- Timeline controls -->
      <div class="timeline-controls" id="timeline-controls" style="display: none;">
        <div class="range-wrapper">
          <label for="timeline-slider">History Position</label>
          <input type="range" id="timeline-slider" min="0" max="0" value="0" step="1" />
          <div class="range-labels">
            <span id="range-start">--</span>
            <span class="range-current" id="range-current">--</span>
            <span id="range-end">--</span>
          </div>
        </div>
      </div>

      <!-- Timeline aura display -->
      <div class="timeline-display" id="timeline-display" style="display: none;">
        <div class="timeline-aura-frame">
          <div class="aura-container" id="aura-timeline"></div>
        </div>
        <div class="timeline-meta">
          <div class="timeline-meta-item">
            <span class="meta-label">Date</span>
            <span class="meta-value" id="tl-date">--</span>
          </div>
          <div class="timeline-meta-item">
            <span class="meta-label">Drift Score</span>
            <span class="meta-value" id="tl-score">--</span>
          </div>
          <div class="timeline-meta-item">
            <span class="meta-label">Severity</span>
            <span class="meta-value" id="tl-severity">--</span>
          </div>
          <div class="timeline-meta-item" id="tl-trust-row" style="display: none;">
            <span class="meta-label">Trust</span>
            <span class="meta-value" id="tl-trust">--</span>
            <span class="trust-badge" id="tl-trust-badge" style="margin-left: 0.5rem;"></span>
          </div>
        </div>
        <div class="timeline-dimensions" id="timeline-dimensions"></div>
      </div>

      <!-- Empty state -->
      <div class="empty-state" id="empty-timeline">
        <p>Select an agent above to view its drift history over time.</p>
      </div>
    </div>

  </div>

  </div>
</Base>

<script is:inline src="/js/aura-engine.js"></script>

<style>
  /* ============================================================
     Compare Page
     ============================================================ */
  .compare-page {
    max-width: 1200px;
    margin: 0 auto;
  }

  .back-link {
    display: inline-block;
    font-size: 0.85rem;
    color: var(--text-muted);
    margin-bottom: 1.5rem;
    transition: color 0.2s var(--ease);
  }

  .back-link:hover {
    color: var(--accent);
  }

  .compare-header {
    margin-bottom: 2rem;
  }

  .compare-header h1 {
    font-size: clamp(1.75rem, 4vw, 2.5rem);
    margin-bottom: 0.5rem;
  }

  .compare-sub {
    color: var(--text-muted);
    max-width: 600px;
  }

  /* Mode tabs */
  .mode-tabs {
    display: flex;
    gap: 0;
    margin-bottom: 2rem;
    border-bottom: 1px solid var(--border);
  }

  .mode-tab {
    padding: 0.75rem 1.5rem;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--text-muted);
    font-family: var(--font-sans);
    font-size: 0.9rem;
    font-weight: 500;
    cursor: pointer;
    transition: color 0.2s var(--ease), border-color 0.2s var(--ease);
  }

  .mode-tab:hover {
    color: var(--text-secondary);
  }

  .mode-tab.active {
    color: var(--text-primary);
    border-bottom-color: var(--accent);
  }

  /* Selectors */
  .selector-row {
    display: flex;
    align-items: flex-end;
    gap: 1.5rem;
    margin-bottom: 2rem;
  }

  .selector-group {
    flex: 1;
  }

  .selector-group label {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 0.5rem;
  }

  .agent-select {
    width: 100%;
    padding: 0.6rem 1rem;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: 0.9rem;
    cursor: pointer;
    outline: none;
    transition: border-color 0.2s var(--ease);
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 5l3 3 3-3' stroke='%2371717a' fill='none' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.75rem center;
    padding-right: 2.5rem;
  }

  .agent-select:focus {
    border-color: var(--accent);
  }

  .agent-select option {
    background: var(--bg-secondary);
    color: var(--text-primary);
  }

  .vs-divider {
    font-family: var(--font-mono);
    font-size: 0.9rem;
    color: var(--text-muted);
    padding-bottom: 0.6rem;
    flex-shrink: 0;
  }

  /* Comparison grid */
  .comparison-grid {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: 1.5rem;
    align-items: start;
  }

  .comparison-col {
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 1.25rem;
  }

  .col-header {
    margin-bottom: 1rem;
  }

  .col-header h3 {
    font-size: 1.1rem;
    margin-bottom: 0.25rem;
  }

  .col-meta {
    display: flex;
    align-items: center;
    gap: 0.75rem;
  }

  .drift-score {
    font-family: var(--font-mono);
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--text-primary);
  }

  .drift-class {
    font-size: 0.8rem;
    color: var(--text-muted);
    font-weight: 500;
  }

  /* Trust score row */
  .col-trust {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--border);
  }

  .trust-label {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }

  .trust-score {
    font-family: var(--font-mono);
    font-size: 1.1rem;
    font-weight: 700;
  }

  .trust-badge {
    font-size: 0.7rem;
    font-weight: 600;
    padding: 0.15rem 0.5rem;
    border-radius: 10px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }

  .trust-badge.exemplary {
    background: rgba(34, 197, 94, 0.12);
    color: #22c55e;
    border: 1px solid rgba(34, 197, 94, 0.25);
  }

  .trust-badge.strong {
    background: rgba(59, 130, 246, 0.12);
    color: #3b82f6;
    border: 1px solid rgba(59, 130, 246, 0.25);
  }

  .trust-badge.developing {
    background: rgba(234, 179, 8, 0.12);
    color: #eab308;
    border: 1px solid rgba(234, 179, 8, 0.25);
  }

  .trust-badge.weak {
    background: rgba(249, 115, 22, 0.12);
    color: #f97316;
    border: 1px solid rgba(249, 115, 22, 0.25);
  }

  .trust-badge.untrusted {
    background: rgba(248, 113, 113, 0.12);
    color: #f87171;
    border: 1px solid rgba(248, 113, 113, 0.25);
  }

  .aura-frame {
    aspect-ratio: 1;
    position: relative;
  }

  .aura-container {
    width: 100%;
    height: 100%;
  }

  .aura-container svg {
    width: 100%;
    height: 100%;
  }

  /* Diff column */
  /* WHY fixed 200px: diff bars sit between two auras and need a narrow,
     consistent width to avoid squishing the aura frames on resize. */
  .diff-col {
    width: 200px;
    padding-top: 3rem;
  }

  .diff-col h4 {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    margin-bottom: 1rem;
  }

  .diff-bars {
    display: grid;
    gap: 1rem;
  }

  .diff-item {
    display: grid;
    gap: 0.35rem;
  }

  .diff-label {
    font-size: 0.75rem;
    font-family: var(--font-mono);
    color: var(--text-muted);
    display: flex;
    justify-content: space-between;
  }

  .diff-bar-track {
    height: 8px;
    background: rgba(255, 255, 255, 0.04);
    border-radius: 4px;
    position: relative;
    overflow: hidden;
  }

  .diff-bar-fill-a {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    border-radius: 4px 0 0 4px;
    transition: width 0.4s var(--ease);
  }

  .diff-bar-fill-b {
    position: absolute;
    right: 0;
    top: 0;
    height: 100%;
    border-radius: 0 4px 4px 0;
    transition: width 0.4s var(--ease);
  }

  .diff-bar-center {
    position: absolute;
    left: 50%;
    top: 0;
    width: 1px;
    height: 100%;
    background: rgba(255, 255, 255, 0.15);
  }

  /* Empty state */
  .empty-state {
    text-align: center;
    padding: 4rem 2rem;
    border: 1px dashed var(--border);
    border-radius: var(--radius-lg);
  }

  .empty-state p {
    color: var(--text-muted);
    margin-bottom: 0;
  }

  /* Timeline */
  .timeline-selector {
    max-width: 400px;
  }

  .timeline-controls {
    margin-bottom: 2rem;
  }

  .range-wrapper {
    max-width: 600px;
  }

  .range-wrapper label {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 0.75rem;
  }

  .range-wrapper input[type="range"] {
    width: 100%;
    height: 6px;
    background: rgba(255, 255, 255, 0.06);
    border-radius: 3px;
    outline: none;
    appearance: none;
    cursor: pointer;
  }

  .range-wrapper input[type="range"]::-webkit-slider-thumb {
    appearance: none;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--accent);
    border: 2px solid var(--bg-primary);
    box-shadow: 0 0 8px rgba(59, 130, 246, 0.3);
    cursor: pointer;
  }

  .range-labels {
    display: flex;
    justify-content: space-between;
    margin-top: 0.5rem;
    font-size: 0.75rem;
    font-family: var(--font-mono);
    color: var(--text-muted);
  }

  .range-current {
    color: var(--accent);
    font-weight: 600;
  }

  .timeline-display {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2rem;
    align-items: start;
  }

  .timeline-aura-frame {
    aspect-ratio: 1;
    max-width: 440px;
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 1rem;
  }

  .timeline-meta {
    display: grid;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
  }

  .timeline-meta-item {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border);
  }

  .meta-label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    min-width: 100px;
  }

  .meta-value {
    font-family: var(--font-mono);
    font-size: 0.9rem;
    color: var(--text-primary);
  }

  .timeline-dimensions {
    display: grid;
    gap: 0.5rem;
  }

  .tl-dim-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: 0.85rem;
  }

  .tl-dim-name {
    font-family: var(--font-mono);
    color: var(--text-muted);
    min-width: 90px;
    font-size: 0.75rem;
  }

  .tl-dim-bar-track {
    flex: 1;
    height: 6px;
    background: rgba(255, 255, 255, 0.04);
    border-radius: 3px;
    overflow: hidden;
  }

  .tl-dim-bar-fill {
    height: 100%;
    border-radius: 3px;
    transition: width 0.4s var(--ease);
  }

  .tl-dim-score {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    color: var(--text-secondary);
    min-width: 32px;
    text-align: right;
  }

  /* Responsive */
  @media (max-width: 900px) {
    .comparison-grid {
      grid-template-columns: 1fr;
    }

    .diff-col {
      width: 100%;
      padding-top: 0;
      order: 3;
    }

    .timeline-display {
      grid-template-columns: 1fr;
    }

    .timeline-aura-frame {
      max-width: 100%;
    }
  }

  @media (max-width: 600px) {
    .selector-row {
      flex-direction: column;
      gap: 1rem;
    }

    .vs-divider {
      text-align: center;
      padding-bottom: 0;
    }
  }
</style>

<script is:inline>
  // ============================================================
  // Compare Page Controller
  // ============================================================

  // 14 dimensions across two tiers + mixed
  // Identity Core (7): Values, Goals, Boundaries, Autonomy, Adversarial Resistance, Self-Awareness, Fidelity
  // Cognitive Profile (6): Personality, Reasoning Style, Consistency, Uncertainty Calibration, Relational Dynamics, Temporal Grounding
  // Mixed (1): Knowledge
  var DIMENSIONS = [
    'Values', 'Goals', 'Boundaries', 'Autonomy', 'Adversarial Resistance', 'Self-Awareness', 'Fidelity',
    'Personality', 'Reasoning Style', 'Consistency', 'Uncertainty Calibration', 'Relational Dynamics', 'Temporal Grounding',
    'Knowledge'
  ];

  var DIM_COLORS = {
    // Identity Core — amber tones
    Values: '#f59e0b',
    Goals: '#eab308',
    Boundaries: '#d97706',
    Autonomy: '#f59e0b',
    'Adversarial Resistance': '#ca8a04',
    'Self-Awareness': '#b45309',
    Fidelity: '#d97706',
    // Cognitive Profile — cyan/blue tones
    Personality: '#22c55e',
    'Reasoning Style': '#3b82f6',
    Consistency: '#06b6d4',
    'Uncertainty Calibration': '#38bdf8',
    'Relational Dynamics': '#0ea5e9',
    'Temporal Grounding': '#0891b2',
    // Mixed
    Knowledge: '#a855f7',
  };

  // Trust classification thresholds
  function getTrustClassification(score) {
    if (score >= 90) return { label: 'Exemplary', css: 'exemplary', color: '#22c55e' };
    if (score >= 75) return { label: 'Strong', css: 'strong', color: '#3b82f6' };
    if (score >= 55) return { label: 'Developing', css: 'developing', color: '#eab308' };
    if (score >= 35) return { label: 'Weak', css: 'weak', color: '#f97316' };
    return { label: 'Untrusted', css: 'untrusted', color: '#f87171' };
  }

  function renderTrustBadge(badgeEl, scoreEl, trustScore, rowEl) {
    if (trustScore == null) {
      if (rowEl) rowEl.style.display = 'none';
      return;
    }
    var cls = getTrustClassification(trustScore);
    if (rowEl) rowEl.style.display = '';
    if (scoreEl) {
      scoreEl.textContent = String(Math.round(trustScore));
      scoreEl.style.color = cls.color;
    }
    if (badgeEl) {
      badgeEl.textContent = cls.label;
      badgeEl.className = 'trust-badge ' + cls.css;
    }
  }

  var manifest = null;
  // WHY cache: same agent data is shared across versus and timeline modes —
  // avoids redundant fetches when switching between modes or swapping selections.
  var agentCache = {};

  // ============================================================
  // Initialization
  // ============================================================

  async function init() {
    // Read query params for pre-selection
    const params = new URLSearchParams(window.location.search);
    const preA = params.get('a');
    const preB = params.get('b');

    // Fetch manifest
    try {
      const res = await fetch('/data/agents.json');
      if (!res.ok) throw new Error('No manifest');
      manifest = await res.json();
    } catch {
      manifest = { agents: ['sentinel'], enabled: ['sentinel'], updated: '' };
    }

    // Populate all dropdowns
    const selectA = document.getElementById('agent-a');
    const selectB = document.getElementById('agent-b');
    const selectTL = document.getElementById('agent-timeline');

    const agents = manifest.enabled.length > 0 ? manifest.enabled : manifest.agents;

    agents.forEach(name => {
      const displayName = name.charAt(0).toUpperCase() + name.slice(1);
      const optA = new Option(displayName, name);
      const optB = new Option(displayName, name);
      const optTL = new Option(displayName, name);
      selectA.add(optA);
      selectB.add(optB);
      selectTL.add(optTL);
    });

    // WHY pre-select from query params: dashboard cards link here with
    // ?a=agent1&b=agent2 so users land directly on the comparison they want.
    if (preA) selectA.value = preA;
    if (preB) selectB.value = preB;

    // Event listeners
    selectA.addEventListener('change', onVersusChange);
    selectB.addEventListener('change', onVersusChange);
    selectTL.addEventListener('change', onTimelineAgentChange);

    // Mode tabs
    document.getElementById('tab-versus').addEventListener('click', () => switchMode('versus'));
    document.getElementById('tab-timeline').addEventListener('click', () => switchMode('timeline'));

    // Slider
    const slider = document.getElementById('timeline-slider');
    slider.addEventListener('input', onSliderChange);

    // Trigger initial load if pre-selected
    if (preA && preB) {
      onVersusChange();
    }
  }

  // ============================================================
  // Mode Switching
  // ============================================================

  function switchMode(mode) {
    const tabs = document.querySelectorAll('.mode-tab');
    tabs.forEach(t => t.classList.remove('active'));
    document.getElementById('tab-' + mode).classList.add('active');

    const panels = document.querySelectorAll('.mode-panel');
    panels.forEach(function(p) { p.style.display = 'none'; });
    document.getElementById('panel-' + mode).style.display = 'block';
  }

  // ============================================================
  // Agent Data Fetching
  // ============================================================

  async function fetchAgent(name) {
    if (agentCache[name]) return agentCache[name];
    try {
      const res = await fetch(`/data/${name}-live.json`);
      if (!res.ok) return null;
      const data = await res.json();
      agentCache[name] = data;
      return data;
    } catch {
      return null;
    }
  }

  // ============================================================
  // Agent vs Agent Mode
  // ============================================================

  async function onVersusChange() {
    const selectA = document.getElementById('agent-a');
    const selectB = document.getElementById('agent-b');
    const container = document.getElementById('comparison-container');
    const empty = document.getElementById('empty-versus');

    const nameA = selectA.value;
    const nameB = selectB.value;

    if (!nameA || !nameB) {
      container.style.display = 'none';
      empty.style.display = 'block';
      return;
    }

    const [dataA, dataB] = await Promise.all([fetchAgent(nameA), fetchAgent(nameB)]);

    if (!dataA || !dataB) {
      container.style.display = 'none';
      empty.style.display = 'block';
      return;
    }

    empty.style.display = 'none';
    container.style.display = 'block';

    // Update labels and meta
    (document.getElementById('label-a')).textContent = dataA.agent || nameA;
    (document.getElementById('label-b')).textContent = dataB.agent || nameB;
    (document.getElementById('score-a')).textContent = String(dataA.overall_drift);
    (document.getElementById('score-b')).textContent = String(dataB.overall_drift);
    (document.getElementById('class-a')).textContent = dataA.severity || dataA.classification;
    (document.getElementById('class-b')).textContent = dataB.severity || dataB.classification;

    // Render trust scores
    renderTrustBadge(
      document.getElementById('trust-badge-a'),
      document.getElementById('trust-score-a'),
      dataA.trust_score,
      document.getElementById('trust-row-a')
    );
    renderTrustBadge(
      document.getElementById('trust-badge-b'),
      document.getElementById('trust-score-b'),
      dataB.trust_score,
      document.getElementById('trust-row-b')
    );

    // Render auras
    renderAura('aura-a', dataA, nameA);
    renderAura('aura-b', dataB, nameB);

    // Render diff bars
    renderDiffBars(dataA, dataB);
  }

  function renderAura(containerId, data, name) {
    var scores = { ...data.scores };
    var drift = { ...data.drift };
    const links = data.links || [];

    if (data.fidelity_score != null) {
      scores['Fidelity'] = Math.round((100 - data.fidelity_score) * 10) / 10;
      drift['Fidelity'] = Math.round(data.fidelity_score * 10) / 10;
    }

    var baseline = {};
    for (const dim of Object.keys(scores)) {
      if (scores[dim] != null && drift[dim] != null) {
        baseline[dim] = Math.min(100, scores[dim] + drift[dim]);
      }
    }

    const agent = {
      name: data.agent || name,
      scores,
      links,
      drift,
      baseline,
    };

    // WHY fallback: aura-engine.js loads async — if it hasn't arrived yet
    // (slow connection, blocked CDN), show a radar-chart polygon so the
    // comparison is still usable without the full energy-field renderer.
    if (typeof window.AuraEngine !== 'undefined' && window.AuraEngine.renderEnergy) {
      window.AuraEngine.renderEnergy(containerId, agent);
    } else {
      renderSimpleAura(containerId, agent);
    }
  }

  function renderSimpleAura(containerId, agent) {
    const container = document.getElementById(containerId);
    if (!container) return;

    // Use all available dimensions from agent data, ordered by canonical list
    var dims = DIMENSIONS.filter(d => agent.scores[d] != null);
    Object.keys(agent.scores).forEach(d => { if (!dims.includes(d) && agent.scores[d] != null) dims.push(d); });
    const CX = 150, CY = 150, MAX_R = 110;
    const angleStep = 360 / dims.length;

    function polar(angleDeg, r) {
      const rad = (angleDeg - 90) * Math.PI / 180;
      return { x: CX + r * Math.cos(rad), y: CY + r * Math.sin(rad) };
    }

    // Grid rings
    let gridRings = '';
    for (let i = 1; i <= 4; i++) {
      const r = MAX_R * (i / 4);
      gridRings += `<circle cx="${CX}" cy="${CY}" r="${r}" fill="none" stroke="rgba(255,255,255,0.04)" stroke-width="1" />`;
    }

    // Grid lines
    let gridLines = '';
    dims.forEach((_, i) => {
      const p = polar(i * angleStep, MAX_R);
      gridLines += `<line x1="${CX}" y1="${CY}" x2="${p.x}" y2="${p.y}" stroke="rgba(255,255,255,0.06)" stroke-width="1" />`;
    });

    // Data polygon
    const points = dims.map((dim, i) => {
      const r = (agent.scores[dim] / 100) * MAX_R;
      const p = polar(i * angleStep, r);
      return `${p.x},${p.y}`;
    }).join(' ');

    // Labels
    let labels = '';
    dims.forEach((dim, i) => {
      const p = polar(i * angleStep, MAX_R + 18);
      const score = agent.scores[dim];
      const driftVal = agent.drift ? agent.drift[dim] : undefined;
      const driftStr = driftVal !== undefined && driftVal > 5 ? ` (${driftVal})` : '';
      labels += `<text x="${p.x}" y="${p.y}" text-anchor="middle" dominant-baseline="middle" font-family="var(--font-mono)" font-size="9" fill="var(--text-muted)">${dim}</text>`;
      labels += `<text x="${p.x}" y="${p.y + 12}" text-anchor="middle" dominant-baseline="middle" font-family="var(--font-mono)" font-size="8" fill="var(--text-muted)" opacity="0.6">${score}${driftStr}</text>`;
    });

    // Dots at vertices
    let dots = '';
    dims.forEach((dim, i) => {
      const r = (agent.scores[dim] / 100) * MAX_R;
      const p = polar(i * angleStep, r);
      const color = DIM_COLORS[dim] || '#3b82f6';
      dots += `<circle cx="${p.x}" cy="${p.y}" r="4" fill="${color}" opacity="0.8" />`;
    });

    container.innerHTML = `
      <svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
        ${gridRings}
        ${gridLines}
        <polygon points="${points}" fill="rgba(59,130,246,0.08)" stroke="var(--accent)" stroke-width="1.5" opacity="0.8" />
        ${dots}
        ${labels}
      </svg>`;
  }

  function renderDiffBars(dataA, dataB) {
    const container = document.getElementById('diff-bars');
    container.innerHTML = '';

    // Use all dimensions present in either agent's data
    var dims = DIMENSIONS.filter(dim => dataA.scores[dim] != null || dataB.scores[dim] != null);

    dims.forEach(dim => {
      const scoreA = dataA.scores[dim] ?? 0;
      const scoreB = dataB.scores[dim] ?? 0;
      const diff = scoreA - scoreB;
      const maxScore = Math.max(scoreA, scoreB, 1);

      const item = document.createElement('div');
      item.className = 'diff-item';

      const label = document.createElement('div');
      label.className = 'diff-label';
      label.innerHTML = `<span>${dim}</span><span style="color: ${diff > 0 ? '#3b82f6' : diff < 0 ? '#eab308' : 'var(--text-muted)'}">${diff > 0 ? '+' : ''}${diff.toFixed(1)}</span>`;

      const track = document.createElement('div');
      track.className = 'diff-bar-track';

      const center = document.createElement('div');
      center.className = 'diff-bar-center';

      const fillA = document.createElement('div');
      fillA.className = 'diff-bar-fill-a';
      const pctA = (scoreA / 100) * 50;
      fillA.style.width = pctA + '%';
      fillA.style.background = DIM_COLORS[dim] || '#3b82f6';
      fillA.style.opacity = '0.7';

      // WHY different opacities (0.7 vs 0.35): A is always the "reference"
      // agent (left side) — stronger bar makes it obvious which direction
      // the difference goes without needing to read labels.
      const fillB = document.createElement('div');
      fillB.className = 'diff-bar-fill-b';
      const pctB = (scoreB / 100) * 50;
      fillB.style.width = pctB + '%';
      fillB.style.background = DIM_COLORS[dim] || '#3b82f6';
      fillB.style.opacity = '0.35';

      track.appendChild(fillA);
      track.appendChild(center);
      track.appendChild(fillB);
      item.appendChild(label);
      item.appendChild(track);
      container.appendChild(item);
    });
  }

  // ============================================================
  // Timeline Mode
  // ============================================================

  var timelineHistory = [];
  var timelineAgentData = null;

  async function onTimelineAgentChange() {
    const select = document.getElementById('agent-timeline');
    const controls = document.getElementById('timeline-controls');
    const display = document.getElementById('timeline-display');
    const empty = document.getElementById('empty-timeline');
    const slider = document.getElementById('timeline-slider');

    const name = select.value;

    if (!name) {
      controls.style.display = 'none';
      display.style.display = 'none';
      empty.style.display = 'block';
      return;
    }

    const data = await fetchAgent(name);
    if (!data || !data.history || data.history.length === 0) {
      controls.style.display = 'none';
      display.style.display = 'none';
      empty.style.display = 'block';
      return;
    }

    timelineAgentData = data;
    timelineHistory = data.history;

    empty.style.display = 'none';
    controls.style.display = 'block';
    display.style.display = 'grid';

    // Configure slider
    const maxIdx = timelineHistory.length - 1;
    slider.min = '0';
    slider.max = String(maxIdx);
    slider.value = String(maxIdx);

    // Range labels
    const startDate = formatDate(timelineHistory[0].date);
    const endDate = formatDate(timelineHistory[maxIdx].date);
    (document.getElementById('range-start')).textContent = startDate;
    (document.getElementById('range-end')).textContent = endDate;

    // Render current position
    renderTimelinePoint(maxIdx);
  }

  function onSliderChange() {
    const slider = document.getElementById('timeline-slider');
    const idx = parseInt(slider.value);
    renderTimelinePoint(idx);
  }

  function renderTimelinePoint(idx) {
    if (!timelineAgentData || !timelineHistory[idx]) return;

    const entry = timelineHistory[idx];

    // Update current label
    const currentLabel = document.getElementById('range-current');
    currentLabel.textContent = formatDate(entry.date);

    // Update meta
    (document.getElementById('tl-date')).textContent = formatDate(entry.date);
    (document.getElementById('tl-score')).textContent = String(entry.score);
    const severityEl = document.getElementById('tl-severity');
    severityEl.textContent = entry.severity || '--';
    severityEl.style.color = getSeverityColor(entry.score);

    // Build scores for this history point
    var scores = {};
    if (entry.dimensions) {
      // Use per-dimension scores from history (identity strength = 100 - drift)
      for (const [dim, val] of Object.entries(entry.dimensions)) {
        scores[dim] = val;
      }
    } else {
      // Fallback: use current scores
      for (const dim of DIMENSIONS) {
        scores[dim] = timelineAgentData.scores[dim] ?? 50;
      }
    }

    // Render the aura at this point
    const agent = {
      name: timelineAgentData.agent || 'Agent',
      scores,
      links: timelineAgentData.links || [],
    };

    if (typeof window.AuraEngine !== 'undefined' && window.AuraEngine.renderEnergy) {
      window.AuraEngine.renderEnergy('aura-timeline', agent);
    } else {
      renderSimpleAura('aura-timeline', agent);
    }

    // Render dimension bars
    renderTimelineDimensions(scores);

    // Render trust score if available in history entry or agent data
    var trustScore = entry.trust_score != null ? entry.trust_score : (timelineAgentData.trust_score != null ? timelineAgentData.trust_score : null);
    renderTrustBadge(
      document.getElementById('tl-trust-badge'),
      document.getElementById('tl-trust'),
      trustScore,
      document.getElementById('tl-trust-row')
    );
  }

  function renderTimelineDimensions(scores) {
    const container = document.getElementById('timeline-dimensions');
    container.innerHTML = '';

    // Render all dimensions present in the scores, ordered by the canonical DIMENSIONS list
    var dims = DIMENSIONS.filter(dim => scores[dim] != null);
    // Also include any dimensions not in the canonical list (future-proofing)
    Object.keys(scores).forEach(dim => { if (!dims.includes(dim)) dims.push(dim); });

    dims.forEach(dim => {
      const score = scores[dim];
      if (score == null) return;

      const row = document.createElement('div');
      row.className = 'tl-dim-row';

      const nameEl = document.createElement('span');
      nameEl.className = 'tl-dim-name';
      nameEl.textContent = dim;

      const track = document.createElement('div');
      track.className = 'tl-dim-bar-track';

      const fill = document.createElement('div');
      fill.className = 'tl-dim-bar-fill';
      fill.style.width = score + '%';
      fill.style.background = DIM_COLORS[dim] || '#3b82f6';
      fill.style.opacity = '0.7';

      const scoreEl = document.createElement('span');
      scoreEl.className = 'tl-dim-score';
      scoreEl.textContent = score.toFixed(1);

      track.appendChild(fill);
      row.appendChild(nameEl);
      row.appendChild(track);
      row.appendChild(scoreEl);
      container.appendChild(row);
    });
  }

  // ============================================================
  // Utilities
  // ============================================================

  function formatDate(iso) {
    try {
      const d = new Date(iso);
      return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
    } catch {
      return iso.slice(0, 10);
    }
  }

  function getSeverityColor(score) {
    if (score <= 15) return '#22c55e';
    if (score <= 35) return '#eab308';
    if (score <= 60) return '#f97316';
    return '#ef4444';
  }

  // ============================================================
  // Boot
  // ============================================================

  document.addEventListener('DOMContentLoaded', init);
</script>
