// views_client.jsx — client workflow: Home hub, Run audit (stepper),
// Recommendations (approve assets), Exports, Monitoring.
(function () {
  const { useState, useEffect, useRef } = React;
  const D = window.JS_DATA;
  const S = window.JS_SCORE;
  const r1 = n => Math.round(n);
  const fixForAsset = id => (S.FIXES || []).find(f => f.asset === id) || null;

  // ============================================================ HOME / HUB
  function pipeStage(hasRun, packGenerated) {
    return [
      { name: 'Audit', state: hasRun ? 'done' : 'current', label: hasRun ? 'Complete' : 'Start here' },
      { name: 'Analyze', state: hasRun ? 'done' : 'todo', label: hasRun ? '71 / 100' : 'Pending' },
      { name: 'Generate', state: packGenerated ? 'done' : hasRun ? 'current' : 'todo', label: packGenerated ? '5 assets' : hasRun ? 'Ready' : 'Pending' },
      { name: 'Approve', state: packGenerated ? 'current' : 'todo', label: packGenerated ? '2 / 5 done' : 'Pending' },
      { name: 'Export', state: 'todo', label: 'Pending' },
      { name: 'Monitor', state: 'todo', label: 'Monthly' },
    ];
  }

  function Pipeline({ stages, go }) {
    const map = { Audit: 'run-audit', Analyze: 'results', Generate: 'recommendations', Approve: 'recommendations', Export: 'exports', Monitor: 'monitoring' };
    return (
      <div className="js-pipeline">
        {stages.map((s, i) => (
          <div key={i} className={'js-pipe-step is-' + s.state} onClick={() => go(map[s.name])}>
            <div className="ps-top">
              <span className="js-pipe-num">{s.state === 'done' ? <Icon name="check" size={14} /> : i + 1}</span>
              <span className="js-pipe-name">{s.name}</span>
            </div>
            <div className="js-pipe-state">{s.label}</div>
          </div>
        ))}
      </div>
    );
  }

  function ClientHome({ audit, hasRun, packGenerated, go, prefs, startTour }) {
    const a = audit.analysis;
    const name = (prefs && prefs.name) || 'Tom';
    return (
      <div className="js-view">
        <div className="js-pagehead">
          <div>
            <p className="eyebrow">Welcome back, {name}</p>
            <h1>{hasRun ? 'Your AI-search standing' : 'Let’s find out where you stand'}</h1>
            <p className="sub">{hasRun ? `${audit.clientName || 'This site'} is being scored against backend audit evidence.` : 'Run your first audit to see how AI search engines read and cite your site.'}</p>
          </div>
          <div className="js-head-actions">
            {startTour && <Btn kind="ghost" icon="sparkles" sm onClick={startTour}>Take the tour</Btn>}
            {hasRun ? <Btn icon="gauge" onClick={() => go('results')}>View results</Btn> : <Btn icon="play" onClick={() => go('run-audit')}>Run first audit</Btn>}
          </div>
        </div>

        <div style={{ marginBottom: 24 }}>
          <p className="js-tag" style={{ marginBottom: 10 }}>Your workflow</p>
          <Pipeline stages={pipeStage(hasRun, packGenerated)} go={go} />
        </div>

        {hasRun ? <>
          <div className="js-stats" style={{ marginBottom: 22 }}>
            <Stat k="JiffyScore" v={a.scores.total} sub={'+' + (a.scores.total - a.previous.total) + ' this month'} dir="up" icon="gauge" />
            <Stat k="Citation readiness" v={a.scores.citationReadiness} sub="biggest opportunity" dir="flat" icon="quote" />
            <Stat k="Priority gaps" v={a.gaps.length} sub="2 high impact" dir="flat" icon="target" />
            <Stat k="Local visibility" v={a.scores.localVisibility} sub="strongest area" dir="up" icon="map" />
          </div>

          <div className="js-cols-main">
            <Panel className="js-artback">
              <PanelHead eyebrow="6-month trend" title="Climbing, steadily" desc="No urgency, by design — conviction compounds. Each audit replays the full methodology." />
              <div style={{ padding: '8px 4px' }}><Sparkline data={D.SCORE_HISTORY} h={120} /></div>
              <div className="row" style={{ justifyContent: 'space-between', marginTop: 6 }}>
                {D.SCORE_HISTORY.map(h => <span key={h.date} className="js-tag">{h.date}</span>)}
              </div>
            </Panel>
            <Panel raised>
              <PanelHead title="Next best action" />
              <div className="js-gap sev-high" style={{ background: 'transparent', border: 0, padding: 0 }}>
                <h4>Add FAQ schema</h4>
                <p>The single fastest lift to citation readiness. We’ve already drafted the markup.</p>
              </div>
              <Btn kind="gold" icon="sparkles" onClick={() => go('recommendations')} style={{ marginTop: 6 }}>Review your pack</Btn>
              <hr className="js-divider" />
              <div className="row" style={{ color: 'var(--emerald)', gap: 8 }}><Icon name="shieldCheck" size={16} /><span className="js-tag" style={{ color: 'var(--emerald)' }}>Methodology v3.2 · glass-box</span></div>
            </Panel>
          </div>
        </> : (
          <div className="fr-hero">
            <Panel raised className="js-artback">
              <PanelHead eyebrow="What happens next" title="From URL to a ranked fix pack" desc="One audit, the whole picture — and every number shows its work." />
              <div className="fr-steps">
                {[
                  ['We crawl your site', 'Up to 24 pages, read the way an answer engine reads them — schema, depth, entity signals.'],
                  ['Score across six dimensions', 'Technical, content, entity clarity, AI readiness, citation readiness and local visibility — blended into one JiffyScore.'],
                  ['Draft the fixes', 'The highest-impact gaps come back as ready-to-ship assets you approve, with the projected lift on each.'],
                ].map((s, i) => (
                  <div key={i} className="fr-step">
                    <span className="fr-num">{i + 1}</span>
                    <div className="fr-stepbody"><span className="fr-steplabel">{s[0]}</span><span className="fr-stepdesc">{s[1]}</span></div>
                  </div>
                ))}
              </div>
            </Panel>
            <Panel style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'flex-start', gap: 14 }}>
              <p className="eyebrow">Glass box, always</p>
              <h3 style={{ fontFamily: 'var(--font-display)', fontSize: 26, lineHeight: 1.1, margin: 0, color: 'var(--ink)' }}>No black-box scores. <em style={{ color: 'var(--gold)', fontStyle: 'normal' }}>Ever.</em></h3>
              <p style={{ fontSize: 13.5, color: 'var(--ink-soft)', lineHeight: 1.55, margin: 0 }}>Every figure you’ll see opens to its own reasoning — the factors, the evidence, and a simulator to test fixes before you commit.</p>
              <div className="row" style={{ gap: 8, flexWrap: 'wrap' }}>
                <Btn icon="play" onClick={() => go('run-audit')}>Run your first audit</Btn>
                {startTour && <Btn kind="ghost" sm icon="sparkles" onClick={startTour}>Take the tour</Btn>}
              </div>
            </Panel>
          </div>
        )}
      </div>
    );
  }
  window.ClientHome = ClientHome;

  // ============================================================ RUN AUDIT
  const INDUSTRIES = ['Auto-detect', 'Plumbing', 'Dental', 'Accounting', 'Legal', 'Healthcare', 'Real estate', 'Ecommerce', 'Cybersecurity', 'Construction', 'Education'];
  const CRAWL_PAGES = [
    { url: '/', s: 'ok' }, { url: '/emergency-plumbing', s: 'ok' }, { url: '/blocked-drains', s: 'flag' },
    { url: '/hot-water', s: 'flag' }, { url: '/gas-fitting', s: 'ok' }, { url: '/leak-detection', s: 'flag' },
    { url: '/about', s: 'ok' }, { url: '/reviews', s: 'ok' }, { url: '/contact', s: 'ok' },
  ];

  function RunAudit({ onComplete, go }) {
    const [step, setStep] = useState(0);
    const [form, setForm] = useState({ url: 'https://example.com', client: 'Demo Local Services Co', industry: 'Plumbing', location: 'Sydney, NSW', maxPages: 24 });
    const [running, setRunning] = useState(false);
    const [crawled, setCrawled] = useState(0);
    const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

    useEffect(() => {
      if (!running) return;
      if (crawled >= CRAWL_PAGES.length) { const t = setTimeout(() => onComplete(form), 900); return () => clearTimeout(t); }
      const t = setTimeout(() => setCrawled(c => c + 1), 360);
      return () => clearTimeout(t);
    }, [running, crawled]);

    if (running) {
      return (
        <div className="js-view" style={{ maxWidth: 720 }}>
          <div className="js-pagehead"><div><p className="eyebrow">Auditing</p><h1>Reading your site the way <em>AI does</em></h1>
            <p className="sub">Crawling, extracting entities, and scoring across six dimensions. This usually takes under a minute.</p></div></div>
          <Panel raised className="js-artback">
            <div className="row" style={{ justifyContent: 'space-between', marginBottom: 18 }}>
              <div className="row" style={{ gap: 12 }}><span className="js-spin" /><span style={{ fontWeight: 600, whiteSpace: 'nowrap' }}>{crawled >= CRAWL_PAGES.length ? 'Scoring…' : 'Crawling pages'}</span></div>
              <span className="js-num" style={{ color: 'var(--gold)' }}>{Math.min(crawled, CRAWL_PAGES.length)}/{CRAWL_PAGES.length}</span>
            </div>
            <div className="track" style={{ height: 8, background: 'var(--surface-2)', borderRadius: 99, overflow: 'hidden', marginBottom: 22 }}>
              <div style={{ height: '100%', width: (crawled / CRAWL_PAGES.length * 100) + '%', background: 'var(--lime-gradient)', borderRadius: 99, transition: 'width .35s var(--ease-out-expo)', boxShadow: 'var(--glow-lime)' }} />
            </div>
            <div className="js-rows">
              {CRAWL_PAGES.slice(0, crawled).map((p, i) => (
                <div key={i} className="row" style={{ justifyContent: 'space-between', padding: '9px 14px', background: 'var(--bg-2)', borderRadius: 'var(--r-sm)', border: '1px solid var(--line-soft)', animation: 'js-fade .3s' }}>
                  <span style={{ fontFamily: 'var(--font-mono)', fontSize: 13 }}>{p.url}</span>
                  {p.s === 'flag' ? <Pill tone="amber" dot={false}>Flagged</Pill> : <Pill tone="green" dot={false}>OK</Pill>}
                </div>
              ))}
            </div>
          </Panel>
        </div>
      );
    }

    const steps = ['Website', 'Business', 'Depth'];
    return (
      <div className="js-view" style={{ maxWidth: 760 }}>
        <div className="js-pagehead"><div><p className="eyebrow">New audit</p><h1>Run an <em>AI-search</em> audit</h1>
          <p className="sub">We crawl your public site, identify your business entity, and score how ready you are to be found and cited by answer engines.</p></div></div>

        <div className="seg" style={{ marginBottom: 24 }}>
          {steps.map((s, i) => <button key={s} className={'seg-opt' + (i === step ? ' is-active' : '')} onClick={() => setStep(i)}>{i + 1}. {s}</button>)}
        </div>

        <Panel>
          {step === 0 && <div>
            <div className="field"><label className="field-label">Website URL</label>
              <input className="input" value={form.url} onChange={e => set('url', e.target.value)} placeholder="https://example.com" />
              <span className="field-hint">A public, crawlable site. We respect robots.txt.</span></div>
            <div className="field"><label className="field-label">Business name <span className="js-tag">optional</span></label>
              <input className="input" value={form.client} onChange={e => set('client', e.target.value)} /></div>
          </div>}
          {step === 1 && <div>
            <div className="field"><label className="field-label">Industry</label>
              <div className="chips">{INDUSTRIES.map(ind => <button key={ind} className={'chip' + (form.industry === ind ? ' is-selected' : '')} onClick={() => set('industry', ind)}>{ind}</button>)}</div></div>
            <div className="field" style={{ marginTop: 8 }}><label className="field-label">Primary location</label>
              <input className="input" value={form.location} onChange={e => set('location', e.target.value)} placeholder="Sydney, Melbourne, London…" />
              <span className="field-hint">Sharpens local-visibility scoring and the search-intent map.</span></div>
          </div>}
          {step === 2 && <div>
            <div className="field"><div className="slider-row">
              <div className="slider-head"><span className="slider-name">Max pages to crawl</span><span className="slider-val">{form.maxPages}</span></div>
              <input className="slider-input" type="range" min="5" max="75" value={form.maxPages} onChange={e => set('maxPages', +e.target.value)} />
            </div><span className="field-hint">More pages = deeper analysis. Most small sites are well covered at 20–30.</span></div>
            <div className="js-gap sev-low" style={{ marginTop: 20 }}>
              <h4><Icon name="shieldCheck" size={16} style={{ color: 'var(--emerald)' }} />No surprises</h4>
              <p style={{ margin: 0 }}>One audit run. No background charges, no scarcity timers. You can re-run any time after you make changes.</p>
            </div>
          </div>}
          <div className="row" style={{ justifyContent: 'space-between', marginTop: 26 }}>
            <Btn kind="ghost" sm icon="chevronRight" onClick={() => step === 0 ? go('home') : setStep(step - 1)}>{step === 0 ? 'Cancel' : 'Back'}</Btn>
            {step < 2 ? <Btn icon="arrow" onClick={() => setStep(step + 1)}>Continue</Btn>
              : <Btn kind="gold" icon="play" onClick={() => { setRunning(true); setCrawled(0); }}>Run audit</Btn>}
          </div>
        </Panel>
      </div>
    );
  }
  window.RunAudit = RunAudit;

  // ============================================================ RECOMMENDATIONS
  function Recommendations({ audit, assets, setAssets, packGenerated, onGenerate, go }) {
    const [editing, setEditing] = useState(null);
    const [draftBody, setDraftBody] = useState('');
    const setStatus = async (id, status) => {
      setAssets(as => as.map(a => a.id === id ? { ...a, status } : a));
      if (audit?.id && window.JS_API) {
        try { await window.JS_API.audits.updateAsset(audit.id, id, status); }
        catch (e) { alert('Asset status update failed: ' + e.message); }
      }
    };
    const startEdit = (asset) => { setEditing(asset.id); setDraftBody(asset.body || ''); };
    const cancelEdit = () => { setEditing(null); setDraftBody(''); };
    const saveEdit = async (asset) => {
      setAssets(as => as.map(a => a.id === asset.id ? { ...a, body: draftBody } : a));
      try {
        if (audit?.id) await window.JS_API.audits.updateAsset(audit.id, asset.id, { body: draftBody });
        cancelEdit();
      } catch (e) {
        alert('Asset edit failed: ' + e.message);
      }
    };
    const approved = assets.filter(a => a.status === 'approved').length;

    if (!packGenerated) {
      return <div className="js-view"><div className="js-pagehead"><div><p className="eyebrow">Recommendations</p><h1>Your improvement <em>pack</em></h1>
        <p className="sub">We turn every priority gap into ready-to-ship assets — schema, copy, entity blocks — that you review before anything goes live.</p></div></div>
        <EmptyState icon="sparkles" title="No pack generated yet" desc="Generate an implementation pack from your audit’s priority gaps. Each fix comes as an editable asset you approve or reject."
          action={<Btn kind="gold" icon="sparkles" onClick={onGenerate}>Generate improvement pack</Btn>} /></div>;
    }

    // live pack projection: composite now → composite with every APPROVED fix shipped
    const base = S.simulate([]).composite;
    const approvedFixIds = assets.filter(a => a.status === 'approved').map(a => { const f = fixForAsset(a.id); return f && f.id; }).filter(Boolean);
    const projected = S.simulate(approvedFixIds).composite;
    const gain = r1(projected) - r1(base);

    return (
      <div className="js-view js-view--wide">
        <div className="js-pagehead">
          <div><p className="eyebrow">Recommendations · {assets.length} assets</p><h1>Your improvement <em>pack</em></h1>
            <p className="sub">Approve what you’ll ship. Each asset shows the JiffyScore it’s projected to earn. Nothing is published without your sign-off.</p></div>
          <div className="js-head-actions">
            <Pill tone="green">{approved} approved</Pill>
            <Btn icon="download" onClick={() => go('exports')}>Go to exports</Btn>
          </div>
        </div>

        {/* pack projection bar — the whole point of the loop, made visible */}
        <div className="js-packproj">
          <div className="pp-dialwrap"><ScoreDial value={projected} base={base} label="Projected" size="sm" /></div>
          <div className="pp-body">
            <p className="eyebrow">If you ship what’s approved</p>
            <div className="pp-scoreline">
              <span className="pp-now">{r1(base)}</span>
              <Icon name="arrow" size={20} style={{ color: 'var(--mute)' }} />
              <span className="pp-proj" style={{ color: gain ? 'var(--lime)' : 'var(--ink)' }}>{r1(projected)}</span>
              {gain > 0 && <span className="lf-deltabig">+{gain} JiffyScore</span>}
            </div>
            <p className="pp-note">{gain > 0
              ? <>Approving the remaining high-impact assets would lift you further. The projection updates as you approve or reject.</>
              : <>Approve assets below to project your JiffyScore lift. Each one shows what it’s worth.</>}</p>
          </div>
        </div>

        <div className="js-grid-2">
          {assets.map(asset => {
            const fx = fixForAsset(asset.id);
            const lift = fx ? S.marginalLift(fx.id, []) : 0;
            return (
            <div key={asset.id} className={'js-asset' + (asset.status === 'approved' ? ' is-approved' : asset.status === 'rejected' ? ' is-rejected' : '')}>
              <div className="row" style={{ justifyContent: 'space-between', alignItems: 'flex-start' }}>
                <div><div className="a-type">{asset.type}</div><h4>{asset.title}</h4></div>
                {asset.status === 'approved' ? <Pill tone="green">Approved</Pill> : asset.status === 'rejected' ? <Pill tone="coral">Rejected</Pill> : <Pill tone="amber">Pending</Pill>}
              </div>
              <div className="a-projrow">
                {lift > 0
                  ? <span className="a-lift"><Icon name="trending" size={13} />+{lift.toFixed(1)} JiffyScore projected</span>
                  : <span className="a-lift a-lift--none"><Icon name="check" size={13} />Hygiene fix · keeps you clean</span>}
                {fx && <span className="js-tag">{fx.effort} effort</span>}
              </div>
              {editing === asset.id ? (
                <textarea className="input" value={draftBody} onChange={e => setDraftBody(e.target.value)} style={{ minHeight: 180, resize: 'vertical', fontFamily: 'var(--font-mono)', lineHeight: 1.45 }} />
              ) : (
                <div className="a-body">{asset.body}</div>
              )}
              <div className="a-actions">
                <Btn sm kind={asset.status === 'approved' ? 'primary' : 'ghost'} icon="check" onClick={() => setStatus(asset.id, 'approved')}>Approve</Btn>
                <Btn sm kind="ghost" icon="x" onClick={() => setStatus(asset.id, 'rejected')}>Reject</Btn>
                {editing === asset.id ? <>
                  <Btn sm kind="gold" icon="check" onClick={() => saveEdit(asset)}>Save edit</Btn>
                  <Btn sm kind="ghost" icon="x" onClick={cancelEdit}>Cancel</Btn>
                </> : <Btn sm kind="ghost" icon="code" onClick={() => startEdit(asset)}>Edit</Btn>}
              </div>
            </div>
            );
          })}
        </div>
      </div>
    );
  }
  window.Recommendations = Recommendations;

  // ============================================================ EXPORTS
  function Exports({ assets, packGenerated, go }) {
    const approved = assets.filter(a => a.status === 'approved').length;
    const auditId = D.AUDIT.id;
    const items = [
      { t: 'Full report (HTML)', d: 'Branded, shareable audit with all six dimensions and the why behind each.', icon: 'fileText', tag: 'Always available', path: `/audits/${auditId}/export.html` },
      { t: 'Raw data (JSON)', d: 'The complete audit object — scores, entities, gaps, intents, page findings.', icon: 'code', tag: 'Always available', path: `/audits/${auditId}/export.json` },
      { t: 'Implementation ZIP', d: 'Every approved asset packaged for handoff to your dev or CMS.', icon: 'box', tag: approved + ' assets', path: `/audits/${auditId}/export.zip` },
      { t: 'Citation evidence ZIP', d: 'Screenshots and source records proving where you’re cited today.', icon: 'quote', tag: 'Always available', path: `/audits/${auditId}/citation-evidence.zip` },
      { t: 'WordPress plugin', d: 'Drop-in plugin that applies approved schema and copy.', icon: 'code', tag: 'CMS pack', path: `/audits/${auditId}/integrations/wordpress.zip` },
      { t: 'Shopify theme pack', d: 'Liquid snippets for approved structured data.', icon: 'box', tag: 'CMS pack', path: `/audits/${auditId}/integrations/shopify.zip` },
    ];
    return (
      <div className="js-view">
        <div className="js-pagehead"><div><p className="eyebrow">Exports</p><h1>Take it <em>anywhere</em></h1>
          <p className="sub">Everything JiffyScore produces is exportable — no lock-in. Implementation packs reflect your approved assets.</p></div></div>
        {!packGenerated && <div className="js-gap sev-medium" style={{ marginBottom: 18 }}><h4><Icon name="alert" size={16} style={{ color: 'var(--gold)' }} />Generate a pack first</h4>
          <p style={{ margin: 0 }}>Implementation and CMS exports need approved assets. <span className="js-link-gold" onClick={() => go('recommendations')}>Review recommendations →</span></p></div>}
        <div className="js-grid-3">
          {items.map(it => (
            <Panel key={it.t} className="card--hover" style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
              <div className="row" style={{ justifyContent: 'space-between' }}>
                <div style={{ width: 42, height: 42, borderRadius: 12, background: 'var(--surface-2)', border: '1px solid var(--line-soft)', display: 'grid', placeItems: 'center', color: 'var(--gold)' }}><Icon name={it.icon} /></div>
                <span className="js-tag">{it.tag}</span>
              </div>
              <h4 style={{ fontFamily: 'var(--font-display)', fontSize: 18, margin: 0, color: 'var(--ink)' }}>{it.t}</h4>
              <p style={{ fontSize: 13, color: 'var(--ink-soft)', margin: 0, lineHeight: 1.5, flex: 1 }}>{it.d}</p>
              <Btn sm kind="ghost" icon="download" onClick={() => window.JS_API.download(it.path)}>Download</Btn>
            </Panel>
          ))}
        </div>
      </div>
    );
  }
  window.Exports = Exports;

  // ============================================================ MONITORING
  function Monitoring({ audit, go }) {
    const [status, setStatus] = useState('');
    const createPlan = async () => {
      if (!audit?.id) return setStatus('Run an audit before creating a monitoring plan.');
      try {
        await window.JS_API.growth.createMonitoringPlan(audit.id, { frequency: 'monthly', maxPages: audit.maxPages || 20 });
        setStatus('Monitoring plan created');
      } catch (e) {
        setStatus('Monitoring plan failed: ' + e.message);
      }
    };
    const runPlan = async (planId) => {
      try {
        await window.JS_API.growth.runMonitoringPlan(planId);
        setStatus('Monitoring plan run queued');
      } catch (e) {
        setStatus('Monitoring run failed: ' + e.message);
      }
    };
    return (
      <div className="js-view">
        <div className="js-pagehead"><div><p className="eyebrow">Monitoring</p><h1>Stay <em>cited</em> over time</h1>
          <p className="sub">Re-audit on a schedule and watch your JiffyScore move. Manual runs work without enabling the scheduler.</p></div>
          <Btn icon="plus" onClick={createPlan}>New plan</Btn></div>
        {status && <div className="js-gap sev-low" style={{ marginBottom: 18 }}><p style={{ margin: 0 }}>{status}</p></div>}

        <div className="js-cols-main">
          <Panel className="js-artback">
            <PanelHead eyebrow="JiffyScore over time" title="Up 19 points in 6 months" />
            <div style={{ padding: '8px 4px' }}><Sparkline data={D.SCORE_HISTORY} h={140} /></div>
            <div className="row" style={{ justifyContent: 'space-between', marginTop: 6 }}>{D.SCORE_HISTORY.map(h => <span key={h.date} className="js-tag">{h.date} · {h.total}</span>)}</div>
          </Panel>
          <Panel raised>
            <PanelHead title="This month" />
            <div className="js-stat" style={{ background: 'transparent', border: 0, padding: 0, marginBottom: 14 }}>
              <div className="k"><Icon name="trending" size={14} />Latest change</div><div className="v" style={{ color: 'var(--lime)' }}>+7</div>
              <div className="sub">New reviews + schema rollout</div>
            </div>
            <Btn kind="gold" sm icon="play" onClick={() => go('run-audit')}>Run now</Btn>
          </Panel>
        </div>

        <Panel style={{ marginTop: 18 }}>
          <PanelHead eyebrow="Closed loop" title="What shipped this month"
            desc="Every change pushed live and the JiffyScore it earned at re-audit — proof the work moved the number.">
            <span className="js-scorechip"><span className="sc-ring" style={{ background: 'var(--lime)' }} />+{D.SHIPPED.reduce((s, x) => s + x.earned, 0).toFixed(1)} earned</span>
          </PanelHead>
          <div className="js-ship">
            {D.SHIPPED.map(s => (
              <div key={s.id} className="js-shipitem">
                <div className="si-rail"><span className="si-dot" /></div>
                <div className="si-body">
                  <div className="si-head">
                    <span className="si-label">{s.label}</span>
                    <span className="si-earn">+{s.earned.toFixed(1)}</span>
                  </div>
                  <div className="si-meta"><span className="js-tag">{s.date}</span><span className="js-tag">{s.dim}</span><span className="si-engine">{s.engine}</span></div>
                  <p className="si-detail">{s.detail}</p>
                </div>
              </div>
            ))}
          </div>
        </Panel>

        <Panel style={{ marginTop: 18 }}>
          <PanelHead eyebrow="Active plans" title="Re-audit schedule" />
          <div className="js-rows">
            {D.MONITORING.length ? D.MONITORING.map(m => (
              <div key={m.id} className="js-rowcard" style={{ gridTemplateColumns: 'auto 1fr auto auto auto' }}>
                <div style={{ width: 40, height: 40, borderRadius: 11, background: 'var(--surface-2)', display: 'grid', placeItems: 'center', color: 'var(--gold)', border: '1px solid var(--line-soft)' }}><Icon name="clock" size={18} /></div>
                <div><div className="rc-title">{m.frequency} re-audit</div><div className="rc-sub">Up to {m.maxPages} pages · next {m.nextRun}</div></div>
                <span className="js-scorechip"><span className="sc-ring" style={{ background: 'var(--lime)' }} />+{m.lastDelta}</span>
                <Pill tone="green">{m.status}</Pill>
                <Btn sm kind="ghost" icon="play" onClick={() => runPlan(m.id)}>Run</Btn>
              </div>
            )) : <EmptyState icon="activity" title="No monitoring plans" desc="Create a backend monitoring plan for this audit to schedule or run re-audits." />}
          </div>
        </Panel>
      </div>
    );
  }
  window.Monitoring = Monitoring;

})();
