// Tech Console — primary surface
// Left: queue filters + rows
// Center: ticket detail with live streaming agent plan
// Right: context panel (user, device, KBAs, related)

const { useState, useEffect, useMemo, useRef } = React;

// ---------- Top bar ----------
const ProfileMenu = ({ session, onSignOut }) => {
  const [open, setOpen] = useState(false);
  const [toast, setToast] = useState(null);
  const [confirmSignOut, setConfirmSignOut] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    if (!open) return;
    const handler = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [open]);
  // Reset transient UI state when menu closes.
  useEffect(() => { if (!open) { setConfirmSignOut(false); setToast(null); } }, [open]);
  // Auto-dismiss toast.
  useEffect(() => {
    if (!toast) return;
    const id = setTimeout(() => setToast(null), 2500);
    return () => clearTimeout(id);
  }, [toast]);

  const signedInAgo = (() => {
    try {
      const mins = Math.floor((Date.now() - new Date(session.signedInAt).getTime()) / 60000);
      if (mins < 1) return 'just now';
      if (mins < 60) return `${mins}m ago`;
      const h = Math.floor(mins / 60);
      if (h < 24) return `${h}h ago`;
      return `${Math.floor(h / 24)}d ago`;
    } catch (e) { return '—'; }
  })();

  return (
    <div ref={ref} style={{position: 'relative'}}>
      <button
        onClick={() => setOpen(o => !o)}
        style={{width: 32, height: 32, borderRadius: '50%', background: 'linear-gradient(135deg, var(--nyu-purple), var(--nyu-indigo))', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontWeight: 700, fontSize: 12, letterSpacing: '0.05em', border: open ? '2px solid var(--nyu-digital)' : 'none', cursor: 'pointer', padding: 0}}
        title={`Signed in as ${session.name}`}
      >{session.initials}</button>
      {open && (
        <div style={{position: 'absolute', top: 42, right: 0, width: 300, background: 'white', border: '1px solid var(--border-strong)', borderRadius: 12, boxShadow: '0 12px 40px rgba(24, 3, 48, 0.16)', zIndex: 100, overflow: 'hidden'}}>
          {/* Identity header */}
          <div style={{padding: '16px 16px 14px', background: 'linear-gradient(135deg, rgba(128, 0, 255, 0.04), rgba(179, 65, 255, 0.08))', borderBottom: '1px solid var(--border)'}}>
            <div style={{display: 'flex', alignItems: 'center', gap: 12}}>
              <div style={{width: 40, height: 40, borderRadius: '50%', background: 'linear-gradient(135deg, var(--nyu-purple), var(--nyu-indigo))', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontWeight: 700, fontSize: 14}}>{session.initials}</div>
              <div style={{flex: 1, minWidth: 0}}>
                <div style={{fontWeight: 700, fontSize: 13, color: 'var(--nyu-black)'}}>{session.name}</div>
                <div style={{fontSize: 11, color: 'var(--nyu-text)', fontFamily: 'var(--font-mono)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'}}>{session.email}</div>
              </div>
            </div>
            <div style={{display: 'flex', gap: 6, marginTop: 12, flexWrap: 'wrap'}}>
              <span className="chip chip-purple" style={{fontSize: 10}}>{session.role}</span>
              <span className="chip" style={{fontSize: 10}}>{session.dept}</span>
            </div>
          </div>

          {/* Org + session */}
          <div style={{padding: '12px 16px', borderBottom: '1px solid var(--border)'}}>
            <div style={{display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8}}>
              <div style={{fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.06em', color: 'var(--nyu-text)'}}>Organization</div>
            </div>
            <div style={{display: 'flex', alignItems: 'center', gap: 10}}>
              <div style={{width: 28, height: 28, borderRadius: 6, background: 'var(--nyu-purple)', color: 'white', fontWeight: 800, fontSize: 10, display: 'flex', alignItems: 'center', justifyContent: 'center', letterSpacing: '0.02em'}}>{session.orgLogo}</div>
              <div style={{flex: 1}}>
                <div style={{fontSize: 12, fontWeight: 600, color: 'var(--nyu-black)'}}>{session.org}</div>
                <div style={{fontSize: 10, color: 'var(--nyu-text)'}}>{session.provider}</div>
              </div>
            </div>
          </div>

          {/* Security */}
          <div style={{padding: '10px 16px', borderBottom: '1px solid var(--border)', display: 'grid', gap: 6, fontSize: 11}}>
            <div style={{display: 'flex', justifyContent: 'space-between', color: 'var(--nyu-text)'}}>
              <span>Session started</span><span style={{color: 'var(--nyu-black)'}}>{signedInAgo}</span>
            </div>
            <div style={{display: 'flex', justifyContent: 'space-between', color: 'var(--nyu-text)'}}>
              <span>MFA</span><span style={{color: 'var(--mint-ink, #006B51)'}}>✓ {session.mfa}</span>
            </div>
            <div style={{display: 'flex', justifyContent: 'space-between', color: 'var(--nyu-text)'}}>
              <span>Groups</span><span style={{color: 'var(--nyu-black)', fontFamily: 'var(--font-mono)', fontSize: 10}}>{(session.groups || []).length} assigned</span>
            </div>
          </div>

          {/* Actions */}
          <div style={{padding: 6}}>
            <button type="button" onClick={() => setToast('Profile & preferences — coming soon')} className="menu-item" style={{width: '100%', background: 'transparent', border: 'none', textAlign: 'left', fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 10, padding: '8px 10px', fontSize: 12, color: 'var(--nyu-black)', borderRadius: 6, cursor: 'pointer'}}>
              <Icon name="settings" size={14}/> Profile & preferences
            </button>
            <button type="button" onClick={() => setToast('Keyboard shortcuts — press ?')} className="menu-item" style={{width: '100%', background: 'transparent', border: 'none', textAlign: 'left', fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 10, padding: '8px 10px', fontSize: 12, color: 'var(--nyu-black)', borderRadius: 6, cursor: 'pointer'}}>
              <Icon name="command" size={14}/> Keyboard shortcuts <span style={{marginLeft: 'auto', fontSize: 10, color: 'var(--nyu-disabled)'}}>?</span>
            </button>
            <a href="audit-log.html" className="menu-item" style={{display: 'flex', alignItems: 'center', gap: 10, padding: '8px 10px', fontSize: 12, color: 'var(--nyu-black)', textDecoration: 'none', borderRadius: 6}}>
              <Icon name="shield" size={14}/> My audit trail
            </a>
            <div style={{height: 1, background: 'var(--border)', margin: '4px 6px'}}></div>
            {confirmSignOut ? (
              <div style={{display: 'flex', alignItems: 'center', gap: 8, padding: '8px 10px', background: 'var(--red-tint)', borderRadius: 6}}>
                <Icon name="alert" size={14} color="var(--nyu-red)"/>
                <span style={{fontSize: 12, fontWeight: 600, color: '#B00045'}}>Sign out of Violet?</span>
                <button type="button" onClick={() => setConfirmSignOut(false)} style={{marginLeft: 'auto', background: 'transparent', border: 'none', fontSize: 12, color: 'var(--nyu-text)', cursor: 'pointer', padding: '4px 8px', borderRadius: 4, fontFamily: 'inherit'}}>Cancel</button>
                <button type="button" onClick={() => { onSignOut(); window.location.href = 'sign-in.html'; }} style={{background: 'var(--nyu-red)', color: 'white', border: 'none', fontSize: 12, fontWeight: 600, padding: '4px 10px', borderRadius: 4, cursor: 'pointer', fontFamily: 'inherit'}}>Sign out</button>
              </div>
            ) : (
              <button type="button" onClick={() => setConfirmSignOut(true)} className="menu-item" style={{width: '100%', background: 'transparent', border: 'none', textAlign: 'left', fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 10, padding: '8px 10px', fontSize: 12, color: 'var(--nyu-red)', borderRadius: 6, cursor: 'pointer'}}>
                <Icon name="log-out" size={14}/> Sign out
              </button>
            )}
          </div>

          {toast && (
            <div style={{padding: '8px 14px', background: 'var(--nyu-black)', color: 'white', fontSize: 11, display: 'flex', alignItems: 'center', gap: 8}}>
              <Icon name="info" size={12} color="white"/>
              <span style={{flex: 1}}>{toast}</span>
            </div>
          )}
        </div>
      )}
    </div>
  );
};

const TopBar = ({ paused, setPaused, onCmdK, activeSurface = 'console' }) => {
  const [session, setSession] = useState(() => (window.VioletSession ? window.VioletSession.getSession() : { initials: 'AK', name: 'Alex Kotler', email: 'alex.kotler@nyulangone.org', role: 'Tier 2', dept: 'Desktop Support', org: 'NYU Langone Health', orgLogo: 'NYU', provider: 'Entra ID', signedInAt: new Date().toISOString(), mfa: 'Duo · verified', groups: [] }));
  const handleSignOut = () => { if (window.VioletSession) window.VioletSession.signOut(); };
  return (
  <header className="app-header" style={{minWidth: 1100}}>
    <a href="index.html" className="wordmark" style={{textDecoration: 'none', color: 'inherit', cursor: 'pointer'}} title="Back to demo navigator">
      <span>NYU Langone Health</span>
      <span className="pipe"></span>
      <span className="sub">Desktop Support</span>
    </a>
    <div className="violet-badge">
      <span className="dot dot-pulse"></span>
      Violet
    </div>
    <nav className="nav-tabs">
      <a href="tech-home.html" className={`nav-tab ${activeSurface === 'home' ? 'active' : ''}`}>
        <Icon name="activity" size={14}/> Home
      </a>
      <a href="tech-console.html" className={`nav-tab ${activeSurface === 'console' ? 'active' : ''}`}>
        <Icon name="inbox" size={14}/> Tech console
      </a>
      <a href="ops-dashboard.html" className={`nav-tab ${activeSurface === 'ops' ? 'active' : ''}`}>
        <Icon name="users" size={14}/> Ops
      </a>
      <a href="portal.html" className={`nav-tab ${activeSurface === 'portal' ? 'active' : ''}`}>
        <Icon name="phone" size={14}/> End-user portal
      </a>
    </nav>
    <div style={{marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 12}}>
      <button className="btn btn-ghost btn-sm" onClick={onCmdK} style={{minWidth: 200}}>
        <Icon name="search" size={14}/>
        <span style={{color: 'var(--nyu-disabled)', flex: 1, textAlign: 'left'}}>Search or run command</span>
        <span className="kbd">⌘K</span>
      </button>
      <button
        className={`btn btn-sm ${paused ? 'btn-danger' : 'btn-secondary'}`}
        onClick={() => setPaused(p => !p)}
        title="Pause all auto-resolution"
      >
        <Icon name={paused ? 'play' : 'pause'} size={14}/>
        {paused ? 'Resume Violet' : 'Pause Violet'}
      </button>
      <ProfileMenu session={session} onSignOut={handleSignOut}/>
    </div>
  </header>
  );
};

// ---------- Left queue ----------
const statusChip = (t) => {
  if (t.status === 'auto-resolved') return <span className="chip chip-mint"><Icon name="check" size={10} strokeWidth={2.5}/> Auto-resolved</span>;
  if (t.status === 'in-progress') return <span className="chip chip-purple"><span className="ring-spin" style={{width: 8, height: 8, borderWidth: 1.5}}></span> Agent working</span>;
  if (t.status === 'hitl-required') return <span className="chip chip-orange"><Icon name="shield" size={10} strokeWidth={2.5}/> HITL · Destructive</span>;
  if (t.status === 'hitl-review') return <span className="chip chip-orange"><Icon name="eye" size={10} strokeWidth={2.5}/> HITL · Review</span>;
  if (t.status === 'escalated') return <span className="chip chip-outline"><Icon name="route" size={10} strokeWidth={2.5}/> Escalated</span>;
  return <span className="chip">{t.status}</span>;
};

const urgencyDot = (u) => {
  const colors = { critical: 'var(--nyu-red)', high: 'var(--nyu-orange)', medium: 'var(--nyu-indigo)', low: 'var(--nyu-disabled)' };
  return <span className="dot" style={{background: colors[u] || 'var(--nyu-disabled)'}}></span>;
};

const relTime = (iso) => {
  const d = new Date(iso);
  const now = new Date('2026-04-20T14:22:00');
  const diff = Math.floor((now - d) / 60000);
  if (diff < 1) return 'just now';
  if (diff < 60) return `${diff}m ago`;
  if (diff < 1440) return `${Math.floor(diff / 60)}h ago`;
  return `${Math.floor(diff / 1440)}d ago`;
};

const QueueFilters = ({ active, setActive, tickets }) => {
  const counts = {
    all: tickets.length,
    mine: tickets.filter(t => t.assignedTo === 'Violet').length,
    hitl: tickets.filter(t => t.status.startsWith('hitl')).length,
    sla: tickets.filter(t => t.slaDueAt && new Date(t.slaDueAt) - new Date('2026-04-20T14:22:00') < 30 * 60000 && t.status !== 'auto-resolved').length,
    auto: tickets.filter(t => t.status === 'auto-resolved').length,
  };
  const filters = [
    { id: 'all', label: 'All active', icon: 'inbox', count: counts.all },
    { id: 'mine', label: 'Assigned to Violet', icon: 'violet', count: counts.mine },
    { id: 'hitl', label: 'HITL review', icon: 'shield', count: counts.hitl, accent: 'orange' },
    { id: 'sla', label: 'SLA at-risk', icon: 'clock', count: counts.sla, accent: 'red' },
    { id: 'auto', label: 'Auto-resolved', icon: 'check', count: counts.auto, accent: 'mint' },
  ];
  return (
    <div style={{padding: '12px 10px', borderBottom: '1px solid var(--border)'}}>
      {filters.map(f => (
        <button
          key={f.id}
          type="button"
          onClick={() => setActive(f.id)}
          style={{
            display: 'flex',
            alignItems: 'center',
            gap: 10,
            padding: '8px 10px',
            borderRadius: 8,
            border: 'none',
            cursor: 'pointer',
            background: active === f.id ? 'var(--purple-tint)' : 'transparent',
            color: active === f.id ? 'var(--nyu-purple)' : 'var(--nyu-text)',
            fontWeight: active === f.id ? 600 : 500,
            fontSize: 13,
            fontFamily: 'inherit',
            width: '100%',
            textAlign: 'left',
          }}
        >
          <Icon name={f.icon} size={14}/>
          <span style={{flex: 1}}>{f.label}</span>
          <span style={{
            fontSize: 11, fontWeight: 600,
            background: active === f.id ? 'var(--nyu-purple)' : 'var(--nyu-gray-100)',
            color: active === f.id ? 'white' : 'var(--nyu-text)',
            padding: '1px 7px', borderRadius: 999,
          }}>{f.count}</span>
        </button>
      ))}
    </div>
  );
};

const TicketRow = ({ ticket, selected, onClick }) => {
  const user = USERS[ticket.user];
  return (
    <button
      type="button"
      onClick={onClick}
      style={{
        padding: '12px 14px',
        border: 'none',
        borderBottom: '1px solid var(--border)',
        borderLeft: selected ? '3px solid var(--nyu-purple)' : '3px solid transparent',
        cursor: 'pointer',
        background: selected ? 'var(--purple-tint)' : 'transparent',
        transition: 'background 100ms',
        width: '100%',
        textAlign: 'left',
        fontFamily: 'inherit',
        color: 'inherit',
        display: 'block',
      }}
      onMouseEnter={e => { if (!selected) e.currentTarget.style.background = 'var(--nyu-gray-50)'; }}
      onMouseLeave={e => { if (!selected) e.currentTarget.style.background = 'transparent'; }}
    >
      <div style={{display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4}}>
        {urgencyDot(ticket.urgency)}
        <span className="mono" style={{fontSize: 11, color: 'var(--nyu-text)'}}>{ticket.id}</span>
        <span style={{marginLeft: 'auto', fontSize: 11, color: 'var(--nyu-text)'}}>{relTime(ticket.createdAt)}</span>
      </div>
      <div style={{fontSize: 13.5, fontWeight: 600, color: 'var(--nyu-black)', marginBottom: 4, lineHeight: 1.3}}>
        {ticket.subject}
      </div>
      <div style={{fontSize: 12, color: 'var(--nyu-text)', marginBottom: 6}}>
        {user?.name} · {user?.dept}
      </div>
      <div style={{display: 'flex', gap: 6, flexWrap: 'wrap'}}>
        {statusChip(ticket)}
      </div>
    </button>
  );
};

// ---------- Live streaming agent plan ----------
const planStepIcon = (agent) => {
  const map = {
    ingest: 'inbox', classify: 'brain', enrich: 'database', memory: 'folder',
    dispatch: 'route', plan: 'sparkle', account: 'key', endpoint: 'cpu',
    verify: 'shield', respond: 'send', escalate: 'route', prepare: 'file',
    gate: 'shield', wait: 'clock', 'follow-up': 'eye',
  };
  return map[agent] || 'bolt';
};

const PlanStep = ({ step, i, revealed, onClick, expanded }) => {
  const statusColor = {
    done: 'var(--nyu-mint)',
    running: 'var(--nyu-indigo)',
    queued: 'var(--nyu-disabled)',
    failed: 'var(--nyu-red)',
    hitl: 'var(--nyu-orange)',
  }[step.status] || 'var(--nyu-disabled)';

  return (
    <div
      className={revealed ? 'plan-step' : ''}
      style={{
        display: revealed ? 'flex' : 'none',
        gap: 10,
        padding: '8px 0',
        cursor: step.detail ? 'pointer' : 'default',
        animationDelay: `${i * 40}ms`,
      }}
      onClick={() => step.detail && onClick()}
    >
      {/* Timeline rail */}
      <div style={{width: 22, display: 'flex', flexDirection: 'column', alignItems: 'center', position: 'relative', flexShrink: 0}}>
        <div style={{
          width: 20, height: 20, borderRadius: '50%',
          background: step.status === 'done' ? 'var(--mint-tint)' : step.status === 'running' ? 'var(--purple-tint)' : step.status === 'hitl' ? 'var(--orange-tint)' : 'var(--nyu-gray-100)',
          border: `1.5px solid ${statusColor}`,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          zIndex: 2,
        }}>
          {step.status === 'done' && <Icon name="check" size={11} strokeWidth={3} color={statusColor}/>}
          {step.status === 'running' && <span className="ring-spin" style={{width: 10, height: 10, borderWidth: 1.5}}></span>}
          {step.status === 'queued' && <div style={{width: 6, height: 6, borderRadius: '50%', background: statusColor}}></div>}
          {step.status === 'hitl' && <Icon name="alert" size={11} strokeWidth={2} color="var(--nyu-orange)"/>}
        </div>
        <div style={{width: 1.5, flex: 1, background: 'var(--border)', marginTop: 2}}></div>
      </div>
      {/* Content */}
      <div style={{flex: 1, minWidth: 0, paddingBottom: 6}}>
        <div style={{display: 'flex', alignItems: 'baseline', gap: 8, marginBottom: 2, flexWrap: 'wrap'}}>
          <span style={{
            fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.08em',
            color: 'var(--nyu-purple)', background: 'var(--purple-tint)',
            padding: '2px 8px', borderRadius: 999,
          }}>
            {step.agent}
          </span>
          {step.tool && (
            <span className="mono" style={{fontSize: 11, color: 'var(--nyu-text)', background: 'var(--nyu-gray-100)', padding: '2px 7px', borderRadius: 999}}>
              {step.tool}
            </span>
          )}
          {step.model && (
            <span style={{fontSize: 10, color: 'var(--nyu-text)'}}>
              <Icon name="sparkle" size={10}/> {step.model}
            </span>
          )}
          {step.t && <span className="mono" style={{fontSize: 10, color: 'var(--nyu-disabled)', marginLeft: 'auto'}}>{step.t}</span>}
        </div>
        <div style={{fontSize: 13, color: 'var(--nyu-black)', fontWeight: 500, lineHeight: 1.35}}>
          {step.action}
          {step.duration && <span style={{color: 'var(--nyu-disabled)', fontWeight: 400, marginLeft: 8, fontSize: 11}} className="mono">{step.duration}ms</span>}
        </div>
        {step.detail && (expanded || step.status === 'running' || step.status === 'hitl') && (
          <div style={{
            fontSize: 12, color: 'var(--nyu-text)', marginTop: 4, lineHeight: 1.45,
            padding: step.status === 'hitl' ? '8px 10px' : 0,
            background: step.status === 'hitl' ? 'var(--orange-tint)' : 'transparent',
            borderRadius: step.status === 'hitl' ? 6 : 0,
            border: step.status === 'hitl' ? '1px solid #FFB74D' : 'none',
          }}>
            {step.detail}
          </div>
        )}
      </div>
    </div>
  );
};

const AgentPlanCard = ({ ticket, paused, onHitlClick, onHandoffClick }) => {
  const [revealedCount, setRevealedCount] = useState(ticket.status === 'auto-resolved' ? ticket.trace.length : 0);
  const [expanded, setExpanded] = useState({});
  const [collapsed, setCollapsed] = useState(false);
  const tid = ticket.id;

  // Stream in the trace for live tickets. Reset when ticket changes.
  useEffect(() => {
    if (paused) return;
    if (ticket.status === 'auto-resolved') { setRevealedCount(ticket.trace.length); return; }
    setRevealedCount(1);
    const max = ticket.trace.length;
    let i = 1;
    const interval = setInterval(() => {
      i += 1;
      setRevealedCount(c => Math.min(max, c + 1));
      if (i >= max) clearInterval(interval);
    }, 650);
    return () => clearInterval(interval);
  }, [tid, paused]);

  const confidenceColor = ticket.confidence >= 0.85 ? 'var(--nyu-mint)' : 'var(--nyu-orange)';

  return (
    <div className="card" style={{marginBottom: 20, overflow: 'hidden'}}>
      {/* Header */}
      <div style={{
        padding: '14px 20px',
        background: 'linear-gradient(90deg, var(--nyu-deep-purple), var(--nyu-purple))',
        color: 'white',
        display: 'flex', alignItems: 'center', gap: 12,
      }}>
        <div style={{
          width: 28, height: 28, borderRadius: '50%',
          background: 'rgba(255,255,255,0.18)', display: 'flex', alignItems: 'center', justifyContent: 'center',
          border: '1px solid rgba(255,255,255,0.3)',
        }}>
          <Icon name="violet" size={16} color="white"/>
        </div>
        <div style={{flex: 1, minWidth: 0}}>
          <div style={{fontSize: 13, fontWeight: 700, letterSpacing: '-0.01em', whiteSpace: 'nowrap'}}>
            Violet · Live agent plan
          </div>
          <div style={{fontSize: 11, opacity: 0.8, marginTop: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>
            {ticket.status === 'auto-resolved' && `Resolved in ${ticket.ttr} · vs. ${ticket.humanBaseline} human baseline`}
            {ticket.status === 'in-progress' && `Streaming · ${revealedCount}/${ticket.trace.length} steps`}
            {ticket.status === 'hitl-required' && `Paused at destructive-action gate · awaiting human`}
            {ticket.status === 'escalated' && `Escalated to human · confidence below threshold`}
          </div>
        </div>
        {/* Confidence meter */}
        <div style={{display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 3}}>
          <div style={{fontSize: 10, opacity: 0.7, textTransform: 'uppercase', letterSpacing: '0.08em', fontWeight: 600}}>Confidence</div>
          <div style={{display: 'flex', alignItems: 'center', gap: 8}}>
            <div style={{width: 60, height: 4, background: 'rgba(255,255,255,0.2)', borderRadius: 2, overflow: 'hidden'}}>
              <div style={{width: `${ticket.confidence * 100}%`, height: '100%', background: confidenceColor, transition: 'width 400ms ease'}}></div>
            </div>
            <span className="mono" style={{fontSize: 13, fontWeight: 700}}>{ticket.confidence.toFixed(2)}</span>
          </div>
          <div style={{fontSize: 10, opacity: 0.65}}>gate: 0.85</div>
        </div>
        <button
          className="btn btn-xs"
          style={{background: 'rgba(255,255,255,0.15)', color: 'white', border: '1px solid rgba(255,255,255,0.3)'}}
          onClick={() => setCollapsed(c => !c)}
        >
          <Icon name={collapsed ? 'chevron' : 'chevronDown'} size={12}/>
          {collapsed ? 'Expand' : 'Collapse'}
        </button>
      </div>

      {!collapsed && (
        <>
          {/* HITL banner on destructive */}
          {ticket.status === 'hitl-required' && (
            <div style={{padding: '12px 20px', background: 'var(--orange-tint)', borderBottom: '1px solid #FFB74D', display: 'flex', alignItems: 'center', gap: 12}}>
              <Icon name="shield" size={18} color="#8A4E00"/>
              <div style={{flex: 1}}>
                <div style={{fontSize: 13, fontWeight: 700, color: '#8A4E00'}}>
                  Destructive-action gate · human approval required
                </div>
                <div style={{fontSize: 12, color: '#8A4E00', marginTop: 2}}>
                  Intune wipe is on the always-HITL list, regardless of confidence ({ticket.confidence.toFixed(2)}). Violet has staged the full 5-step plan and is waiting.
                </div>
              </div>
              <button className="btn btn-primary btn-sm" onClick={onHitlClick}>
                Review &amp; approve
                <Icon name="arrow" size={12}/>
              </button>
            </div>
          )}
          {ticket.status === 'escalated' && (
            <div style={{padding: '12px 20px', background: 'var(--nyu-gray-50)', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 12}}>
              <Icon name="route" size={18} color="var(--nyu-purple)"/>
              <div style={{flex: 1}}>
                <div style={{fontSize: 13, fontWeight: 700}}>
                  Handed off to a human with full context packet
                </div>
                <div style={{fontSize: 12, color: 'var(--nyu-text)', marginTop: 2}}>
                  Confidence {ticket.confidence.toFixed(2)} fell below the 0.85 gate. Violet stepped back per policy.
                </div>
              </div>
              <button className="btn btn-secondary btn-sm" onClick={onHandoffClick}>
                View handoff packet
                <Icon name="arrow" size={12}/>
              </button>
            </div>
          )}

          <div style={{padding: '16px 20px 12px'}}>
            {ticket.trace.map((step, i) => (
              <PlanStep
                key={i}
                i={i}
                step={step}
                revealed={i < revealedCount}
                expanded={expanded[i]}
                onClick={() => setExpanded(e => ({...e, [i]: !e[i]}))}
              />
            ))}
            {revealedCount < ticket.trace.length && (
              <div style={{padding: '8px 32px', color: 'var(--nyu-purple)', fontSize: 12, display: 'flex', alignItems: 'center', gap: 8}}>
                <span className="ring-spin"></span>
                Violet is thinking
                <span className="caret" style={{width: 5, height: 11}}></span>
              </div>
            )}
          </div>
        </>
      )}
    </div>
  );
};

window.TechConsoleShared = { TopBar, QueueFilters, TicketRow, AgentPlanCard, statusChip, urgencyDot, relTime };
