// Audit — upload, analyze, interactive report with annotated overlay
const AuditFlow = ({ showToast }) => {
  const isMobile = useIsMobile();
  // stages: queue | upload | analyzing | report
  const [stage, setStage] = React.useState("queue");
  const [activeFinding, setActiveFinding] = React.useState(0);
  const [progress, setProgress] = React.useState(0);
  const [analysisStep, setAnalysisStep] = React.useState(0);
  // Live audit state
  const [file, setFile] = React.useState(null);            // { name, size, dataUrl }
  const [result, setResult] = React.useState(null);        // server response or null
  const [auditError, setAuditError] = React.useState(null);
  const [dragOver, setDragOver] = React.useState(false);
  const fileInputRef = React.useRef(null);
  const [dims, setDims] = React.useState({
    regulatory: true, wcag: true, brand: true, claims: true, privacy: false, localization: false,
  });

  const queue = [
    { id: "AUD-2104", name: "Veltrox HCP — Email v3", type: "Email · 1024×2400", up: "2h ago", who: "Maya Park", st: "warn", score: 78, issues: { c: 2, m: 4 }, status: "Needs review" },
    { id: "AUD-2103", name: "Acme.com / Therapeutic areas", type: "Web · responsive", up: "5h ago", who: "James O'Connor", st: "crit", score: 64, issues: { c: 3, m: 6 }, status: "Action required" },
    { id: "AUD-2102", name: "Veltrox patient leaflet", type: "Print · A5", up: "yesterday", who: "Amelia Chen", st: "ok", score: 91, issues: { c: 0, m: 1 }, status: "Approved" },
    { id: "AUD-2101", name: "Cardiometabolic banner set", type: "Display · 12 sizes", up: "2d ago", who: "Maya Park", st: "ok", score: 88, issues: { c: 0, m: 2 }, status: "Approved" },
    { id: "AUD-2100", name: "Investor day deck (Q2)", type: "Deck · 32 slides", up: "3d ago", who: "James O'Connor", st: "warn", score: 82, issues: { c: 1, m: 5 }, status: "In review" },
  ];

  const analysisSteps = [
    "Extracting text and visual elements…",
    "Cross-referencing FDA fair-balance requirements…",
    "Checking ISI placement and prominence…",
    "Running WCAG 2.2 contrast and hit-target checks…",
    "Comparing against Acme brand system v4.2.1…",
    "Flagging unsubstantiated efficacy claims…",
    "Generating governance report…",
  ];

  // While analyzing, animate the progress bar + step text indeterminately.
  // The actual transition to "report" is driven by runAudit() once the API returns.
  React.useEffect(() => {
    if (stage !== "analyzing") return;
    setProgress(0); setAnalysisStep(0);
    const start = Date.now();
    const tick = setInterval(() => {
      const elapsed = Date.now() - start;
      // Easing: rises fast then slows, asymptotes to ~92 until result lands.
      const p = Math.min(92, 92 * (1 - Math.exp(-elapsed / 8000)));
      setProgress(p);
      const stepIdx = Math.min(analysisSteps.length - 1, Math.floor((elapsed / 1200)));
      setAnalysisStep(stepIdx);
    }, 120);
    return () => clearInterval(tick);
  }, [stage]);

  const fileToDataUrl = (f) => new Promise((resolve, reject) => {
    const r = new FileReader();
    r.onload = () => resolve(r.result);
    r.onerror = () => reject(r.error);
    r.readAsDataURL(f);
  });

  const acceptFile = async (f) => {
    if (!f) return;
    if (!f.type.startsWith("image/")) {
      setAuditError("Please upload an image (PNG, JPG, WebP).");
      return;
    }
    if (f.size > 10 * 1024 * 1024) {
      setAuditError("Image is over 10 MB. Try a smaller export.");
      return;
    }
    setAuditError(null);
    const dataUrl = await fileToDataUrl(f);
    setFile({ name: f.name, size: f.size, type: f.type, dataUrl });
  };

  const useSample = async () => {
    setAuditError(null);
    try {
      const res = await fetch("uploads/CleanShot 2026-04-28 at 09.28.22.png");
      const blob = await res.blob();
      const dataUrl = await fileToDataUrl(blob);
      setFile({ name: "Sample asset.png", size: blob.size, type: blob.type, dataUrl });
    } catch (e) {
      setAuditError("Couldn't load the sample image.");
    }
  };

  const runAudit = async () => {
    if (!file) return;
    setAuditError(null);
    setResult(null);
    setStage("analyzing");
    try {
      const selected = Object.entries(dims).filter(([, v]) => v).map(([k]) => k);
      const res = await fetch("api/audit", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ image: file.dataUrl, dimensions: selected, audience: "HCP", market: "US" }),
      });
      if (!res.ok) {
        const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
        throw new Error(body.error || `Audit failed: ${res.status}`);
      }
      const data = await res.json();
      setResult(data);
      setActiveFinding(0);
      setStage("report");
    } catch (e) {
      setAuditError(e.message || "Audit failed.");
      setStage("upload");
    }
  };

  const cannedFindings = [
    { id: "F-01", sev: "crit",  cat: "Regulatory",   axis: "FDA fair balance", title: "Important Safety Information not visually prominent",
      desc: "The ISI block is rendered at 11px on dark gray, below the 50% prominence ratio required by 21 CFR §202.1(e)(5). FDA enforcement letters cite reduced font weight as a primary failure mode.",
      cite: "21 CFR §202.1(e)(5) · FDA Bad Ad letter 2024-038", marker: { x: 38, y: 72 }, refs: ["Fair Balance Standard §3.2"] },
    { id: "F-02", sev: "crit",  cat: "Regulatory",   axis: "Claim substantiation", title: "Efficacy claim lacks NCT-linked citation",
      desc: "“Proven to reduce cardiovascular events by up to 47%” — no clinical trial reference visible. Pharma promotional materials must cite source within 1 viewport of the claim.",
      cite: "PhRMA Code §4.1 · OPDP Guidance 2022", marker: { x: 22, y: 28 }, refs: ["Claim Substantiation Policy"] },
    { id: "F-03", sev: "warn",  cat: "Accessibility", axis: "WCAG 2.2 AA · 1.4.3", title: "Headline contrast 3.8:1 on accent background",
      desc: "Coral accent #FF5A4E vs. paper #F5F3EE measures 3.8:1. Below 4.5:1 minimum for 18px body type. Increase weight to 600+ or shift to ink #0E0E10.",
      cite: "WCAG 2.2 SC 1.4.3 Contrast (Minimum)", marker: { x: 64, y: 18 } },
    { id: "F-04", sev: "warn",  cat: "Accessibility", axis: "WCAG 2.2 AA · 2.5.8", title: "CTA hit target 38×38px, below 44px minimum",
      desc: "“Talk to a rep” button on the patient leaflet measures 38×38px. WCAG 2.2 SC 2.5.8 requires 24×24 minimum, with 44×44 strongly recommended for medical audiences with motor impairment.",
      cite: "WCAG 2.2 SC 2.5.8 Target Size (Minimum)", marker: { x: 78, y: 56 } },
    { id: "F-05", sev: "info",  cat: "Brand",         axis: "Acme DS v4.2.1",      title: "Heading uses Helvetica Neue — system spec is Söhne Halbfett",
      desc: "Detected font fallback. The Acme design system mandates Söhne Halbfett for H1/H2 across HCP and patient surfaces.",
      cite: "Acme DS · Type token h1.fontFamily", marker: { x: 22, y: 12 } },
    { id: "F-06", sev: "info",  cat: "Brand",         axis: "Acme DS v4.2.1",      title: "Coral accent at 92% saturation — token expects 88%",
      desc: "Used color is #FF4A3E. Brand token --accent-primary resolves to #FF5A4E at the time of audit.",
      cite: "Acme DS · color.accent.primary", marker: { x: 50, y: 44 } },
    { id: "F-07", sev: "info",  cat: "Localization",  axis: "Multi-market",        title: "EU market copy missing reimbursement footnote",
      desc: "When localized for DE/FR/IT, this asset will require the standard reimbursement disclosure (EFPIA Code §7).",
      cite: "EFPIA Code of Practice §7", marker: { x: 50, y: 84 } },
  ];

  const sevColor = (s) => s === "crit" ? "var(--crit)" : s === "warn" ? "var(--warn)" : "var(--muted)";

  // ───────────────────────────── QUEUE ─────────────────────────────
  if (stage === "queue") {
    return (
      <div style={{ padding: isMobile ? "20px 16px 60px" : "36px 36px 80px", maxWidth: 1500 }}>
        <div style={{ display: "flex", flexDirection: isMobile ? "column" : "row", justifyContent: "space-between", alignItems: isMobile ? "stretch" : "flex-end", gap: isMobile ? 16 : 0, marginBottom: isMobile ? 24 : 32 }}>
          <div>
            <div className="eyebrow">Audit</div>
            <h1 className="h-section" style={{ marginTop: 6 }}>Governance, <span style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", color: "var(--accent)" }}>at speed</span>.</h1>
            <p style={{ color: "var(--muted)", maxWidth: 640, marginTop: 10, fontSize: 15 }}>
              Upload any design — email, web page, leaflet, deck, banner — and Graphite's regulatory intelligence checks it against FDA, EMA, MHRA standards, your brand system, accessibility, and claim substantiation in under 15 minutes.
            </p>
          </div>
          <button className="btn btn-primary" onClick={()=>setStage("upload")}>
            <Icon name="upload" size={14}/> New audit
          </button>
        </div>

        {/* Stat strip */}
        <div className="card chamfer-tr" style={{ padding: 0, marginBottom: 24, display: "grid", gridTemplateColumns: isMobile ? "repeat(2, 1fr)" : "repeat(4, 1fr)" }}>
          {[
            { k: "127", lbl: "Audits this quarter", sub: "+34 vs. last Q" },
            { k: "94", lbl: "Avg. score", sub: "Target ≥ 90" },
            { k: "12 min", lbl: "Median turnaround", sub: "Industry: 4 days" },
            { k: "2.1×", lbl: "Time-to-approval", sub: "vs. manual review" },
          ].map((s, i) => {
            const lastInRow = isMobile ? (i % 2 === 1) : (i === 3);
            const lastRow = isMobile ? (i >= 2) : true;
            return (
              <div key={i} style={{
                padding: isMobile ? "18px 18px" : "22px 26px",
                borderRight: !lastInRow ? "1px solid var(--line)" : "none",
                borderBottom: !lastRow ? "1px solid var(--line)" : "none",
              }}>
                <div className="eyebrow">{s.lbl}</div>
                <div style={{ fontSize: isMobile ? 24 : 30, fontWeight: 500, letterSpacing: "-0.02em", marginTop: 6 }}>{s.k}</div>
                <div style={{ fontSize: 12, color: "var(--accent)", fontFamily: "var(--font-mono)", marginTop: 4 }}>{s.sub}</div>
              </div>
            );
          })}
        </div>

        <div className="card" style={{ overflow: "hidden" }}>
          <div style={{ padding: "20px 24px", display: "flex", flexDirection: isMobile ? "column" : "row", justifyContent: "space-between", alignItems: isMobile ? "stretch" : "center", gap: isMobile ? 12 : 0, borderBottom: "1px solid var(--line)" }}>
            <div style={{ fontSize: 16, fontWeight: 500 }}>Audit queue</div>
            <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
              <button className="btn btn-quiet" style={{ padding: "6px 12px", fontSize: 12 }}>All teams</button>
              <button className="btn btn-quiet" style={{ padding: "6px 12px", fontSize: 12 }}>Last 30 days</button>
              <button className="btn btn-quiet" style={{ padding: "6px 12px", fontSize: 12 }}><Icon name="filter" size={12}/> Filter</button>
            </div>
          </div>
          <div className="tbl-scroll">
          <table className="tbl">
            <thead>
              <tr><th>Audit ID</th><th>Asset</th><th>Type</th><th>Score</th><th>Findings</th><th>Submitted</th><th>Status</th><th></th></tr>
            </thead>
            <tbody>
              {queue.map((r, i) => (
                <tr key={r.id} onClick={()=>setStage("report")} style={{ cursor: "pointer" }}>
                  <td style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--muted)" }}>{r.id}</td>
                  <td style={{ fontWeight: 500 }}>{r.name}</td>
                  <td style={{ color: "var(--muted)" }}>{r.type}</td>
                  <td>
                    <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                      <strong style={{ color: r.score >= 85 ? "var(--ok)" : r.score >= 65 ? "var(--warn)" : "var(--crit)", fontSize: 16 }}>{r.score}</strong>
                      <div className="sev-bar" style={{ width: 60 }}><div className="sev-bar-fill" style={{ width: `${r.score}%`, background: r.score >= 85 ? "var(--ok)" : r.score >= 65 ? "var(--warn)" : "var(--crit)" }}/></div>
                    </div>
                  </td>
                  <td style={{ fontSize: 13 }}>
                    {r.issues.c > 0 && <span style={{ color: "var(--crit)" }}>{r.issues.c} critical</span>}
                    {r.issues.c > 0 && r.issues.m > 0 && <span style={{ color: "var(--muted)" }}> · </span>}
                    {r.issues.m > 0 && <span style={{ color: "var(--muted)" }}>{r.issues.m} minor</span>}
                  </td>
                  <td style={{ color: "var(--muted)", fontSize: 13 }}>{r.up}<div style={{ fontSize: 11 }}>{r.who}</div></td>
                  <td><span className={`pill pill-${r.st}`}><span className="pill-dot"/>{r.status}</span></td>
                  <td><Icon name="chevron-right" size={14} style={{ color: "var(--muted)" }}/></td>
                </tr>
              ))}
            </tbody>
          </table>
          </div>
        </div>
      </div>
    );
  }

  // ───────────────────────────── UPLOAD ─────────────────────────────
  if (stage === "upload") {
    const dimList = [
      { key: "regulatory",   i: "shield", t: "Regulatory compliance",  d: "FDA, EMA, MHRA fair-balance, ISI, claim substantiation" },
      { key: "wcag",         i: "wcag",   t: "Accessibility",          d: "WCAG 2.2 AA — contrast, hit targets, semantics" },
      { key: "brand",        i: "brand",  t: "Brand consistency",      d: "Acme Design System v4.2.1 — type, color, spacing" },
      { key: "claims",       i: "alert",  t: "Medical accuracy flags", d: "Unsubstantiated claims, missing CT references" },
      { key: "privacy",      i: "lock",   t: "Privacy & PII",          d: "GDPR, HIPAA surfaces, patient data handling" },
      { key: "localization", i: "globe",  t: "Localization readiness", d: "EU/UK/US/APAC market-specific disclosures" },
    ];
    const anyDim = Object.values(dims).some(Boolean);
    return (
      <div style={{ padding: isMobile ? "20px 16px 60px" : "36px 36px 80px", maxWidth: 1100 }}>
        <button onClick={()=>setStage("queue")} style={{ background: "transparent", border: "none", color: "var(--muted)", cursor: "pointer", fontSize: 13, marginBottom: 20, display: "inline-flex", alignItems: "center", gap: 6 }}>← Back to queue</button>
        <h1 className="h-section" style={{ marginBottom: 8 }}>New audit</h1>
        <p style={{ color: "var(--muted)", marginBottom: 32 }}>Drop an image of your design, or use the bundled sample. GPT-4.1 vision audits against your selected dimensions.</p>

        <input ref={fileInputRef} type="file" accept="image/png,image/jpeg,image/webp,image/gif" style={{ display: "none" }}
          onChange={(e) => acceptFile(e.target.files?.[0])}/>

        {file ? (
          <div className="card" style={{ padding: 18, display: "flex", gap: 18, alignItems: "center", flexWrap: "wrap" }}>
            <img src={file.dataUrl} alt={file.name} style={{ width: 96, height: 96, objectFit: "cover", borderRadius: 8, border: "1px solid var(--line)", flexShrink: 0 }}/>
            <div style={{ flex: 1, minWidth: 200 }}>
              <div style={{ fontSize: 15, fontWeight: 500, wordBreak: "break-word" }}>{file.name}</div>
              <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 4, fontFamily: "var(--font-mono)" }}>
                {(file.size / 1024).toFixed(1)} KB · {file.type}
              </div>
            </div>
            <div style={{ display: "flex", gap: 8 }}>
              <button className="btn btn-quiet" onClick={()=>fileInputRef.current?.click()}>Replace</button>
              <button className="btn btn-quiet" onClick={()=>setFile(null)}>Clear</button>
            </div>
          </div>
        ) : (
          <div className={`dropzone ${dragOver ? "active" : ""}`}
            onClick={()=>fileInputRef.current?.click()}
            onDragOver={(e)=>{ e.preventDefault(); setDragOver(true); }}
            onDragLeave={()=>setDragOver(false)}
            onDrop={(e)=>{ e.preventDefault(); setDragOver(false); acceptFile(e.dataTransfer.files?.[0]); }}>
            <div style={{ width: 56, height: 56, borderRadius: 14, background: "var(--bone)", display: "grid", placeItems: "center", margin: "0 auto 16px" }}>
              <Icon name="upload" size={22}/>
            </div>
            <div style={{ fontSize: 18, fontWeight: 500, letterSpacing: "-0.01em" }}>Drop your design here</div>
            <p style={{ color: "var(--muted)", fontSize: 13, margin: "6px 0 0" }}>PNG, JPG, WebP, GIF · up to 10 MB</p>
            <div style={{ display: "flex", justifyContent: "center", gap: 10, marginTop: 22, flexWrap: "wrap" }}>
              <button className="btn btn-primary" onClick={(e)=>{e.stopPropagation(); fileInputRef.current?.click();}}>Choose file</button>
              <button className="btn btn-quiet" onClick={(e)=>{e.stopPropagation(); useSample();}}>Use sample</button>
            </div>
          </div>
        )}

        {auditError && (
          <div style={{ marginTop: 16, padding: "12px 16px", border: "1px solid color-mix(in oklch, var(--crit) 40%, var(--line))", background: "color-mix(in oklch, var(--crit) 6%, var(--paper))", color: "var(--crit)", borderRadius: 8, fontSize: 13, display: "flex", gap: 10, alignItems: "flex-start" }}>
            <Icon name="alert" size={16} style={{ flexShrink: 0, marginTop: 2 }}/>
            <span>{auditError}</span>
          </div>
        )}

        <div style={{ marginTop: 32 }}>
          <div className="eyebrow" style={{ marginBottom: 12 }}>Audit dimensions</div>
          <div style={{ display: "grid", gridTemplateColumns: isMobile ? "1fr" : "repeat(2, 1fr)", gap: 10 }}>
            {dimList.map((d) => (
              <label key={d.key} className="card" style={{ padding: 16, display: "flex", gap: 14, cursor: "pointer", alignItems: "flex-start" }}>
                <input type="checkbox" checked={!!dims[d.key]}
                  onChange={(e)=>setDims(prev => ({ ...prev, [d.key]: e.target.checked }))}
                  style={{ marginTop: 4, accentColor: "var(--accent)" }}/>
                <Icon name={d.i} size={18} style={{ marginTop: 2 }}/>
                <div>
                  <div style={{ fontWeight: 500 }}>{d.t}</div>
                  <div style={{ fontSize: 12, color: "var(--muted)" }}>{d.d}</div>
                </div>
              </label>
            ))}
          </div>
        </div>

        <div style={{ marginTop: 32, display: "flex", gap: 12, justifyContent: "flex-end", flexWrap: "wrap" }}>
          <button className="btn btn-quiet" onClick={()=>setStage("queue")}>Cancel</button>
          <button className="btn btn-primary" disabled={!file || !anyDim} onClick={runAudit}
            style={{ opacity: (!file || !anyDim) ? 0.5 : 1, cursor: (!file || !anyDim) ? "not-allowed" : "pointer" }}>
            Run audit <Icon name="arrow-right" size={13}/>
          </button>
        </div>
      </div>
    );
  }

  // ───────────────────────────── ANALYZING ─────────────────────────────
  if (stage === "analyzing") {
    return (
      <div style={{ minHeight: "calc(100vh - 64px)", display: "grid", placeItems: "center", padding: isMobile ? "32px 20px" : 48 }}>
        <div style={{ maxWidth: 720, width: "100%", textAlign: "center" }}>
          <div style={{ position: "relative", width: 280, height: 360, margin: "0 auto 36px", borderRadius: 14, background: "var(--paper)", border: "1px solid var(--line)", overflow: "hidden" }}>
            <div style={{ position: "absolute", inset: 16, background: "var(--bone)", borderRadius: 6, opacity: 0.6 }}/>
            <div style={{ position: "absolute", left: 28, top: 32, width: 140, height: 14, background: "var(--ink)", borderRadius: 3 }}/>
            <div style={{ position: "absolute", left: 28, top: 56, width: 200, height: 8, background: "var(--line)", borderRadius: 3 }}/>
            <div style={{ position: "absolute", left: 28, top: 72, width: 180, height: 8, background: "var(--line)", borderRadius: 3 }}/>
            <div style={{ position: "absolute", left: 28, top: 110, width: 224, height: 100, background: "var(--ink)", opacity: 0.1, borderRadius: 6 }}/>
            <div style={{ position: "absolute", left: 28, bottom: 60, width: 100, height: 8, background: "var(--accent)", borderRadius: 3 }}/>
            <div style={{ position: "absolute", left: 28, bottom: 40, width: 220, height: 6, background: "var(--line)", borderRadius: 3 }}/>
            <div style={{ position: "absolute", left: 28, bottom: 28, width: 160, height: 6, background: "var(--line)", borderRadius: 3 }}/>
            {/* scan line */}
            <div style={{
              position: "absolute", left: 0, right: 0, height: "30%",
              background: "linear-gradient(180deg, transparent, color-mix(in oklch, var(--accent) 35%, transparent), transparent)",
              animation: "scan 1.6s linear infinite"
            }}/>
          </div>

          <div className="eyebrow eyebrow-coral" style={{ marginBottom: 12 }}>● Analyzing</div>
          <h2 className="h-section" style={{ marginBottom: 12 }}>Cross-referencing against <span style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", color: "var(--accent)" }}>2,400+</span> regulations</h2>
          <p style={{ color: "var(--muted)", marginBottom: 28, fontFamily: "var(--font-mono)", fontSize: 13, minHeight: 20 }}>{analysisSteps[analysisStep]}</p>

          <div style={{ width: "100%", height: 4, background: "var(--line)", borderRadius: 99, overflow: "hidden", maxWidth: 480, margin: "0 auto" }}>
            <div style={{ height: "100%", background: "var(--accent)", width: `${progress}%`, transition: "width 0.15s linear" }}/>
          </div>
          <div style={{ marginTop: 12, fontSize: 12, color: "var(--muted)", fontFamily: "var(--font-mono)" }}>Calling GPT-4.1 vision · {Math.round(progress)}%</div>
        </div>
      </div>
    );
  }

  // ───────────────────────────── REPORT ─────────────────────────────
  // When result is set we ALWAYS use the live LLM data — no fallback to
  // canned, even if the model returned zero findings. Canned data is only
  // shown for queue-row clicks where no audit has actually been run.
  const isLive = !!result;
  const findings = isLive ? (result.findings || []) : cannedFindings;
  const reportScore = isLive ? result.score : 78;
  const reportSummary = isLive ? result.summary : "Conditional pass";
  const reportAxes = isLive ? (result.axes || []).map(a => ({ l: a.label, v: a.score, n: a.note })) : [
    { l: "Regulatory · FDA", v: 62, n: "2 critical" },
    { l: "Accessibility · WCAG 2.2", v: 84, n: "2 minor" },
    { l: "Brand · Acme DS", v: 88, n: "2 minor" },
    { l: "Claim substantiation", v: 70, n: "1 critical" },
    { l: "Localization", v: 92, n: "1 info" },
  ];
  const critCount = findings.filter(f => f.sev === "crit").length;
  const summaryPill = reportSummary === "Approved" ? "ok" : reportSummary === "Action required" ? "crit" : "warn";
  const af = findings[Math.min(activeFinding, findings.length - 1)] || findings[0];
  const previewSrc = isLive && file ? file.dataUrl : null;
  return (
    <div>
      {/* Report header */}
      <div style={{ padding: isMobile ? "20px 16px" : "28px 36px", borderBottom: "1px solid var(--line)", background: "var(--paper)", display: "flex", flexDirection: isMobile ? "column" : "row", justifyContent: "space-between", alignItems: isMobile ? "stretch" : "flex-start", gap: isMobile ? 16 : 24 }}>
        <div>
          <button onClick={()=>{ setResult(null); setStage("queue"); }} style={{ background: "transparent", border: "none", color: "var(--muted)", cursor: "pointer", fontSize: 13, marginBottom: 8, display: "inline-flex", alignItems: "center", gap: 6, padding: 0 }}>← All audits</button>
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 6, flexWrap: "wrap" }}>
            <span className="eyebrow" style={{ fontFamily: "var(--font-mono)", color: "var(--muted)" }}>{isLive ? "AUD-LIVE" : "AUD-2104"}</span>
            <span className={`pill pill-${summaryPill}`}><span className="pill-dot"/>{reportSummary}</span>
            <span style={{ fontSize: 12, color: "var(--muted)" }}>{isLive ? `Audited just now · gpt-4.1 · ${findings.length} findings` : "Audited 3 minutes ago · v3 · 5,200ms"}</span>
          </div>
          <h1 style={{ fontSize: isMobile ? 22 : 30, fontWeight: 500, letterSpacing: "-0.02em", margin: 0 }}>{isLive ? (file?.name || "Uploaded asset") : "Veltrox HCP — Email v3"}</h1>
          <div style={{ fontSize: 13, color: "var(--muted)", marginTop: 4 }}>{isLive ? `Audited via GPT-4.1 vision · ${result.meta?.dimensions?.join(", ") || ""}` : "Submitted by Maya Park · for HCP audience · US market · Email · 1024×2400"}</div>
        </div>
        <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
          <button className="btn btn-quiet"><Icon name="copy" size={13}/> Share link</button>
          <button className="btn btn-quiet" onClick={()=>showToast("PDF report exported")}><Icon name="download" size={13}/> Export PDF</button>
          <button className="btn btn-primary">Approve & sign-off <Icon name="check" size={13}/></button>
        </div>
      </div>

      {/* Report body */}
      <div style={{ display: "grid", gridTemplateColumns: isMobile ? "1fr" : "320px 1fr 360px", minHeight: isMobile ? "auto" : "calc(100vh - 64px)", background: "var(--paper)" }}>
        {/* LEFT — score + axes */}
        <div style={{ borderRight: isMobile ? "none" : "1px solid var(--line)", borderBottom: isMobile ? "1px solid var(--line)" : "none", padding: isMobile ? "20px 16px" : 28, background: "var(--bone)" }}>
          <div style={{ display: "flex", justifyContent: "center", marginBottom: 20 }}>
            <ScoreDonut score={reportScore} size={150} label="Governance" />
          </div>
          <div style={{ textAlign: "center", marginBottom: 24 }}>
            <div style={{ fontSize: 14, fontWeight: 500 }}>{reportSummary}</div>
            <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 4 }}>{critCount > 0 ? `Resolve ${critCount} critical finding${critCount === 1 ? "" : "s"} to ship` : "No critical findings"}</div>
          </div>

          <div className="eyebrow" style={{ marginBottom: 12 }}>By dimension</div>
          {reportAxes.map((a, i) => (
            <div key={i} style={{ marginBottom: 14 }}>
              <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12, marginBottom: 5 }}>
                <span>{a.l}</span>
                <span style={{ color: "var(--muted)", fontFamily: "var(--font-mono)" }}>{a.v}</span>
              </div>
              <div className="sev-bar"><div className="sev-bar-fill" style={{ width: `${a.v}%`, background: a.v >= 85 ? "var(--ok)" : a.v >= 65 ? "var(--warn)" : "var(--crit)" }}/></div>
              <div style={{ fontSize: 11, color: "var(--muted)", marginTop: 4 }}>{a.n}</div>
            </div>
          ))}

          <hr className="hr" style={{ margin: "20px 0" }}/>
          <div className="eyebrow" style={{ marginBottom: 10 }}>Audited against</div>
          <div style={{ display: "flex", flexDirection: "column", gap: 6, fontSize: 12, color: "var(--muted)" }}>
            {(isLive
              ? (result.meta?.dimensions || []).flatMap(d => ({
                  regulatory:   ["· FDA 21 CFR §202 (promotion)", "· OPDP Bad Ad guidance"],
                  claims:       ["· PhRMA Code §4.1", "· FTC truth-in-advertising"],
                  wcag:         ["· WCAG 2.2 AA"],
                  brand:        ["· Brand system tokens"],
                  localization: ["· EFPIA Code §7", "· ABPI / ANSM / FSA / PMDA"],
                  privacy:      ["· GDPR Art. 9", "· HIPAA Privacy Rule"],
                }[d] || []))
              : ["· FDA 21 CFR §202 (promotion)", "· OPDP Bad Ad guidance 2024", "· PhRMA Code §4.1", "· WCAG 2.2 AA", "· Acme Design System v4.2.1", "· Acme Voice & Tone v3"]
            ).map((s, i) => <span key={i}>{s}</span>)}
          </div>
        </div>

        {/* CENTER — annotated preview */}
        <div style={{ padding: isMobile ? "20px 16px" : 36, background: "var(--bone)", display: "grid", placeItems: "start center" }}>
          <div style={{ position: "relative", width: "100%", maxWidth: 480, background: "var(--paper)", border: "1px solid var(--line)", borderRadius: 8, overflow: "hidden", boxShadow: "0 8px 32px rgba(0,0,0,0.06)" }}>
            {previewSrc ? (
              <img src={previewSrc} alt={file?.name || "Audited asset"} style={{ display: "block", width: "100%", height: "auto" }}/>
            ) : (
              <>
                {/* Mock email design (canned demo) */}
                <div style={{ background: "var(--ink)", padding: "24px 28px" }}>
                  <Logo light size={14}/>
                </div>
                <div style={{ padding: "32px 28px 40px" }}>
                  <div className="eyebrow" style={{ color: "var(--accent)", marginBottom: 12 }}>FOR HEALTHCARE PROFESSIONALS</div>
                  <div style={{ fontSize: 30, fontWeight: 500, letterSpacing: "-0.02em", lineHeight: 1.05 }}>
                    Veltrox® reduces<br/>major CV events by<br/><span style={{ color: "var(--accent)" }}>up to 47%</span>.
                  </div>
                  <p style={{ color: "var(--muted)", fontSize: 13, marginTop: 18 }}>In adults with established cardiovascular disease and elevated lipoprotein(a). See full prescribing information.</p>
                  <div className="placeholder-img" style={{ height: 140, marginTop: 20, borderRadius: 6 }}>HCP HERO IMAGERY</div>
                  <div style={{ marginTop: 20 }}>
                    <button style={{ background: "var(--accent)", color: "var(--ink)", border: "none", padding: "8px 14px", borderRadius: 99, fontSize: 12, fontWeight: 500 }}>Talk to a rep</button>
                  </div>
                  <div style={{ marginTop: 28, fontSize: 9, color: "var(--muted-2)", lineHeight: 1.5, borderTop: "1px solid var(--line)", paddingTop: 14 }}>
                    <strong>IMPORTANT SAFETY INFORMATION.</strong> Veltrox is contraindicated in patients with known hypersensitivity to any component. Adverse reactions include myalgia, elevated transaminases, and rare cases of rhabdomyolysis. See full prescribing info at veltrox.com/pi.
                  </div>
                </div>
              </>
            )}
            {/* Markers overlay */}
            {findings.map((f, i) => (
              <div key={f.id}
                onClick={()=>setActiveFinding(i)}
                className={`marker ${f.sev}`}
                style={{
                  left: `${f.marker.x}%`, top: `${f.marker.y}%`,
                  transform: i === activeFinding ? "scale(1.2)" : "scale(1)",
                  zIndex: i === activeFinding ? 10 : 5,
                  boxShadow: i === activeFinding ? "0 0 0 4px color-mix(in oklch, var(--accent) 30%, transparent), 0 4px 12px rgba(0,0,0,0.18)" : undefined,
                }}>{i + 1}</div>
            ))}
          </div>
        </div>

        {/* RIGHT — findings list / detail */}
        <div style={{ borderLeft: isMobile ? "none" : "1px solid var(--line)", borderTop: isMobile ? "1px solid var(--line)" : "none", display: "flex", flexDirection: "column", maxHeight: isMobile ? "none" : "calc(100vh - 64px - 100px)", overflow: "hidden" }}>
          <div style={{ padding: "20px 24px", borderBottom: "1px solid var(--line)" }}>
            <div className="eyebrow">Findings</div>
            <div style={{ fontSize: 18, fontWeight: 500, marginTop: 4 }}>{findings.length} total · {critCount} critical</div>
          </div>
          <div style={{ overflowY: "auto", flex: 1 }}>
            {findings.length === 0 && (
              <div style={{ padding: "32px 24px", textAlign: "center", color: "var(--muted)", fontSize: 13 }}>
                <Icon name="check" size={20} style={{ color: "var(--ok)", marginBottom: 8 }}/>
                <div style={{ fontWeight: 500, color: "var(--ink)", marginBottom: 4 }}>No issues found</div>
                <div>The model didn't surface anything against the selected dimensions.</div>
              </div>
            )}
            {findings.map((f, i) => (
              <div key={f.id} onClick={()=>setActiveFinding(i)} style={{
                padding: "14px 20px", borderBottom: "1px solid var(--line)",
                cursor: "pointer", borderLeft: i === activeFinding ? "3px solid var(--accent)" : "3px solid transparent",
                background: i === activeFinding ? "var(--bone)" : "transparent",
              }}>
                <div style={{ display: "flex", gap: 10, alignItems: "flex-start" }}>
                  <div style={{
                    width: 22, height: 22, borderRadius: 99, background: sevColor(f.sev), color: f.sev === "info" ? "var(--paper)" : "var(--ink)",
                    display: "grid", placeItems: "center", fontSize: 11, fontFamily: "var(--font-mono)", fontWeight: 600, flexShrink: 0
                  }}>{i + 1}</div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 11, color: sevColor(f.sev), fontFamily: "var(--font-mono)", textTransform: "uppercase", letterSpacing: "0.06em" }}>{f.sev === "crit" ? "Critical" : f.sev === "warn" ? "Minor" : "Info"} · {f.cat}</div>
                    <div style={{ fontSize: 13, fontWeight: 500, marginTop: 2 }}>{f.title}</div>
                    {i === activeFinding && (
                      <div style={{ marginTop: 10, fontSize: 12, color: "var(--muted)", lineHeight: 1.55 }}>
                        {f.evidence && (
                          <div style={{ marginBottom: 10, padding: 10, background: "var(--paper)", border: "1px solid var(--line)", borderLeft: "3px solid var(--accent)", borderRadius: 6, fontSize: 12, color: "var(--ink)", fontStyle: "italic" }}>
                            <span style={{ fontFamily: "var(--font-mono)", fontStyle: "normal", fontSize: 10, color: "var(--accent)", textTransform: "uppercase", letterSpacing: "0.06em", display: "block", marginBottom: 4 }}>Observed</span>
                            {f.evidence}
                          </div>
                        )}
                        {f.desc}
                        <div style={{ marginTop: 10, padding: 10, background: "var(--bone)", borderRadius: 6, fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--ink)" }}>
                          <strong style={{ color: "var(--accent)" }}>Cite:</strong> {f.cite}
                        </div>
                        <div style={{ display: "flex", gap: 6, marginTop: 10 }}>
                          <button className="btn btn-primary" style={{ padding: "6px 12px", fontSize: 11 }}>Auto-fix</button>
                          <button className="btn btn-quiet" style={{ padding: "6px 12px", fontSize: 11 }}>Dismiss</button>
                          <button className="btn btn-quiet" style={{ padding: "6px 12px", fontSize: 11 }}>Discuss</button>
                        </div>
                      </div>
                    )}
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
};

window.AuditFlow = AuditFlow;
