// All the non-home pages. Kept light but complete enough to feel like a real app.
// Pages: Portfolio, Projects (list + detail v1 + detail v2), Initiatives (list + detail v1 + detail v2),
// Ideas (list + detail), Components (list + detail), Tickets, Help, Admin.

// ── PORTFOLIO ────────────────────────────────────────────────────────
const PortfolioPage = ({ goto }) => (
  <Page>
    <PageHeader kicker="Portfolio" title="Initiatives, projects, and the lines that connect them"
      subtitle="A read-only roll-up of the entire portfolio. Filter by sensitivity, owner, phase. Click any node to drill in." />
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16, marginBottom: 'var(--apm-section-gap)' }}>
      <Card><Stat label="Initiatives" value="4" /></Card>
      <Card><Stat label="Projects in flight" value="9" sub="3 archived" /></Card>
      <Card><Stat label="At-risk" value="2" tone="warn" /></Card>
      <Card><Stat label="FY spend" value="$4.4M / $10.2M" /></Card>
    </div>
    <SectionHeading title="Initiatives" />
    <div style={{ display: 'grid', gridTemplateColumns: '1fr', gap: 12 }}>
      {APM_INITIATIVES.map(ini => {
        const projs = projectsByInitiative(ini.id);
        return (
          <Card key={ini.id} hoverable onClick={() => goto('initiative', { id: ini.id })}>
            <div style={{ display: 'flex', gap: 24, alignItems: 'flex-start' }}>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 11, color: 'var(--apm-muted)', textTransform: 'uppercase', letterSpacing: '0.12em' }}>{ini.code}</div>
                <div style={{ fontFamily: 'var(--apm-font-display)', fontSize: 22, marginTop: 4, letterSpacing: '-0.01em' }}>{ini.name}</div>
                <div style={{ fontSize: 13, color: 'var(--apm-muted)', marginTop: 6, maxWidth: 580, lineHeight: 1.55 }}>{ini.summary}</div>
                <div style={{ display: 'flex', gap: 6, marginTop: 14, flexWrap: 'wrap' }}>
                  {projs.map(p => <PhasePill key={p.id} phase={p.phase} />)}
                </div>
              </div>
              <div style={{ width: 280 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, marginBottom: 4 }}>
                  <span style={{ color: 'var(--apm-muted)' }}>Health</span>
                  <span style={{ fontWeight: 600 }}>{ini.health}</span>
                </div>
                <HealthBar value={ini.health} />
                <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 12, fontSize: 12, color: 'var(--apm-muted)' }}>
                  <span>{fmtMoney(ini.spent)} / {fmtMoney(ini.budget)}</span>
                  <span>target {ini.target}</span>
                </div>
                <div style={{ marginTop: 12, display: 'flex', alignItems: 'center', gap: 10 }}>
                  <Avatar person={ini.owner} size={22} />
                  <span style={{ fontSize: 12, color: 'var(--apm-muted)' }}>{PERSON_BY_ID[ini.owner].name} · {projs.length} projects</span>
                </div>
              </div>
            </div>
          </Card>
        );
      })}
    </div>
  </Page>
);

// ── PROJECTS LIST ────────────────────────────────────────────────────
const ProjectsPage = ({ goto }) => {
  const [view, setView] = React.useState('table');
  const [phase, setPhase] = React.useState(null);
  const filtered = phase ? APM_PROJECTS.filter(p => p.phase === phase) : APM_PROJECTS;

  return (
    <Page>
      <PageHeader kicker="Projects" title="All projects across the portfolio"
        subtitle="Active, in-flight, and recently archived. Filter by phase or sensitivity. The pipeline strip below shows where every project sits."
        action={<Button variant="primary" icon={<Icon name="plus" size={14} />} onClick={() => goto('__new_project__')}>New project</Button>}
      />

      {/* Phase pipeline strip */}
      <Card style={{ marginBottom: 'var(--apm-section-gap)' }}>
        <div style={{ display: 'flex', gap: 4, overflowX: 'auto' }}>
          {APM_PHASES.map((ph, i) => {
            const cnt = APM_PROJECTS.filter(p => p.phase === ph).length;
            const active = phase === ph;
            return (
              <button key={ph} onClick={() => setPhase(active ? null : ph)} style={{
                flex: 1, minWidth: 90,
                padding: '10px 8px',
                background: active ? 'var(--apm-bg-sunken)' : 'transparent',
                border: '1px solid ' + (active ? 'var(--apm-line-strong)' : 'transparent'),
                borderRadius: 'var(--apm-radius)', cursor: 'pointer',
                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
                fontFamily: 'var(--apm-font-body)',
              }}>
                <div style={{ width: '100%', height: 3, background: `var(${APM_PHASE_VAR[ph]})`, borderRadius: 2 }} />
                <div style={{ fontSize: 11.5, color: 'var(--apm-muted)', marginTop: 4, textAlign: 'center', whiteSpace: 'nowrap' }}>{ph}</div>
                <div style={{ fontFamily: 'var(--apm-font-display)', fontSize: 18, color: cnt ? 'var(--apm-ink)' : 'var(--apm-muted-2)' }}>{cnt}</div>
              </button>
            );
          })}
        </div>
      </Card>

      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 16 }}>
        <Tabs value={view} onChange={setView} tabs={[
          { id: 'table', label: 'Table' }, { id: 'board', label: 'Board' },
        ]} style={{ flex: 1 }} />
        {phase && (
          <Badge tone="accent" icon={<Icon name="filter" size={11} />}>
            {phase} <button onClick={() => setPhase(null)} style={{ marginLeft: 4, background: 'transparent', border: 'none', cursor: 'pointer', color: 'inherit' }}><Icon name="x" size={11} /></button>
          </Badge>
        )}
        <Input placeholder="Search projects" prefix={<Icon name="search" size={13} />} style={{ width: 240 }} />
      </div>

      {view === 'table' ? (
        <Card pad={false}>
          <div style={{
            display: 'grid', gridTemplateColumns: '2fr 1fr 0.8fr 0.8fr 1fr 1fr 0.8fr',
            padding: '10px 16px', fontSize: 11, color: 'var(--apm-muted)',
            textTransform: 'uppercase', letterSpacing: '0.1em', borderBottom: '1px solid var(--apm-line)',
          }}>
            <div>Project</div><div>Initiative</div><div>Phase</div><div>Health</div><div>Owner</div><div>Sensitivity</div><div>Target</div>
          </div>
          {filtered.map((p, i, a) => (
            <div key={p.id} onClick={() => goto('project', { id: p.id })} style={{
              display: 'grid', gridTemplateColumns: '2fr 1fr 0.8fr 0.8fr 1fr 1fr 0.8fr',
              padding: 'var(--apm-row-pad) var(--apm-card-pad)', alignItems: 'center', cursor: 'pointer',
              borderBottom: i < a.length - 1 ? '1px solid var(--apm-line)' : 'none',
              transition: 'background .1s',
            }}
              onMouseEnter={e => e.currentTarget.style.background = 'var(--apm-bg-sunken)'}
              onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
              <div>
                <div style={{ fontSize: 13.5, fontWeight: 600 }}>{p.name}</div>
                <div style={{ fontSize: 11.5, color: 'var(--apm-muted)' }}>{p.code}</div>
              </div>
              <div style={{ fontSize: 12.5, color: 'var(--apm-muted)' }}>{INI_BY_ID[p.initiative].name}</div>
              <PhasePill phase={p.phase} />
              <HealthDot value={p.health} />
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <Avatar person={p.owner} size={22} />
                <span style={{ fontSize: 12, color: 'var(--apm-muted)' }}>{PERSON_BY_ID[p.owner].name.split(' ')[0]}</span>
              </div>
              <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
                {p.sensitivity.map(s => <SensitivityTag key={s} id={s} />)}
              </div>
              <div style={{ fontSize: 12, color: 'var(--apm-muted)' }}>{p.target}</div>
            </div>
          ))}
        </Card>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12, overflowX: 'auto' }}>
          {['Intake','Design','IT Review','Security','HIPAA/PII','Cost & Ops','RA/QA','UAT','Go-Live','Active'].map(ph => {
            const items = APM_PROJECTS.filter(p => p.phase === ph);
            return (
              <div key={ph} style={{ background: 'var(--apm-bg-sunken)', borderRadius: 'var(--apm-radius-lg)', padding: 10, minHeight: 200 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 8 }}>
                  <span style={{ width: 8, height: 8, borderRadius: '50%', background: `var(${APM_PHASE_VAR[ph]})` }} />
                  <div style={{ fontSize: 12, fontWeight: 600 }}>{ph}</div>
                  <div style={{ marginLeft: 'auto', fontSize: 11, color: 'var(--apm-muted)' }}>{items.length}</div>
                </div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--apm-inner-gap)' }}>
                  {items.map(p => (
                    <Card key={p.id} hoverable onClick={() => goto('project', { id: p.id })} style={{ padding: 10 }}>
                      <div style={{ fontSize: 12.5, fontWeight: 600, lineHeight: 1.3 }}>{p.name}</div>
                      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 8 }}>
                        <Avatar person={p.owner} size={20} />
                        <HealthDot value={p.health} />
                      </div>
                    </Card>
                  ))}
                </div>
              </div>
            );
          })}
        </div>
      )}
    </Page>
  );
};

// ── PROJECT DETAIL — variant A (gates-first) ────────────────────────
const ProjectDetail = ({ id, tab = 'overview', variant = 'a', goto }) => {
  const p = PROJ_BY_ID[id] || APM_PROJECTS[0];
  const ini = INI_BY_ID[p.initiative];
  const [activeTab, setActiveTab] = React.useState(tab);
  const phaseIdx = APM_PHASES.indexOf(p.phase);

  const tabs = [
    { id: 'overview', label: 'Overview' },
    { id: 'gates', label: 'Phase gates', count: 3 },
    { id: 'tickets', label: 'Tickets', count: p.openTickets },
    { id: 'components', label: 'Components', count: p.components.length },
    { id: 'team', label: 'Team' },
    { id: 'docs', label: 'Documents' },
  ];

  if (variant === 'b') return <ProjectDetailB p={p} ini={ini} activeTab={activeTab} setActiveTab={setActiveTab} tabs={tabs} phaseIdx={phaseIdx} goto={goto} />;

  return (
    <Page>
      <PageHeader
        kicker={<><a onClick={() => goto('initiative', { id: ini.id })} style={{ color: 'var(--apm-muted)', cursor: 'pointer', textDecoration: 'underline', textUnderlineOffset: 2 }}>{ini.name}</a> · {p.code}</>}
        title={p.name}
        subtitle={p.summary}
        meta={<>
          <PhasePill phase={p.phase} />
          <HealthDot value={p.health} />
          <span style={{ fontSize: 12, color: 'var(--apm-muted)' }}>· updated {p.updated}</span>
          <span style={{ fontSize: 12, color: 'var(--apm-muted)' }}>· target {p.target}</span>
          {p.sensitivity.map(s => <SensitivityTag key={s} id={s} />)}
        </>}
        action={<div style={{ display: 'flex', gap: 8 }}>
          <Button variant="outline" icon={<Icon name="layers" size={14} />} onClick={() => goto('project', { id, variant: 'b' })}>Compact view</Button>
          <Button variant="primary" icon={<Icon name="flag" size={14} />}>Submit gate</Button>
        </div>}
      />

      {/* Phase pipeline */}
      <Card style={{ marginBottom: 'var(--apm-section-gap)' }}>
        <div style={{ fontSize: 11, color: 'var(--apm-muted)', textTransform: 'uppercase', letterSpacing: '0.12em', marginBottom: 12 }}>Phase pipeline</div>
        <div style={{ display: 'flex', gap: 4 }}>
          {APM_PHASES.slice(0, 10).map((ph, i) => {
            const passed = i < phaseIdx;
            const current = i === phaseIdx;
            return (
              <div key={ph} style={{ flex: 1 }}>
                <div style={{
                  height: 6, borderRadius: 3,
                  background: passed ? 'var(--apm-ok)' : current ? `var(${APM_PHASE_VAR[ph]})` : 'var(--apm-bg-sunken)',
                  border: current ? '1px solid var(--apm-ink)' : 'none',
                }} />
                <div style={{
                  fontSize: 10.5, marginTop: 6, textAlign: 'center',
                  color: current ? 'var(--apm-ink)' : 'var(--apm-muted-2)',
                  fontWeight: current ? 600 : 400,
                }}>{ph}</div>
              </div>
            );
          })}
        </div>
      </Card>

      <Tabs tabs={tabs} value={activeTab} onChange={setActiveTab} style={{ marginBottom: 'var(--apm-section-gap)' }} />

      {activeTab === 'overview' && <ProjectOverviewTab p={p} ini={ini} goto={goto} />}
      {activeTab === 'gates' && <ProjectGatesTab p={p} phaseIdx={phaseIdx} />}
      {activeTab === 'tickets' && <ProjectTicketsTab p={p} goto={goto} />}
      {activeTab === 'components' && <ProjectComponentsTab p={p} goto={goto} />}
      {activeTab === 'team' && <ProjectTeamTab p={p} />}
      {activeTab === 'docs' && <ProjectDocsTab p={p} />}
    </Page>
  );
};

const ProjectOverviewTab = ({ p, ini, goto }) => (
  <div style={{ display: 'grid', gridTemplateColumns: '1.5fr 1fr', gap: 24 }}>
    <div>
      <SectionHeading kicker="Now" title="What we're working on" level={3} />
      <Card>
        <div style={{ fontSize: 14, lineHeight: 1.6 }}>
          We're closing out the RA/QA review with two open conditions: <strong>(1)</strong> evidence that the consent ledger
          covers ML-training scope retroactively and <strong>(2)</strong> a routing plan for adverse-event signals
          surfaced by the model. Both have owners; no scope changes.
        </div>
        <div style={{ display: 'flex', gap: 8, marginTop: 16 }}>
          <Button size="sm" variant="primary" icon={<Icon name="file" size={13} />}>Open response doc</Button>
          <Button size="sm" variant="ghost">View 7 prior gate responses</Button>
        </div>
      </Card>

      <div style={{ marginTop: 'var(--apm-section-gap)' }}>
        <SectionHeading kicker="Risks & blockers" title="Open" level={3} />
        <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--apm-inner-gap)' }}>
          <InboxRow icon="flag" tone="risk" title="Consent migration may need a re-prompt window" meta="raised by Jenna · 2 days · owner Priya" action={<Button size="sm" variant="ghost">Open</Button>} />
          <InboxRow icon="branch" tone="warn" title="Telemetry SDK 4.0 RC2 has a 0.2% packet drop bug in EU region" meta="raised by Kira · 4h · owner Kira" action={<Button size="sm" variant="ghost">Open</Button>} />
        </div>
      </div>

      <div style={{ marginTop: 'var(--apm-section-gap)' }}>
        <SectionHeading kicker="Activity" title="Recent" level={3} />
        <Card pad={false}>
          <div style={{ padding: '0 var(--apm-card-pad)' }}>
            {APM_ACTIVITY.slice(0, 5).map((a, i) => <ActivityRow key={i} a={a} />)}
          </div>
        </Card>
      </div>
    </div>
    <div>
      <SectionHeading kicker="Stats" title="Progress" level={3} />
      <Card>
        <div style={{ display: 'grid', gap: 16 }}>
          <Stat label="Progress" value={p.progress + '%'} sub={p.health.replace('-', ' ')} tone={p.health === 'on-track' ? 'ok' : p.health === 'at-risk' ? 'warn' : 'risk'} />
          <Stat label="Spend" value={fmtMoney(p.spent)} sub={`of ${fmtMoney(p.budget)} (${pct(p.spent, p.budget)}%)`} />
          <Stat label="Open tickets" value={p.openTickets} sub={`${p.blockers || 0} blockers`} />
          <Stat label="Risks" value={p.risks} />
        </div>
      </Card>

      <div style={{ marginTop: 'var(--apm-section-gap)' }}>
        <SectionHeading kicker="People" title="Owners" level={3} />
        <Card>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--apm-inner-gap)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <Avatar person={p.owner} size={32} />
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 13, fontWeight: 600 }}>{PERSON_BY_ID[p.owner].name}</div>
                <div style={{ fontSize: 11.5, color: 'var(--apm-muted)' }}>Project Owner</div>
              </div>
            </div>
            {p.raqa && (
              <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <Avatar person={p.raqa} size={32} />
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 600 }}>{PERSON_BY_ID[p.raqa].name}</div>
                  <div style={{ fontSize: 11.5, color: 'var(--apm-muted)' }}>RA/QA</div>
                </div>
              </div>
            )}
          </div>
        </Card>
      </div>
    </div>
  </div>
);

const ProjectGatesTab = ({ p, phaseIdx }) => (
  <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--apm-inner-gap)' }}>
    {APM_PHASES.slice(0, 10).map((ph, i) => {
      const passed = i < phaseIdx;
      const current = i === phaseIdx;
      const future = i > phaseIdx;
      return (
        <Card key={ph} accent={current}>
          <div style={{ display: 'flex', gap: 16, alignItems: 'flex-start' }}>
            <div style={{
              width: 36, height: 36, borderRadius: 8,
              background: passed ? 'var(--apm-ok-soft)' : current ? `color-mix(in oklab, var(${APM_PHASE_VAR[ph]}) 30%, var(--apm-bg-2))` : 'var(--apm-bg-sunken)',
              color: passed ? 'var(--apm-ok)' : current ? 'var(--apm-ink)' : 'var(--apm-muted)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontFamily: 'var(--apm-font-display)', fontWeight: 600, flexShrink: 0,
            }}>{passed ? <Icon name="check" size={16} /> : i + 1}</div>
            <div style={{ flex: 1 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <div style={{ fontFamily: 'var(--apm-font-display)', fontSize: 17, letterSpacing: '-0.005em' }}>{ph}</div>
                {passed && <Badge tone="ok" size="sm">Passed</Badge>}
                {current && <Badge tone="warn" size="sm" dot>Active · 2 conditions</Badge>}
                {future && <Badge tone="neutral" size="sm">Locked</Badge>}
              </div>
              <div style={{ fontSize: 12.5, color: 'var(--apm-muted)', marginTop: 4 }}>
                {passed && `Cleared ${i + 2} weeks ago · signed by ${PERSON_BY_ID[p.owner].name}`}
                {current && 'In review by Jenna Rowe · 2 conditions outstanding · target close: tomorrow'}
                {future && 'Will activate when prior gate clears'}
              </div>
              {current && (
                <div style={{ marginTop: 14, padding: 14, background: 'var(--apm-bg-sunken)', borderRadius: 'var(--apm-radius)' }}>
                  <div style={{ fontSize: 11, color: 'var(--apm-muted)', textTransform: 'uppercase', letterSpacing: '0.1em', marginBottom: 8 }}>Conditions</div>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--apm-inner-gap)' }}>
                    <div style={{ display: 'flex', gap: 8, alignItems: 'flex-start' }}>
                      <input type="checkbox" style={{ marginTop: 3 }} />
                      <div style={{ flex: 1, fontSize: 13 }}>Provide evidence that consent_ledger covers ML-training scope retroactively. <span style={{ color: 'var(--apm-muted)' }}>owner: Priya · due tomorrow</span></div>
                    </div>
                    <div style={{ display: 'flex', gap: 8, alignItems: 'flex-start' }}>
                      <input type="checkbox" style={{ marginTop: 3 }} />
                      <div style={{ flex: 1, fontSize: 13 }}>Document adverse-event routing path from model output to PMS dashboard. <span style={{ color: 'var(--apm-muted)' }}>owner: Jenna · due Fri</span></div>
                    </div>
                  </div>
                  <div style={{ display: 'flex', gap: 8, marginTop: 14 }}>
                    <Button size="sm" variant="primary">Submit response</Button>
                    <Button size="sm" variant="outline">Request extension</Button>
                  </div>
                </div>
              )}
            </div>
          </div>
        </Card>
      );
    })}
  </div>
);

const ProjectTicketsTab = ({ p, goto }) => {
  const tix = APM_TICKETS.filter(t => t.project === p.id);
  if (!tix.length) return <EmptyState icon={<Icon name="tickets" size={28} />} title="No open tickets" body="When a clinic, RA/QA reviewer, or component owner opens a ticket against this project it will show up here." />;
  return (
    <Card pad={false}>
      {tix.map((t,i,a) => (
        <div key={t.id} onClick={() => goto('tickets', { id: t.id })} style={{ display: 'grid', gridTemplateColumns: '60px 1fr 100px 80px 80px', padding: 'var(--apm-row-pad) var(--apm-card-pad)', alignItems: 'center', gap: 12, cursor: 'pointer', borderBottom: i<a.length-1?'1px solid var(--apm-line)':'none' }}
          onMouseEnter={e => e.currentTarget.style.background = 'var(--apm-bg-sunken)'} onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
          <Badge tone={t.priority === 'P1' ? 'risk' : t.priority === 'P2' ? 'warn' : 'neutral'} size="sm">{t.priority}</Badge>
          <div>
            <div style={{ fontSize: 13.5, fontWeight: 500 }}>{t.title}</div>
            <div style={{ fontSize: 11.5, color: 'var(--apm-muted)', marginTop: 2 }}>opened by {PERSON_BY_ID[t.from].name} · {t.age}</div>
          </div>
          <Badge tone={t.status === 'open' ? 'warn' : 'info'} size="sm" dot>{t.status}</Badge>
          {t.assignee ? <Avatar person={t.assignee} size={22} /> : <span style={{ fontSize: 12, color: 'var(--apm-muted-2)' }}>—</span>}
          <div style={{ fontSize: 12, color: 'var(--apm-muted)' }}>{t.id}</div>
        </div>
      ))}
    </Card>
  );
};

const ProjectComponentsTab = ({ p, goto }) => (
  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 12 }}>
    {p.components.map(cid => {
      const c = COMP_BY_ID[cid];
      return (
        <Card key={cid} hoverable onClick={() => goto('components', { id: cid })}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 14, fontWeight: 600 }}>{c.name}</div>
              <div style={{ fontSize: 11.5, color: 'var(--apm-muted)', fontFamily: 'var(--apm-font-mono)' }}>{c.version}</div>
              <div style={{ fontSize: 12.5, color: 'var(--apm-muted)', marginTop: 8, lineHeight: 1.5 }}>{c.summary}</div>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--apm-inner-gap)', alignItems: 'flex-end' }}>
              <Badge tone={c.stability === 'GA' ? 'ok' : c.stability === 'Beta' ? 'warn' : 'info'} size="sm">{c.stability}</Badge>
              <Avatar person={c.owner} size={20} />
            </div>
          </div>
        </Card>
      );
    })}
  </div>
);

const ProjectTeamTab = ({ p }) => (
  <Card>
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 16 }}>
      {[p.owner, p.raqa, 'p_kira', 'p_alex', 'p_diego'].filter(Boolean).map(pid => (
        <div key={pid} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <Avatar person={pid} size={36} />
          <div>
            <div style={{ fontSize: 13.5, fontWeight: 600 }}>{PERSON_BY_ID[pid].name}</div>
            <div style={{ fontSize: 11.5, color: 'var(--apm-muted)' }}>{PERSON_BY_ID[pid].title}</div>
          </div>
        </div>
      ))}
    </div>
  </Card>
);

const ProjectDocsTab = ({ p }) => (
  <Card>
    <EmptyState icon={<Icon name="file" size={28} />} title="No documents linked" body="Link spec docs, pen-test reports, RA/QA evidence, and CER files. They'll be visible to all gate reviewers automatically." action={<Button variant="primary" size="sm" icon={<Icon name="upload" size={14} />}>Upload</Button>} />
  </Card>
);

// ── PROJECT DETAIL — variant B (timeline-first) ─────────────────────
const ProjectDetailB = ({ p, ini, activeTab, setActiveTab, tabs, phaseIdx, goto }) => (
  <Page>
    <div style={{ display: 'grid', gridTemplateColumns: '320px 1fr', gap: 24, alignItems: 'flex-start' }}>
      {/* Left rail */}
      <div style={{ position: 'sticky', top: 84 }}>
        <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.14em', color: 'var(--apm-muted)', marginBottom: 6 }}>{ini.name} · {p.code}</div>
        <h1 style={{ fontFamily: 'var(--apm-font-display)', fontWeight: 400, fontSize: 26, lineHeight: 1.15, margin: 0, letterSpacing: '-0.01em' }}>{p.name}</h1>
        <div style={{ fontSize: 13, color: 'var(--apm-muted)', marginTop: 10, lineHeight: 1.5 }}>{p.summary}</div>

        <div style={{ marginTop: 20, padding: 14, background: 'var(--apm-bg-2)', border: '1px solid var(--apm-line)', borderRadius: 'var(--apm-radius-lg)' }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--apm-inner-gap)' }}>
            <div><PhasePill phase={p.phase} /></div>
            <div><HealthDot value={p.health} /></div>
            <div style={{ fontSize: 12 }}>
              <div style={{ color: 'var(--apm-muted)', marginBottom: 2 }}>Owner</div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <Avatar person={p.owner} size={20} />
                {PERSON_BY_ID[p.owner].name}
              </div>
            </div>
            <div style={{ fontSize: 12 }}>
              <div style={{ color: 'var(--apm-muted)', marginBottom: 2 }}>Target</div>
              <div>{p.target}</div>
            </div>
            <div style={{ fontSize: 12 }}>
              <div style={{ color: 'var(--apm-muted)', marginBottom: 4 }}>Sensitivity</div>
              <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>{p.sensitivity.map(s => <SensitivityTag key={s} id={s} />)}</div>
            </div>
          </div>
        </div>

        <div style={{ marginTop: 16, display: 'flex', flexDirection: 'column', gap: 'var(--apm-inner-gap)' }}>
          <Button variant="primary" icon={<Icon name="flag" size={14} />}>Submit gate</Button>
          <Button variant="outline" icon={<Icon name="layers" size={14} />} onClick={() => goto('project', { id: p.id, variant: 'a' })}>Switch to dashboard</Button>
        </div>
      </div>

      {/* Right — vertical timeline of phases */}
      <div>
        <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.14em', color: 'var(--apm-muted)', marginBottom: 16 }}>Lifecycle</div>
        <div style={{ position: 'relative', paddingLeft: 36 }}>
          <div style={{ position: 'absolute', left: 14, top: 8, bottom: 8, width: 2, background: 'var(--apm-line)' }} />
          {APM_PHASES.slice(0, 10).map((ph, i) => {
            const passed = i < phaseIdx; const current = i === phaseIdx;
            return (
              <div key={ph} style={{ position: 'relative', marginBottom: 18 }}>
                <div style={{
                  position: 'absolute', left: -28, top: 4,
                  width: 16, height: 16, borderRadius: '50%',
                  background: passed ? 'var(--apm-ok)' : current ? `var(${APM_PHASE_VAR[ph]})` : 'var(--apm-bg-2)',
                  border: '2px solid var(--apm-card)',
                  boxShadow: '0 0 0 1px ' + (passed ? 'var(--apm-ok)' : current ? 'var(--apm-ink)' : 'var(--apm-line-2)'),
                }} />
                <Card>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <div style={{ fontFamily: 'var(--apm-font-display)', fontSize: 16 }}>{ph}</div>
                    {passed && <Badge tone="ok" size="sm">Passed</Badge>}
                    {current && <Badge tone="warn" dot size="sm">Active</Badge>}
                  </div>
                  {current && <div style={{ fontSize: 12.5, color: 'var(--apm-muted)', marginTop: 6 }}>2 outstanding conditions · in review by Jenna Rowe</div>}
                  {passed && <div style={{ fontSize: 12, color: 'var(--apm-muted-2)', marginTop: 4 }}>Cleared {i + 2}w ago</div>}
                </Card>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  </Page>
);

// ── INITIATIVES LIST ─────────────────────────────────────────────────
const InitiativesPage = ({ goto }) => (
  <Page>
    <PageHeader kicker="Initiatives" title="Strategic bets and how they roll up"
      subtitle="Each initiative groups projects, has a single owner and sponsor, and tracks against OKRs."
      action={<Button variant="primary" icon={<Icon name="plus" size={14} />}>New initiative</Button>}
    />
    <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--apm-inner-gap)' }}>
      {APM_INITIATIVES.map(ini => {
        const projs = projectsByInitiative(ini.id);
        return (
          <Card key={ini.id} hoverable onClick={() => goto('initiative', { id: ini.id })}>
            <div style={{ display: 'flex', gap: 24, alignItems: 'flex-start' }}>
              <div style={{ flex: 1.5 }}>
                <div style={{ fontSize: 11, color: 'var(--apm-muted)', textTransform: 'uppercase', letterSpacing: '0.12em' }}>{ini.code}</div>
                <div style={{ fontFamily: 'var(--apm-font-display)', fontSize: 22, marginTop: 4, letterSpacing: '-0.01em' }}>{ini.name}</div>
                <div style={{ fontSize: 13, color: 'var(--apm-muted)', marginTop: 6, lineHeight: 1.55 }}>{ini.summary}</div>
              </div>
              <div style={{ width: 200 }}>
                <div style={{ fontSize: 11, color: 'var(--apm-muted)', marginBottom: 8 }}>OKRs</div>
                {ini.okrs.map(o => (
                  <div key={o.id} style={{ marginBottom: 10 }}>
                    <div style={{ fontSize: 12, marginBottom: 4, lineHeight: 1.4 }}>{o.text}</div>
                    <HealthBar value={o.progress} height={4} />
                  </div>
                ))}
              </div>
              <div style={{ width: 240 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, marginBottom: 4 }}>
                  <span style={{ color: 'var(--apm-muted)' }}>Health</span>
                  <span style={{ fontWeight: 600 }}>{ini.health}</span>
                </div>
                <HealthBar value={ini.health} />
                <div style={{ fontSize: 12, color: 'var(--apm-muted)', marginTop: 12 }}>{projs.length} projects · {fmtMoney(ini.spent)} / {fmtMoney(ini.budget)}</div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 8 }}>
                  <Avatar person={ini.owner} size={20} />
                  <span style={{ fontSize: 12, color: 'var(--apm-muted)' }}>{PERSON_BY_ID[ini.owner].name}</span>
                </div>
              </div>
            </div>
          </Card>
        );
      })}
    </div>
  </Page>
);

// ── INITIATIVE DETAIL — variant A (rollup) and B (storyboard) ──────
const InitiativeDetail = ({ id, goto, variant = 'a' }) => {
  const ini = INI_BY_ID[id] || APM_INITIATIVES[0];
  const projs = projectsByInitiative(ini.id);

  if (variant === 'b') return (
    <Page max={920}>
      <PageHeader
        kicker={`${ini.code} · Storyboard`}
        title={ini.name}
        subtitle={ini.summary}
        action={<Button variant="outline" icon={<Icon name="layers" size={14} />} onClick={() => goto('initiative', { id, variant: 'a' })}>Rollup view</Button>}
      />
      <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--apm-inner-gap)' }}>
        {ini.okrs.map((o, i) => (
          <Card key={o.id}>
            <div style={{ display: 'flex', alignItems: 'flex-start', gap: 14 }}>
              <div style={{ width: 40, fontFamily: 'var(--apm-font-display)', fontSize: 32, color: 'var(--apm-muted-2)' }}>{i+1}</div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.14em', color: 'var(--apm-muted)' }}>OKR · target {o.target}</div>
                <div style={{ fontFamily: 'var(--apm-font-display)', fontSize: 22, marginTop: 4, letterSpacing: '-0.01em' }}>{o.text}</div>
                <div style={{ marginTop: 14 }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, marginBottom: 4 }}>
                    <span style={{ color: 'var(--apm-muted)' }}>Progress</span>
                    <span style={{ fontWeight: 600 }}>{o.progress}%</span>
                  </div>
                  <HealthBar value={o.progress} />
                </div>
                <div style={{ marginTop: 12, fontSize: 12, color: 'var(--apm-muted)' }}>
                  Backed by: {projs.slice(0,3).map(p => p.name).join(', ')}
                </div>
              </div>
            </div>
          </Card>
        ))}
      </div>
    </Page>
  );

  return (
    <Page>
      <PageHeader kicker={ini.code} title={ini.name} subtitle={ini.summary}
        meta={<>
          <HealthDot value={ini.status} />
          <span style={{ fontSize: 12, color: 'var(--apm-muted)' }}>· target {ini.target}</span>
          <span style={{ fontSize: 12, color: 'var(--apm-muted)' }}>· {fmtMoney(ini.spent)} of {fmtMoney(ini.budget)}</span>
        </>}
        action={<Button variant="outline" icon={<Icon name="book" size={14} />} onClick={() => goto('initiative', { id, variant: 'b' })}>Storyboard view</Button>}
      />

      <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 24 }}>
        <div>
          <SectionHeading kicker="OKRs" title="Outcomes we're tracking" level={3} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--apm-inner-gap)' }}>
            {ini.okrs.map(o => (
              <Card key={o.id}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
                  <div style={{ fontSize: 14, fontWeight: 500 }}>{o.text}</div>
                  <div style={{ fontFamily: 'var(--apm-font-display)', fontSize: 22, color: o.progress >= 60 ? 'var(--apm-ok)' : o.progress >= 30 ? 'var(--apm-warn)' : 'var(--apm-risk)' }}>{o.progress}%</div>
                </div>
                <div style={{ marginTop: 10 }}><HealthBar value={o.progress} /></div>
                <div style={{ fontSize: 11.5, color: 'var(--apm-muted)', marginTop: 8 }}>target {o.target}</div>
              </Card>
            ))}
          </div>

          <div style={{ marginTop: 'var(--apm-section-gap)' }}>
            <SectionHeading kicker="Projects" title="Rolling up to this initiative" level={3} />
            <Card pad={false}>
              {projs.map((p, i) => (
                <div key={p.id} onClick={() => goto('project', { id: p.id })} style={{
                  display: 'grid', gridTemplateColumns: '2fr 1fr 0.8fr 0.8fr 1fr',
                  padding: 'var(--apm-row-pad) var(--apm-card-pad)', alignItems: 'center', cursor: 'pointer',
                  borderBottom: i < projs.length - 1 ? '1px solid var(--apm-line)' : 'none',
                }}
                  onMouseEnter={e => e.currentTarget.style.background = 'var(--apm-bg-sunken)'}
                  onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                  <div>
                    <div style={{ fontSize: 13.5, fontWeight: 600 }}>{p.name}</div>
                    <div style={{ fontSize: 11.5, color: 'var(--apm-muted)' }}>{p.code}</div>
                  </div>
                  <PhasePill phase={p.phase} />
                  <HealthDot value={p.health} />
                  <Avatar person={p.owner} size={22} />
                  <div style={{ fontSize: 12, color: 'var(--apm-muted)', textAlign: 'right' }}>{p.target}</div>
                </div>
              ))}
            </Card>
          </div>
        </div>

        <div>
          <SectionHeading kicker="Investment" title="Spend" level={3} />
          <Card>
            <Stat label="FY budget" value={fmtMoney(ini.budget)} sub={`${pct(ini.spent, ini.budget)}% spent`} />
            <div style={{ marginTop: 14 }}><HealthBar value={pct(ini.spent, ini.budget)} /></div>
            <div style={{ fontSize: 12.5, color: 'var(--apm-muted)', marginTop: 12 }}>
              Spend tracking on plan. Projected to land at {fmtMoney(Math.round(ini.spent * 2.4))} EOY.
            </div>
          </Card>

          <div style={{ marginTop: 'var(--apm-section-gap)' }}>
            <SectionHeading kicker="People" title="Owners" level={3} />
            <Card>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--apm-inner-gap)' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                  <Avatar person={ini.owner} size={32} />
                  <div><div style={{ fontSize: 13, fontWeight: 600 }}>{PERSON_BY_ID[ini.owner].name}</div>
                  <div style={{ fontSize: 11.5, color: 'var(--apm-muted)' }}>Initiative Owner</div></div>
                </div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                  <Avatar person={ini.sponsor} size={32} />
                  <div><div style={{ fontSize: 13, fontWeight: 600 }}>{PERSON_BY_ID[ini.sponsor].name}</div>
                  <div style={{ fontSize: 11.5, color: 'var(--apm-muted)' }}>Executive Sponsor</div></div>
                </div>
              </div>
            </Card>
          </div>

          <div style={{ marginTop: 'var(--apm-section-gap)' }}>
            <SectionHeading kicker="Activity" title="Recent" level={3} />
            <Card pad={false}>
              <div style={{ padding: '0 var(--apm-card-pad)' }}>
                {APM_ACTIVITY.slice(0, 4).map((a, i) => <ActivityRow key={i} a={a} />)}
              </div>
            </Card>
          </div>
        </div>
      </div>
    </Page>
  );
};

Object.assign(window, { PortfolioPage, ProjectsPage, ProjectDetail, InitiativesPage, InitiativeDetail });
