// Screen · Agents
// Post-onboarding management surface untuk agents yang udah di-spawn.
// 3 role-aware view: admin (Master + Dept tier), head (own Dept + Sub-Agents),
// staff (assigned Sub-Agents read-only).
// Pattern visual ngikut AgentHub-style cards, tapi vocab + semantic NalarX.

// Pretty source names — turn raw `postgres.transactions` paths into a friendly
// "Postgres · 3 tables" summary so the RBAC view isn't full of schema jargon.
const PRETTY_SOURCE = {
 postgres: 'Postgres', mysql: 'MySQL', bigquery: 'BigQuery', mongo: 'MongoDB',
 hris: 'HRIS', salesforce: 'Salesforce', hubspot: 'HubSpot', sharepoint: 'SharePoint',
 okta: 'Okta', jira: 'JIRA', coupa: 'Coupa', sap: 'SAP', netsuite: 'NetSuite',
};
const friendlyScope = (scope) => {
 const tables = (scope || '').split(',').map(s => s.trim()).filter(Boolean);
 const bySource = {};
 tables.forEach(t => { const src = t.split('.')[0]; bySource[src] = (bySource[src] || 0) + 1; });
 return Object.entries(bySource).map(([src, n]) => {
 const name = PRETTY_SOURCE[src] || (src.charAt(0).toUpperCase() + src.slice(1));
 return `${name} · ${n} ${n > 1 ? 'tables' : 'table'}`;
 }).join('   ·   ');
};

// Per-agent line icon (lucide) + warna per dept. Background = versi terang dari warna icon.
const AGENT_STYLE = {
  master:     { icon: 'sparkles',        fg: 'oklch(0.52 0.18 285)', bg: 'oklch(0.95 0.035 285)' },
  finance:    { icon: 'wallet',          fg: 'oklch(0.5 0.13 150)',  bg: 'oklch(0.95 0.045 150)' },
  hr:         { icon: 'users-round',     fg: 'oklch(0.55 0.15 350)', bg: 'oklch(0.95 0.04 350)' },
  people:     { icon: 'users-round',     fg: 'oklch(0.55 0.15 350)', bg: 'oklch(0.95 0.04 350)' },
  risk:       { icon: 'shield-alert',    fg: 'oklch(0.55 0.18 25)',  bg: 'oklch(0.95 0.05 25)' },
  sales:      { icon: 'trending-up',     fg: 'oklch(0.52 0.15 235)', bg: 'oklch(0.95 0.045 235)' },
  compliance: { icon: 'clipboard-check', fg: 'oklch(0.5 0.12 195)',  bg: 'oklch(0.95 0.04 195)' },
  procurement:{ icon: 'shopping-cart',   fg: 'oklch(0.55 0.15 55)',  bg: 'oklch(0.95 0.055 55)' },
  it:         { icon: 'monitor',         fg: 'oklch(0.5 0.13 255)',  bg: 'oklch(0.95 0.04 255)' },
};
const agentStyle = (agent = {}) => {
  const seg = (agent.id || '').split('-')[0];
  return AGENT_STYLE[agent.id] || AGENT_STYLE[agent.dept] || AGENT_STYLE[seg]
    || { icon: 'bot', fg: 'var(--ink-3)', bg: 'var(--bg-sunken)' };
};

// Colored line icon on a light tint of its own color (ChatGPT-agents style).
const AgentIcon = ({ agent, size = 42 }) => {
  const s = agentStyle(agent);
  return (
    <div style={{
      width: size, height: size, borderRadius: Math.round(size * 0.26),
      background: s.bg,
      display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
    }}>
      <iconify-icon icon={'lucide:' + s.icon}
        style={{ fontSize: Math.round(size * 0.5), color: s.fg }} />
    </div>
  );
};

// ──────────────────────────────────────────────────────────────
// Mock data — Banking workspace agents (BankCorp scenario)
// ──────────────────────────────────────────────────────────────

const MASTER_AGENT_MOCK = {
 id: 'master',
 icon: '✨',
 name: 'BankCorp Master Agent',
 desc: 'Top-level visibility · all-domain query routing · cross-dept request approver.',
 status: 'active',
 accuracy: '98.7%',
 uptime: '24/7',
 updated: '2h ago',
 stats: { dataSources: 6, capabilities: 4, rules: 23 },
 capabilities: ['WhatsApp', 'Web Search', 'Live Artifacts', 'Deep Research'],
 dataSources: ['postgres.transactions', 'bigquery.fraud', 'hris.employees', 'salesforce.opp', 'sharepoint.audit', 'hubspot.contacts'],
 spawnedAt: 'Track A · step 4',
};

const DEPT_AGENTS_MOCK = [
 {
 id: 'finance',
 icon: '💰',
 name: 'Finance Agent',
 desc: 'Cashflow, revenue, margin, biaya tracking.',
 status: 'active',
 accuracy: '99.2%',
 updated: '1h ago',
 heads: ['dewi.r@bankcorp.com'],
 dataScope: 'postgres.transactions, postgres.invoices, postgres.gl_journal',
 stats: { dataSources: 3, subAgents: 3, rules: 12, staff: 24 },
 capabilities: ['Web Search', 'Live Artifacts', 'Deep Research'],
 crossDeptAggregate: true,
 subAgents: [
 { id: 'finance-procurement', name: 'Procurement Sub-Agent', leads: ['budi.s@bankcorp.com'], staffCount: 8, status: 'active', inherits: true },
 { id: 'finance-purchasing', name: 'Purchasing Sub-Agent', leads: ['lisa.p@bankcorp.com'], staffCount: 4, status: 'active', inherits: true },
 { id: 'finance-reimburse', name: 'Reimbursement Sub-Agent', leads: [], staffCount: 12, status: 'active', inherits: false },
 ],
 },
 {
 id: 'hr',
 icon: '👥',
 name: 'HR Agent',
 desc: 'Headcount, retention, payroll, hiring pipeline.',
 status: 'active',
 accuracy: '97.1%',
 updated: '3h ago',
 heads: ['rina@bankcorp.com'],
 dataScope: 'hris.employees, hris.payroll',
 stats: { dataSources: 2, subAgents: 2, rules: 8, staff: 14 },
 capabilities: ['Web Search', 'Live Artifacts'],
 crossDeptAggregate: false,
 subAgents: [
 { id: 'hr-payroll', name: 'Payroll Sub-Agent', leads: ['payroll.lead@bankcorp.com'], staffCount: 5, status: 'active', inherits: true },
 { id: 'hr-recruiting', name: 'Recruiting Sub-Agent', leads: ['recruit@bankcorp.com'], staffCount: 9, status: 'active', inherits: true },
 ],
 },
 {
 id: 'risk',
 icon: '⚠️',
 name: 'Risk & Fraud Agent',
 desc: 'Velocity anomaly, exposure monitoring, fraud alert.',
 status: 'active',
 accuracy: '98.4%',
 updated: '2h ago',
 heads: ['sari@bankcorp.com'],
 dataScope: 'bigquery.fraud, bigquery.device_fingerprints',
 stats: { dataSources: 2, subAgents: 2, rules: 18, staff: 11 },
 capabilities: ['Web Search', 'Live Artifacts', 'Deep Research'],
 crossDeptAggregate: true,
 subAgents: [
 { id: 'risk-fraud-ops', name: 'Fraud Ops Sub-Agent', leads: ['fraud.lead@bankcorp.com'], staffCount: 7, status: 'active', inherits: true },
 { id: 'risk-aml', name: 'AML Sub-Agent', leads: ['aml.lead@bankcorp.com'], staffCount: 4, status: 'active', inherits: true },
 ],
 },
 {
 id: 'sales',
 icon: '📈',
 name: 'Sales Agent',
 desc: 'Pipeline, win rate, deal velocity.',
 status: 'pending-head',
 accuracy: '96.8%',
 updated: '4h ago',
 heads: ['budi.s@bankcorp.com'],
 dataScope: 'salesforce.opportunities, salesforce.accounts',
 stats: { dataSources: 1, subAgents: 0, rules: 0, staff: 0 },
 capabilities: ['Live Artifacts'],
 crossDeptAggregate: false,
 subAgents: [],
 },
 {
 id: 'compliance',
 icon: '📋',
 name: 'Compliance Agent',
 desc: 'Audit trail, regulatory filing, evidence binder.',
 status: 'active',
 accuracy: '99.0%',
 updated: '4h ago',
 heads: ['hadi.w@bankcorp.com'],
 dataScope: 'sharepoint.audit_evidence',
 stats: { dataSources: 1, subAgents: 1, rules: 6, staff: 5 },
 capabilities: ['Web Search', 'Live Artifacts', 'Deep Research'],
 crossDeptAggregate: false,
 subAgents: [
 { id: 'compliance-audit', name: 'Audit Sub-Agent', leads: ['audit.lead@bankcorp.com'], staffCount: 5, status: 'active', inherits: true },
 ],
 },
];

// Staff view: assigned Sub-Agents across dept
const STAFF_ASSIGNED_MOCK = [
 { id: 'finance-procurement', icon: '💰', name: 'Procurement Sub-Agent', parent: 'Finance Agent', lead: 'Pak Budi', desc: 'Vendor onboarding & PO tracking.', capabilities: ['Web Search', 'Live Artifacts'] },
 { id: 'finance-reimburse', icon: '💰', name: 'Reimbursement Sub-Agent', parent: 'Finance Agent', lead: '(team-led)', desc: 'Expense claims & approval flow.', capabilities: ['Web Search'] },
 { id: 'compliance-audit', icon: '📋', name: 'Audit Sub-Agent', parent: 'Compliance Agent', lead: 'Pak Hadi', desc: 'Audit evidence + regulatory filing.', capabilities: ['Web Search', 'Live Artifacts', 'Deep Research'] },
];

const STATUS_META = {
 active: { label: 'active', tone: 'var(--ok)', bg: 'var(--ok-soft)' },
 'pending-head': { label: 'pending Head', tone: 'oklch(0.5 0.16 70)', bg: 'oklch(0.96 0.05 70)' },
 archived: { label: 'archived', tone: 'var(--ink-4)', bg: 'var(--bg-sunken)' },
};

const CapabilityChip = ({ label }) => (
 <span className="nx-chip" style={{
 height: 22, fontSize: 11, padding: '0 8px',
 background: 'var(--bg-sunken)',
 color: 'var(--ink-2)',
 borderColor: 'transparent',
 }}>
 {label}
 </span>
);

const StatusBadge = ({ status }) => {
 const meta = STATUS_META[status] || STATUS_META.active;
 return (
 <span className="nx-chip" style={{
 height: 20, fontSize: 10.5, padding: '0 7px',
 background: meta.bg, color: meta.tone,
 borderColor: 'transparent', fontWeight: 500,
 }}>
 {meta.label}
 </span>
 );
};

// ──────────────────────────────────────────────────────────────
// Card components
// ──────────────────────────────────────────────────────────────

const Stat = ({ label, value }) => (
 <div>
 <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)' }}>{value}</div>
 <div style={{ fontSize: 10.5, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>{label}</div>
 </div>
);

// Clean catalog card (MiniMax-style): title + desc + light footer. Full detail in popup.
// One node in the hierarchy tree — compact, clickable row.
// Master card — root of the hierarchy.
const MasterCard = ({ agent, onOpen }) => (
 <button onClick={() => onOpen(agent)} className="nx-card"
 style={{
 width: '100%', display: 'block', textAlign: 'left', cursor: 'pointer', fontFamily: 'inherit',
 background: 'var(--bg-elev)', padding: 16, transition: 'transform .12s',
 }}
 onMouseEnter={(e) => { e.currentTarget.style.transform = 'translateY(-1px)'; }}
 onMouseLeave={(e) => { e.currentTarget.style.transform = 'none'; }}>
 <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
 <AgentIcon agent={agent} size={34} />
 <span style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)' }}>{agent.name}</span>
 <span className="nx-chip accent" style={{ height: 19, fontSize: 10, padding: '0 7px' }}>Master tier</span>
 <div style={{ flex: 1 }} />
 <Icon name="chevron-right" size={16} style={{ color: 'var(--ink-4)' }} />
 </div>
 <div style={{ fontSize: 12.5, color: 'var(--ink-3)', marginTop: 8 }}>{agent.desc}</div>
 <div style={{ marginTop: 12, paddingTop: 11, borderTop: '0.5px solid var(--line)', fontSize: 11.5, color: 'var(--ink-4)' }}>
 {agent.stats.dataSources} data sources · all-domain · cross-dept approver
 </div>
 </button>
);

// Department card (box) — header + its own Sub-Agent tree inside.
const DeptCard = ({ agent, onOpen }) => (
 <div className="nx-card" style={{ padding: 0, overflow: 'hidden', display: 'flex', flexDirection: 'column', background: 'var(--bg-elev)' }}>
 <button onClick={() => onOpen(agent)}
 style={{ border: 0, background: 'transparent', textAlign: 'left', cursor: 'pointer', fontFamily: 'inherit', padding: '15px 16px 12px', width: '100%' }}>
 <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
 <AgentIcon agent={agent} size={30} />
 <span style={{ flex: 1, minWidth: 0, fontSize: 14, fontWeight: 600, color: 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{agent.name}</span>
 <Icon name="chevron-right" size={14} style={{ color: 'var(--ink-4)', flexShrink: 0 }} />
 </div>
 <div style={{ fontSize: 12, color: 'var(--ink-3)', lineHeight: 1.45, marginTop: 6 }}>{agent.desc}</div>
 </button>

 {/* Per-department Sub-Agent tree */}
 {agent.subAgents.length > 0 && (
 <div style={{ padding: '2px 16px 8px' }}>
 <div style={{ fontSize: 10, fontWeight: 600, letterSpacing: '0.06em', textTransform: 'uppercase', color: 'var(--ink-4)', marginBottom: 8 }}>
 Sub-Agents · {agent.subAgents.length}
 </div>
 <div style={{ marginLeft: 14, borderLeft: '1px solid var(--line)', paddingLeft: 16, display: 'flex', flexDirection: 'column', gap: 9 }}>
 {agent.subAgents.map(sub => (
 <div key={sub.id} style={{ position: 'relative', display: 'flex', alignItems: 'center', gap: 9 }}>
 <div style={{ position: 'absolute', left: -16, top: '50%', width: 13, height: 1, background: 'var(--line)' }} />
 <AgentIcon agent={{ ...sub, dept: agent.id }} size={22} />
 <div style={{ flex: 1, minWidth: 0 }}>
 <div style={{ fontSize: 12, fontWeight: 550, color: 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{sub.name}</div>
 <div style={{ fontSize: 10.5, color: 'var(--ink-4)' }}>{sub.staffCount} staff</div>
 </div>
 </div>
 ))}
 </div>
 </div>
 )}

 <div style={{ marginTop: 'auto', padding: '10px 16px', borderTop: '0.5px solid var(--line)', fontSize: 11, color: 'var(--ink-4)' }}>
 {agent.stats.staff} staff · {agent.subAgents.length} sub-agent{agent.subAgents.length !== 1 ? 's' : ''}
 </div>
 </div>
);

// ──────────────────────────────────────────────────────────────
// Detail popup — full scope / capabilities / heads / sub-agents
// ──────────────────────────────────────────────────────────────

const ModalSection = ({ title, children }) => (
 <div style={{ padding: '14px 20px', borderTop: '0.5px solid var(--line)' }}>
 <div style={{ fontSize: 10.5, fontWeight: 600, letterSpacing: '0.06em', textTransform: 'uppercase', color: 'var(--ink-4)', marginBottom: 9 }}>{title}</div>
 {children}
 </div>
);

const AgentDetailModal = ({ agent, onClose }) => {
 const scope = agent.dataScope || (agent.dataSources || []).join(', ');
 const rawPaths = scope.split(',').map(s => s.trim()).filter(Boolean);
 const subs = agent.subAgents || [];
 const isMaster = agent.id === 'master';

 return ReactDOM.createPortal((
 <div onClick={onClose} style={{
 position: 'fixed', inset: 0, zIndex: 1000,
 background: 'oklch(0.15 0.02 268 / 0.35)', backdropFilter: 'blur(2px)',
 display: 'flex', alignItems: 'flex-start', justifyContent: 'center',
 paddingTop: '8vh', animation: 'nx-fade .12s ease-out',
 }}>
 <div onClick={(e) => e.stopPropagation()} style={{
 width: 'min(560px, 92vw)', maxHeight: '82vh', overflowY: 'auto',
 background: 'var(--bg-elev)', border: '0.5px solid var(--line-strong)',
 borderRadius: 14, boxShadow: '0 20px 60px oklch(0.15 0.02 268 / 0.25)',
 }}>
 {/* Header */}
 <div style={{ display: 'flex', alignItems: 'flex-start', gap: 13, padding: '20px 20px 16px' }}>
 <AgentIcon agent={agent} size={44} />
 <div style={{ flex: 1, minWidth: 0 }}>
 <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
 <span style={{ fontSize: 16, fontWeight: 600, color: 'var(--ink)' }}>{agent.name}</span>
 <StatusBadge status={agent.status} />
 <span className="nx-chip" style={{ height: 20, fontSize: 10.5, padding: '0 7px' }}>{isMaster ? 'Master tier' : 'Department tier'}</span>
 </div>
 <div style={{ fontSize: 12.5, color: 'var(--ink-3)', marginTop: 4, lineHeight: 1.45 }}>{agent.desc}</div>
 </div>
 <button onClick={onClose} className="nx-btn sm ghost" style={{ flexShrink: 0, width: 28, padding: 0, justifyContent: 'center' }}>
 <Icon name="x" size={14} />
 </button>
 </div>

 {/* Stats */}
 <div style={{ display: 'flex', gap: 28, padding: '0 20px 16px' }}>
 <Stat label="Data Sources" value={agent.stats.dataSources} />
 {isMaster && <Stat label="Capabilities" value={agent.stats.capabilities} />}
 <Stat label="Rules" value={agent.stats.rules} />
 {!isMaster && <Stat label="Staff" value={agent.stats.staff} />}
 {!isMaster && <Stat label="Sub-Agents" value={subs.length} />}
 </div>

 {/* Data scope */}
 <ModalSection title="Data scope">
 <div style={{ fontSize: 12.5, color: 'var(--ink-2)', marginBottom: 8 }}>{friendlyScope(scope)}</div>
 <div style={{ display: 'flex', flexWrap: 'wrap', gap: 5 }}>
 {rawPaths.map((p, i) => (
 <span key={i} style={{ fontFamily: 'var(--font-mono)', fontSize: 10.5, color: 'var(--ink-4)', background: 'var(--bg-sunken)', padding: '2px 7px', borderRadius: 5 }}>{p}</span>
 ))}
 </div>
 </ModalSection>

 {/* Capabilities */}
 {agent.capabilities && agent.capabilities.length > 0 && (
 <ModalSection title="Capabilities">
 <div style={{ display: 'flex', flexWrap: 'wrap', gap: 5 }}>
 {agent.capabilities.map((c, i) => <CapabilityChip key={i} label={c} />)}
 {agent.crossDeptAggregate && (
 <span className="nx-chip" style={{ height: 22, fontSize: 11, padding: '0 8px', background: 'oklch(0.96 0.04 50)', color: 'oklch(0.5 0.16 50)', borderColor: 'transparent' }}>
 <Icon name="arrow-up-right" size={10} /> Cross-dept aggregate
 </span>
 )}
 </div>
 </ModalSection>
 )}

 {/* Heads */}
 {agent.heads && (
 <ModalSection title={agent.heads.length > 1 ? 'Department Heads · multi-Head' : 'Department Head'}>
 {agent.heads.length > 0
 ? agent.heads.map((h, i) => (
 <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 7, fontSize: 12, color: 'var(--ink-2)', fontFamily: 'var(--font-mono)', marginBottom: 3 }}>
 <Icon name="mail" size={12} style={{ color: 'var(--ink-4)' }} /> {h}
 </div>
 ))
 : <div style={{ fontSize: 12, color: 'var(--ink-4)', fontStyle: 'italic' }}>Belum di-assign</div>}
 </ModalSection>
 )}

 {/* Sub-Agents */}
 {subs.length > 0 && (
 <ModalSection title={`Sub-Agents · ${subs.length}`}>
 <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
 {subs.map(sub => (
 <div key={sub.id} style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
 <span style={{ width: 6, height: 6, borderRadius: '50%', background: sub.status === 'active' ? 'var(--ok)' : 'var(--ink-4)', flexShrink: 0 }} />
 <div style={{ flex: 1, minWidth: 0 }}>
 <div style={{ fontSize: 12.5, fontWeight: 550, color: 'var(--ink)' }}>{sub.name}</div>
 <div style={{ fontSize: 10.5, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)' }}>
 {sub.leads.length === 0 ? 'no lead' : sub.leads[0]} · {sub.staffCount} staff
 </div>
 </div>
 {sub.inherits
 ? <span className="nx-chip" style={{ height: 18, fontSize: 9.5, padding: '0 6px', background: 'var(--ok-soft)', color: 'var(--ok)', borderColor: 'transparent' }}>inherits</span>
 : <span className="nx-chip warn" style={{ height: 18, fontSize: 9.5, padding: '0 6px' }}>overrides</span>}
 </div>
 ))}
 </div>
 </ModalSection>
 )}

 {/* Actions */}
 <div style={{ display: 'flex', gap: 8, padding: '14px 20px', borderTop: '0.5px solid var(--line)' }}>
 <button className="nx-btn sm"><Icon name="edit" size={12} /> Edit context</button>
 <button className="nx-btn sm"><Icon name="shield" size={12} /> Manage access</button>
 </div>
 </div>
 </div>
 ), document.body);
};

// SubAgentCard · read-only RBAC card untuk Staff
// Bukan chat shortcut — Chat selalu via menu `Chat`, NalarX routing internal otomatis.
const SubAgentCard = ({ sub, agent }) => (
 <div className="nx-card" style={{ padding: 14 }}>
 <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10, marginBottom: 8 }}>
 <AgentIcon agent={sub} size={36} />
 <div style={{ flex: 1, minWidth: 0 }}>
 <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)' }}>{sub.name}</div>
 <div style={{ fontSize: 11, color: 'var(--ink-4)' }}>
 {sub.parent || agent?.name} · lead: {sub.lead || sub.leads?.[0] || '(none)'}
 </div>
 </div>
 <span className="nx-chip ok" style={{ height: 20, fontSize: 10.5, padding: '0 7px' }}>access granted</span>
 </div>
 <div style={{ fontSize: 12, color: 'var(--ink-3)', lineHeight: 1.45, marginBottom: 10 }}>
 {sub.desc || 'Sub-Agent inherits dari parent.'}
 </div>
 <div style={{ display: 'flex', flexWrap: 'wrap', gap: 5 }}>
 {(sub.capabilities || []).map((c, i) => <CapabilityChip key={i} label={c} />)}
 </div>
 <div style={{
 marginTop: 10, paddingTop: 10,
 borderTop: '0.5px solid var(--line)',
 fontSize: 11, color: 'var(--ink-4)',
 lineHeight: 1.5,
 }}>
 Scope ini bisa Anda akses saat tanya di <b style={{ color: 'var(--ink-3)' }}>Nalar Assistant</b> · NalarX routing otomatis.
 </div>
 </div>
);

// ──────────────────────────────────────────────────────────────
// View modes per role
// ──────────────────────────────────────────────────────────────

const AdminView = () => {
 const [selected, setSelected] = React.useState(null);
 const depts = DEPT_AGENTS_MOCK;

 return (
 <>
 {/* Master (root) */}
 <MasterCard agent={MASTER_AGENT_MOCK} onOpen={setSelected} />

 {/* Org-chart connector — Master branches down to Department Agents */}
 <div style={{ position: 'relative', height: 26 }}>
 <div style={{ position: 'absolute', left: '50%', top: 0, width: 1.5, height: 13, background: 'var(--line-strong)' }} />
 <div style={{ position: 'absolute', left: '12%', right: '12%', top: 13, height: 1.5, background: 'var(--line-strong)' }} />
 {['16%', '50%', '84%'].map(l => (
 <div key={l} style={{ position: 'absolute', left: l, top: 13, width: 1.5, height: 13, background: 'var(--line-strong)' }} />
 ))}
 </div>

 <div style={{ marginBottom: 12 }}>
 <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>
 Department Agents · {depts.length}
 </div>
 </div>

 {/* Department cards — each box holds its own Sub-Agent tree */}
 <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(360px, 1fr))', gap: 12, alignItems: 'start' }}>
 {depts.map(dept => (
 <DeptCard key={dept.id} agent={dept} onOpen={setSelected} />
 ))}
 </div>

 {selected && <AgentDetailModal agent={selected} onClose={() => setSelected(null)} />}
 </>
 );
};

// ──────────────────────────────────────────────────────────────
// Mode 2 · Org-chart view — Master hero + connector tree + a row of
// Department cards, then an aligned row of their Sub-agent cards.
// Columns share one horizontal scroller so the tree stays aligned
// (and scrolls as a unit) when there are many departments.
// ──────────────────────────────────────────────────────────────

const ORG_COL_W = 240;
const ORG_COL_GAP = 14;

// Master trunk + horizontal bus + a drop to each department column.
// Pixel math against fixed column width keeps it aligned inside the scroller.
// Curved SVG connectors with arrowheads — fan out from under the master card
// to each department. SVG lives inside the transformed content, so it scales
// with the canvas pan/zoom.
const ARROW_MARKER = (id) => (
 <defs>
 <marker id={id} markerWidth="8" markerHeight="8" refX="6.2" refY="3.5" orient="auto" markerUnits="userSpaceOnUse">
 <path d="M0 0 L7 3.5 L0 7 z" fill="currentColor" />
 </marker>
 </defs>
);

const OrgConnector = ({ count }) => {
 if (count < 1) return null;
 const w = ORG_COL_W, g = ORG_COL_GAP;
 const center = (i) => i * (w + g) + w / 2;
 const contentW = count * w + (count - 1) * g;
 const H = 34;
 const mid = contentW / 2;
 return (
 <svg width={contentW} height={H} style={{ display: 'block', color: 'var(--line-strong)', overflow: 'visible' }}>
 {ARROW_MARKER('nx-arrow-dept')}
 {Array.from({ length: count }).map((_, i) => {
 const cx = center(i);
 const d = `M ${mid} 0 C ${mid} ${H * 0.62}, ${cx} ${H * 0.42}, ${cx} ${H - 1}`;
 return <path key={i} d={d} fill="none" stroke="currentColor" strokeWidth="1.5" markerEnd="url(#nx-arrow-dept)" />;
 })}
 </svg>
 );
};

// Vertical drops bridging each Department card to its Sub-agent card below.
// Skips columns with no sub-agents. "Sub-agents" label rides at the left.
const OrgSubConnector = ({ depts }) => {
 const w = ORG_COL_W, g = ORG_COL_GAP;
 const center = (i) => i * (w + g) + w / 2;
 const contentW = depts.length * w + (depts.length - 1) * g;
 const H = 28;
 return (
 <div style={{ position: 'relative', margin: '4px 0 0' }}>
 <div style={{ position: 'absolute', left: 0, top: 7, fontSize: 11, fontWeight: 600, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.06em', zIndex: 1 }}>
 Sub-agents
 </div>
 <svg width={contentW} height={H} style={{ display: 'block', color: 'var(--line-strong)', overflow: 'visible' }}>
 {ARROW_MARKER('nx-arrow-sub')}
 {depts.map((d, i) => (d.subAgents && d.subAgents.length > 0) ? (
 <path key={d.id} d={`M ${center(i)} 0 L ${center(i)} ${H - 1}`} fill="none" stroke="currentColor" strokeWidth="1.5" markerEnd="url(#nx-arrow-sub)" />
 ) : null)}
 </svg>
 </div>
 );
};

const OrgLabel = ({ children, top = 0 }) => (
 <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.06em', margin: `${top}px 0 10px` }}>
 {children}
 </div>
);

const hoverLift = {
 onMouseEnter: (e) => { e.currentTarget.style.transform = 'translateY(-1px)'; },
 onMouseLeave: (e) => { e.currentTarget.style.transform = 'none'; },
};

const OrgMasterCard = ({ agent, onOpen }) => (
 <button onClick={() => onOpen(agent)} className="nx-card" {...hoverLift}
 style={{ width: '100%', display: 'block', textAlign: 'left', cursor: 'pointer', fontFamily: 'inherit', background: 'var(--bg-elev)', padding: 18, transition: 'transform .12s' }}>
 <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
 <AgentIcon agent={agent} size={44} />
 <span style={{ fontSize: 16, fontWeight: 600, color: 'var(--ink)' }}>{agent.name}</span>
 <span className="nx-chip accent" style={{ height: 20, fontSize: 10.5, padding: '0 8px' }}>Master Tier</span>
 <div style={{ flex: 1 }} />
 <StatusBadge status={agent.status} />
 <Icon name="menu-dots" size={16} style={{ color: 'var(--ink-4)' }} />
 </div>
 <div style={{ fontSize: 12.5, color: 'var(--ink-3)', marginTop: 10 }}>{agent.desc}</div>
 <div style={{ display: 'flex', alignItems: 'flex-end', gap: 36, marginTop: 16 }}>
 <Stat label="Data sources" value={agent.stats.dataSources} />
 <Stat label="Accuracy" value={agent.accuracy} />
 <Stat label="Active" value={agent.uptime} />
 <div style={{ display: 'flex', alignItems: 'center', gap: 6, color: 'var(--ink-4)', fontSize: 11.5, marginBottom: 1 }}>
 <Icon name="clock" size={12} /> Updated {agent.updated}
 </div>
 </div>
 </button>
);

const OrgDeptCard = ({ agent, onOpen }) => (
 <button onClick={() => onOpen(agent)} className="nx-card" {...hoverLift}
 style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', textAlign: 'left', cursor: 'pointer', fontFamily: 'inherit', background: 'var(--bg-elev)', padding: 0, transition: 'transform .12s' }}>
 <div style={{ padding: '14px 14px 0' }}>
 <div style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
 <AgentIcon agent={agent} size={28} />
 <span style={{ flex: 1, minWidth: 0, fontSize: 13.5, fontWeight: 600, color: 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{agent.name}</span>
 <StatusBadge status={agent.status} />
 </div>
 <div style={{ fontSize: 11.5, color: 'var(--ink-3)', lineHeight: 1.4, marginTop: 8, minHeight: 32 }}>{agent.desc}</div>
 </div>
 <div style={{ display: 'flex', gap: 14, padding: '12px 14px 14px' }}>
 <Stat label="Sub-agents" value={agent.subAgents.length} />
 <Stat label="Users" value={agent.stats.staff} />
 <Stat label="Accuracy" value={agent.accuracy} />
 </div>
 <div style={{ marginTop: 'auto', display: 'flex', alignItems: 'center', gap: 6, padding: '10px 14px', borderTop: '0.5px solid var(--line)', fontSize: 11, color: 'var(--ink-4)' }}>
 <Icon name="clock" size={11} /> Updated {agent.updated}
 <div style={{ flex: 1 }} />
 <Icon name="chevron-right" size={14} />
 </div>
 </button>
);

const OrgSubCard = ({ agent, onOpen }) => {
 const subs = agent.subAgents || [];
 return (
 <div className="nx-card" style={{ height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--bg-elev)', padding: '12px 14px' }}>
 {subs.length === 0 ? (
 <div style={{ fontSize: 11.5, color: 'var(--ink-4)', fontStyle: 'italic', padding: '4px 0' }}>No sub-agents yet</div>
 ) : (
 <div style={{ display: 'flex', flexDirection: 'column', gap: 11 }}>
 {subs.map(sub => (
 <div key={sub.id} style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
 <AgentIcon agent={{ ...sub, dept: agent.id }} size={26} />
 <div style={{ flex: 1, minWidth: 0 }}>
 <div style={{ fontSize: 12, fontWeight: 550, color: 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{sub.name}</div>
 <div style={{ fontSize: 10.5, color: 'var(--ink-4)' }}>{sub.staffCount} staff</div>
 </div>
 </div>
 ))}
 </div>
 )}
 {subs.length > 0 && (
 <div style={{ marginTop: 'auto', borderTop: '0.5px solid var(--line)', marginLeft: -14, marginRight: -14, paddingTop: 8, marginTop: 12 }}>
 <button onClick={() => onOpen(agent)}
 style={{ width: '100%', border: 0, background: 'transparent', cursor: 'pointer', fontFamily: 'inherit', textAlign: 'left', padding: '0 14px', fontSize: 11.5, color: 'var(--ink-3)' }}
 onMouseEnter={(e) => { e.currentTarget.style.color = 'var(--accent-ink)'; }}
 onMouseLeave={(e) => { e.currentTarget.style.color = 'var(--ink-3)'; }}>
 View all {subs.length} sub-agent{subs.length !== 1 ? 's' : ''}
 </button>
 </div>
 )}
 </div>
 );
};

// The org tree content (master → dept row → sub row), shared by the scroll
// view and the canvas view.
const OrgTree = ({ onOpen }) => {
 const depts = DEPT_AGENTS_MOCK;
 const w = ORG_COL_W, g = ORG_COL_GAP;
 const contentW = depts.length * w + (depts.length - 1) * g;
 const Col = ({ children }) => <div style={{ width: w, flexShrink: 0 }}>{children}</div>;
 return (
 <div style={{ width: contentW }}>
 <OrgLabel>Master Agent</OrgLabel>
 <OrgMasterCard agent={MASTER_AGENT_MOCK} onOpen={onOpen} />
 <OrgConnector count={depts.length} />
 <OrgLabel>Department Agents · {depts.length}</OrgLabel>
 <div style={{ display: 'flex', gap: g, alignItems: 'stretch' }}>
 {depts.map(d => <Col key={d.id}><OrgDeptCard agent={d} onOpen={onOpen} /></Col>)}
 </div>
 <OrgSubConnector depts={depts} />
 <div style={{ display: 'flex', gap: g, alignItems: 'stretch' }}>
 {depts.map(d => <Col key={d.id}><OrgSubCard agent={d} onOpen={onOpen} /></Col>)}
 </div>
 </div>
 );
};

const OrgChartView = () => {
 const [selected, setSelected] = React.useState(null);
 return (
 <>
 {/* Horizontal scroller — fixed-width cards, full content reachable. */}
 <div style={{ overflowX: 'auto', overflowY: 'hidden', paddingBottom: 10 }}>
 <OrgTree onOpen={setSelected} />
 </div>
 {selected && <AgentDetailModal agent={selected} onClose={() => setSelected(null)} />}
 </>
 );
};

// ──────────────────────────────────────────────────────────────
// Mode 3 · Canvas — pan / zoom / pinch the org tree (no dependency).
// Hand-rolled (what react-zoom-pan-pinch does under the hood): a viewport
// with a CSS-transformed content layer; wheel zooms toward the cursor, drag
// pans, two pointers pinch. Transform is applied imperatively for smoothness.
// ──────────────────────────────────────────────────────────────
const PanZoom = ({ children, initialScale = 0.8, min = 0.3, max = 2.5 }) => {
 const wrapRef = React.useRef(null);
 const contentRef = React.useRef(null);
 const view = React.useRef({ x: 40, y: 32, k: initialScale });
 const pts = React.useRef(new Map());
 const drag = React.useRef(null);
 const pinch = React.useRef(null);
 const moved = React.useRef(false);
 const clamp = (k) => Math.min(max, Math.max(min, k));
 const apply = () => { const c = contentRef.current; if (c) c.style.transform = `translate(${view.current.x}px,${view.current.y}px) scale(${view.current.k})`; };
 const zoomAt = (cx, cy, factor) => {
 const v = view.current, k = clamp(v.k * factor), r = k / v.k;
 v.x = cx - (cx - v.x) * r; v.y = cy - (cy - v.y) * r; v.k = k; apply();
 };

 // Center the content in the viewport (content may render a tick later if a
 // layout lib is still loading, so retry until it has a measurable size).
 const centerView = () => {
 const el = wrapRef.current, c = contentRef.current;
 if (!el || !c) return;
 const cw = c.scrollWidth, ch = c.scrollHeight, k = view.current.k;
 view.current.x = Math.round((el.clientWidth - cw * k) / 2);
 view.current.y = (ch * k + 56 < el.clientHeight) ? Math.round((el.clientHeight - ch * k) / 2) : 28;
 apply();
 };

 React.useEffect(() => {
 apply();
 const el = wrapRef.current;
 let tries = 0;
 const initCenter = () => { const c = contentRef.current; if (c && c.scrollWidth > 120) centerView(); else if (tries++ < 15) setTimeout(initCenter, 120); };
 initCenter();
 const onWheel = (e) => { e.preventDefault(); const rc = el.getBoundingClientRect(); zoomAt(e.clientX - rc.left, e.clientY - rc.top, Math.exp(-e.deltaY * 0.0015)); };
 el.addEventListener('wheel', onWheel, { passive: false });
 return () => el.removeEventListener('wheel', onWheel);
 }, []);

 const down = (e) => {
 pts.current.set(e.pointerId, { x: e.clientX, y: e.clientY });
 moved.current = false;
 if (pts.current.size === 1) drag.current = { sx: e.clientX, sy: e.clientY, ox: view.current.x, oy: view.current.y };
 else if (pts.current.size === 2) { const [a, b] = [...pts.current.values()]; pinch.current = { d: Math.hypot(a.x - b.x, a.y - b.y), k: view.current.k }; drag.current = null; }
 };
 const move = (e) => {
 if (!pts.current.has(e.pointerId)) return;
 pts.current.set(e.pointerId, { x: e.clientX, y: e.clientY });
 const rc = wrapRef.current.getBoundingClientRect();
 if (pts.current.size === 2 && pinch.current) {
 const [a, b] = [...pts.current.values()], d = Math.hypot(a.x - b.x, a.y - b.y);
 const mx = (a.x + b.x) / 2 - rc.left, my = (a.y + b.y) / 2 - rc.top;
 const target = clamp(pinch.current.k * (d / pinch.current.d)), r = target / view.current.k;
 view.current.x = mx - (mx - view.current.x) * r; view.current.y = my - (my - view.current.y) * r; view.current.k = target; apply();
 moved.current = true;
 } else if (drag.current) {
 const dx = e.clientX - drag.current.sx, dy = e.clientY - drag.current.sy;
 if (Math.abs(dx) + Math.abs(dy) > 4) moved.current = true;
 view.current.x = drag.current.ox + dx; view.current.y = drag.current.oy + dy; apply();
 }
 };
 const up = (e) => { pts.current.delete(e.pointerId); if (pts.current.size < 2) pinch.current = null; if (pts.current.size === 0) drag.current = null; };
 const clickCapture = (e) => { if (moved.current) { e.stopPropagation(); moved.current = false; } };

 const center = (factor) => { const rc = wrapRef.current.getBoundingClientRect(); zoomAt(rc.width / 2, rc.height / 2, factor); };
 const reset = () => { view.current.k = initialScale; centerView(); };

 const CtrlBtn = ({ icon, onClick, title }) => (
 <button onClick={onClick} title={title} style={{
 width: 30, height: 30, border: '0.5px solid var(--line)', borderRadius: 8, background: 'var(--bg-elev)',
 color: 'var(--ink-3)', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
 boxShadow: '0 1px 2px rgba(0,0,0,.06)',
 }}
 onMouseEnter={(e) => { e.currentTarget.style.background = 'var(--bg-hover)'; e.currentTarget.style.color = 'var(--ink)'; }}
 onMouseLeave={(e) => { e.currentTarget.style.background = 'var(--bg-elev)'; e.currentTarget.style.color = 'var(--ink-3)'; }}>
 <Icon name={icon} size={15} />
 </button>
 );

 return (
 <div ref={wrapRef}
 onPointerDown={down} onPointerMove={move} onPointerUp={up} onPointerCancel={up} onPointerLeave={up}
 onClickCapture={clickCapture}
 style={{ position: 'absolute', inset: 0, overflow: 'hidden', touchAction: 'none', cursor: 'grab' }}>
 <div ref={contentRef} style={{ position: 'absolute', top: 0, left: 0, transformOrigin: '0 0', willChange: 'transform' }}>
 {children}
 </div>
 <div style={{ position: 'absolute', right: 12, bottom: 12, display: 'flex', flexDirection: 'column', gap: 6 }}>
 <CtrlBtn icon="plus" title="Zoom in" onClick={() => center(1.25)} />
 <CtrlBtn icon="minus" title="Zoom out" onClick={() => center(0.8)} />
 <CtrlBtn icon="expand" title="Reset view" onClick={reset} />
 </div>
 </div>
 );
};

// d3-hierarchy layout with the existing cards as nodes. d3.tree() computes the
// positions (scales to any depth), d3.linkVertical() draws the curved links.
const D3_NODE_W = { master: 470, dept: ORG_COL_W, sub: ORG_COL_W };
const D3_CARD_H = { master: 132, dept: 158, sub: 120 };

const OrgD3Tree = ({ onOpen }) => {
 const d3ready = !!(window.d3 && window.d3.tree && window.d3.linkVertical);
 const [, force] = React.useReducer((x) => x + 1, 0);
 React.useEffect(() => {
 if (d3ready) return;
 const id = setInterval(() => { if (window.d3 && window.d3.tree) { clearInterval(id); force(); } }, 150);
 return () => clearInterval(id);
 }, [d3ready]);

 const layout = React.useMemo(() => {
 if (!d3ready) return null;
 const d3 = window.d3;
 const depts = DEPT_AGENTS_MOCK;
 const data = {
 kind: 'master', agent: MASTER_AGENT_MOCK,
 children: depts.map(d => ({
 kind: 'dept', agent: d,
 children: (d.subAgents && d.subAgents.length > 0) ? [{ kind: 'sub', agent: d }] : [],
 })),
 };
 const root = d3.hierarchy(data);
 // separation()=1 → even spacing regardless of parent (d3's default doubles
 // the gap for non-siblings, which spread the sub-agent columns way apart).
 d3.tree().nodeSize([ORG_COL_W + 48, 210]).separation(() => 1)(root);
 const nodes = root.descendants();
 const minX = Math.min(...nodes.map(n => n.x));
 const PAD = 140; // >= half the widest node so the leftmost card never clips
 nodes.forEach(n => { n.px = n.x - minX + PAD; n.py = n.y + 28; });
 const links = root.links().map(l => ({
 sx: l.source.px, sy: l.source.py + (D3_CARD_H[l.source.data.kind] || 140),
 tx: l.target.px, ty: l.target.py,
 }));
 const maxX = Math.max(...nodes.map(n => n.px));
 const width = maxX + PAD;
 const height = Math.max(...nodes.map(n => n.py)) + 240;
 return { nodes, links, width, height };
 }, [d3ready]);

 if (!layout) {
 return <div style={{ height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, color: 'var(--ink-3)', fontSize: 13 }}>
 <Icon name="refresh" size={14} className="nx-spin" /> Computing layout…
 </div>;
 }

 const link = window.d3.linkVertical().x(d => d.x).y(d => d.y);
 return (
 <div style={{ position: 'relative', width: layout.width, height: layout.height }}>
 <svg width={layout.width} height={layout.height} style={{ position: 'absolute', top: 0, left: 0, color: 'var(--line-strong)', overflow: 'visible' }}>
 {ARROW_MARKER('nx-arrow-d3')}
 {layout.links.map((l, i) => (
 <path key={i} d={link({ source: { x: l.sx, y: l.sy }, target: { x: l.tx, y: l.ty } })}
 fill="none" stroke="currentColor" strokeWidth="1.5" markerEnd="url(#nx-arrow-d3)" />
 ))}
 </svg>
 {layout.nodes.map((n, i) => {
 const w = D3_NODE_W[n.data.kind];
 const card = n.data.kind === 'master' ? <OrgMasterCard agent={n.data.agent} onOpen={onOpen} />
 : n.data.kind === 'dept' ? <OrgDeptCard agent={n.data.agent} onOpen={onOpen} />
 : <OrgSubCard agent={n.data.agent} onOpen={onOpen} />;
 return <div key={i} style={{ position: 'absolute', left: n.px - w / 2, top: n.py, width: w }}>{card}</div>;
 })}
 </div>
 );
};

const OrgCanvasView = () => {
 const [selected, setSelected] = React.useState(null);
 return (
 <>
 <div style={{ position: 'relative', height: 'calc(100vh - 150px)', border: '0.5px solid var(--line)', borderRadius: 14, overflow: 'hidden', background: 'var(--bg-sunken)' }}>
 <PanZoom initialScale={0.8}>
 <OrgD3Tree onOpen={setSelected} />
 </PanZoom>
 <div style={{ position: 'absolute', left: 14, top: 12, fontSize: 11, color: 'var(--ink-4)', pointerEvents: 'none' }}>
 d3 layout · drag to pan · scroll to zoom · pinch on trackpad
 </div>
 </div>
 {selected && <AgentDetailModal agent={selected} onClose={() => setSelected(null)} />}
 </>
 );
};

// Segmented toggle · switch between Cards (Mode 1) and Org chart (Mode 2).
const ViewToggle = ({ mode, setMode }) => (
 <div style={{ display: 'flex', gap: 2, padding: 2, background: 'var(--bg-sunken)', border: '0.5px solid var(--line)', borderRadius: 8 }}>
 {[['cards', 'Cards', 'layers'], ['org', 'Org chart', 'route'], ['canvas', 'Canvas', 'expand']].map(([id, label, icon]) => (
 <button key={id} onClick={() => setMode(id)}
 style={{
 display: 'flex', alignItems: 'center', gap: 6, height: 26, padding: '0 10px',
 border: 0, borderRadius: 6, cursor: 'pointer', fontFamily: 'inherit', fontSize: 12,
 fontWeight: mode === id ? 550 : 450,
 background: mode === id ? 'var(--bg-elev)' : 'transparent',
 color: mode === id ? 'var(--ink)' : 'var(--ink-3)',
 boxShadow: mode === id ? '0 1px 2px rgba(0,0,0,.06)' : 'none',
 transition: 'background .12s, color .12s',
 }}>
 <Icon name={icon} size={13} /> {label}
 </button>
 ))}
 </div>
);

const HeadView = ({ search = '' }) => {
 // Mock: this Head owns Finance Agent
 const myDeptAgent = DEPT_AGENTS_MOCK.find(a => a.id === 'finance');

 const filteredSubs = (myDeptAgent?.subAgents || []).filter(s =>
!search.trim() || s.name.toLowerCase().includes(search.toLowerCase())
 );

 return (
 <>
 {/* My Dept Agent · context banner */}
 {!search.trim() && (
 <div className="nx-card" style={{ padding: 16, marginBottom: 16, background: 'var(--bg-elev)' }}>
 <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
 <AgentIcon agent={myDeptAgent} size={42} />
 <div style={{ flex: 1, minWidth: 0 }}>
 <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
 <span style={{ fontSize: 11, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.05em', fontWeight: 600 }}>You manage</span>
 <span className="nx-chip" style={{ height: 18, fontSize: 10, padding: '0 6px' }}>Dept tier</span>
 </div>
 <div style={{ fontSize: 16, fontWeight: 600, color: 'var(--ink)', marginTop: 2 }}>{myDeptAgent.name}</div>
 <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 2 }}>{myDeptAgent.desc}</div>
 </div>
 <button className="nx-btn sm">
 <Icon name="edit" size={11} /> Edit context
 </button>
 </div>
 </div>
 )}

 {/* Section header */}
 <div style={{ marginBottom: 12 }}>
 <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>
 Sub-Agents · {filteredSubs.length}
 </div>
 </div>

 {/* Sub-Agent grid (build inline-rich card for Head perspective) */}
 <div style={{
 display: 'grid',
 gridTemplateColumns: 'repeat(auto-fill, minmax(320px, 1fr))',
 gap: 12,
 }}>
 {filteredSubs.map(sub => (
 <div key={sub.id} className="nx-card" style={{ padding: 14 }}>
 <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10, marginBottom: 10 }}>
 <AgentIcon agent={myDeptAgent} size={36} />
 <div style={{ flex: 1, minWidth: 0 }}>
 <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 3 }}>
 <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)' }}>{sub.name}</div>
 <StatusBadge status={sub.status} />
 </div>
 <div style={{ fontSize: 11, color: 'var(--ink-4)' }}>
 Inherits {myDeptAgent.name}
 {sub.inherits
? <span style={{ color: 'var(--ok)', marginLeft: 6 }}>· no overrides</span>
 : <span style={{ color: 'oklch(0.5 0.16 70)', marginLeft: 6 }}>· has overrides</span>}
 </div>
 </div>
 <button className="nx-btn sm ghost"><Icon name="menu-dots" size={12} /></button>
 </div>

 <div style={{ display: 'flex', gap: 14, marginBottom: 10, fontSize: 11 }}>
 <Stat label="Lead" value={sub.leads.length} />
 <Stat label="Staff" value={sub.staffCount} />
 </div>

 <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '7px 10px', background: 'var(--bg-sunken)', borderRadius: 6, marginBottom: 10 }}>
 <Icon name="mail" size={11} style={{ color: 'var(--ink-4)' }} />
 <span style={{ fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)' }}>
 {sub.leads.length > 0? sub.leads[0] : 'No lead assigned · click to add'}
 </span>
 </div>

 <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8 }}>
 <button className="nx-btn sm" style={{ flex: 1 }}>
 <Icon name="edit" size={11} /> Configure
 </button>
 <button className="nx-btn sm" style={{ flex: 1 }}>
 <Icon name="users" size={11} /> Assign
 </button>
 </div>
 </div>
 ))}
 </div>
 </>
 );
};

const StaffView = ({ search = '', setRoute = () => {} }) => {
 const filtered = STAFF_ASSIGNED_MOCK.filter(s =>
!search.trim() ||
 s.name.toLowerCase().includes(search.toLowerCase()) ||
 s.parent.toLowerCase().includes(search.toLowerCase())
 );

 return (
 <>
 {/* Info banner · RBAC framing */}
 {!search.trim() && (
 <div style={{
 padding: '12px 14px',
 background: 'var(--accent-soft)',
 border: '0.5px solid oklch(0.85 0.05 268)',
 borderRadius: 9,
 fontSize: 12, color: 'var(--ink-2)',
 display: 'flex', alignItems: 'center', gap: 12, lineHeight: 1.5,
 marginBottom: 20,
 }}>
 <Icon name="info" size={14} style={{ color: 'var(--accent)', flexShrink: 0 }} />
 <div style={{ flex: 1 }}>
 Ini bukan tempat chat. Halaman ini cuma kasih tahu <b>data scope</b> apa yang bisa Anda akses.
 Untuk tanya, buka <b>Nalar Assistant</b> — NalarX otomatis pilih sub-agent yang tepat.
 </div>
 <button onClick={() => setRoute('chat')}
 className="nx-btn primary sm"
 style={{ height: 30 }}>
 <Icon name="chat" size={12} /> Buka Nalar Assistant
 </button>
 </div>
 )}

 <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 12 }}>
 Data scope yang bisa Anda akses · {filtered.length}
 </div>

 <div style={{
 display: 'grid',
 gridTemplateColumns: 'repeat(auto-fill, minmax(320px, 1fr))',
 gap: 12,
 }}>
 {filtered.map(sub => <SubAgentCard key={sub.id} sub={sub} />)}
 </div>
 </>
 );
};

// ──────────────────────────────────────────────────────────────
// Main screen
// ──────────────────────────────────────────────────────────────

const ScreenAgents = ({ persona = 'admin', setRoute = () => {} }) => {
 const [viewMode, setViewMode] = React.useState('cards');
 const totalAgents = persona === 'admin'
? 1 + DEPT_AGENTS_MOCK.length + DEPT_AGENTS_MOCK.reduce((s, a) => s + a.subAgents.length, 0)
 : persona === 'head'
? DEPT_AGENTS_MOCK[0].subAgents.length + 1
 : STAFF_ASSIGNED_MOCK.length;

 const heading = persona === 'admin'
? { title: 'Agents', sub: 'Access Agent View' }
 : persona === 'head'
? { title: 'Agents', sub: 'Access Agent View' }
 : { title: 'My Access', sub: 'Access Agent View' };

 // Canvas is a pan/zoom surface — let it use the full main area (no maxWidth
 // cap, smaller padding). Cards / Org chart stay in the readable 1200 column.
 const wide = persona === 'admin' && viewMode === 'canvas';

 return (
 <div className="nx-page" style={{
 padding: wide ? '24px 20px 16px' : '24px 32px 40px',
 maxWidth: wide ? 'none' : 1200, margin: '0 auto',
 }}>
 {/* Header */}
 <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 16, gap: 16 }}>
 <div>
 <h1 style={{ margin: 0, fontSize: 22, fontWeight: 500, letterSpacing: '-0.01em' }}>
 {heading.title}
 </h1>
 <div style={{ marginTop: 4, color: 'var(--ink-3)', fontSize: 13 }}>
 {heading.sub}
 </div>
 </div>
 <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
 {persona === 'admin' && <ViewToggle mode={viewMode} setMode={setViewMode} />}
 <span style={{ fontSize: 11.5, color: 'var(--ink-4)' }} className="nx-mono">
 {totalAgents} active
 </span>
 </div>
 </div>

 {/* Role-aware view · ternary chain so unknown persona (e.g., stale "analyst") falls back to Staff */}
 {persona === 'admin'? (viewMode === 'org'? <OrgChartView /> : viewMode === 'canvas'? <OrgCanvasView /> : <AdminView />)
 : persona === 'head'? <HeadView />
 : <StaffView setRoute={setRoute} />}
 </div>
 );
};

window.ScreenAgents = ScreenAgents;
