/* =============================================================================
   VALIORO OS — operating system + client portal (Phase 1 + Phase 2).

   EMPLOYEE (role=employee, or local preview): the deliverable-first OS —
   Deliverables / Frameworks / Methodology / Tools / Operations / Clients / Brand.
   The Clients view is now LIVE: manage each engagement (IRS, valuation, quarter),
   drive the deliverable status board, the 00–11 data room, and view intake.

   CLIENT (role=client): their own portal — Dashboard (IRS + valuation + progress),
   Data Room (the 00–11 folders we deliver into), Intake (the FW-23 forms).

   Auth is config-gated (window.VALIORO_AUTH): runs in local preview mode with no
   login until Supabase keys are added in lib/config.js. In local mode an employee
   can "open the client portal" for any demo client to preview the full experience.

   Data: window.VALIORO_PROGRAM + window.VALIORO_ARTIFACTS (static) ·
         window.VALIORO_PORTAL (data-room folders + intake forms) ·
         window.VALIORO_DATA (the async data layer: seed locally, Supabase remote).
   ========================================================================== */
/* global React, ReactDOM */
const { useState, useEffect, useMemo, useCallback, useRef } = React;

const P = window.VALIORO_PROGRAM || {};
const A = window.VALIORO_ARTIFACTS || { frameworks: {}, methodology: [], operations: [], tools: [], brand: [] };
const AUTH = window.VALIORO_AUTH || { enabled: false };
const D = window.VALIORO_DATA || null;
const PORTAL = window.VALIORO_PORTAL || { DATAROOM_FOLDERS: [], folderById: {}, INTAKE_FORMS: [], formById: {}, PORTAL_NAV: [] };
const DELIVERABLES = P.DELIVERABLES || [];
const FRAMEWORKS = P.FRAMEWORKS || [];
const DISCIPLINES = P.DISCIPLINES || {};
const PILLARS = window.VALIORO_PILLARS || P.PILLARS || {};
const FOLDERS = PORTAL.DATAROOM_FOLDERS;
const FORMS = PORTAL.INTAKE_FORMS;
// the public website is the front door, served at "/" by the platform server
// (serve-platform.js → Launch Valioro.cmd). Absolute so it works from any OS view.
const SITE_HREF = "https://valioro-website.pages.dev/";  // public marketing site (switch to https://valioro.com.br/ once the custom domain is connected)

const EXT_LABEL = { html: "WEB", xlsx: "XLS", docx: "DOC", pptx: "PPT", pdf: "PDF" };
const QUARTERS = [
  { key: "1", tag: "Q1", name: "Strategy & Offer", sub: "Months 1–3 · diagnose, position, price" },
  { key: "2", tag: "Q2", name: "Financial & Valuation", sub: "Months 4–6 · audit-grade books → defensible value" },
  { key: "3", tag: "Q3", name: "Governance & Readiness", sub: "Months 7–9 · make it transactable" },
  { key: "4", tag: "Q4", name: "Investor Materials & Capital", sub: "Months 10–12 · tell it, take it to market" },
  { key: "all", tag: "Spine", name: "Recurring & cross-quarter", sub: "Every month · the connective tissue" },
];
const qkey = q => (q === "all" || q == null ? "all" : String(q));

// The 8 operation rooms (the business operations) + the reference views they draw on.
// Access model: an operator sees only assigned rooms; owner sees all. In local preview
// (no Supabase auth) everything runs as owner, so nothing is hidden yet — the roles /
// ownerOnly metadata activates when employee accounts are turned on. Delivery is the only
// room with a real surface today (the Clients view); the rest open as shells. Full surface
// specs live in Claude Cowork/outputs/company-ops/OS_Employee_Portal_Design.md.
const ROOMS = [
  { id: "demand", label: "Demand Generation", phase: "C", roles: ["demand"],
    purpose: "Steady inbound so Sales always has someone to qualify. The hook is the free mini-IRS.",
    surface: ["Content cadence board — the week's angle: Idea → Drafting → Scheduled → Published, per channel", "Lead inbox — mini-IRS (Typeform) submissions land as captured leads, one-click send to Sales"],
    carries: "Brand assets, the SMM carousel templates, content-angle prompts.",
    handoff: "A captured lead → Sales (Lead stage).",
    today: "Lives in LinkedIn / Typeform today. The OS piece is the lead inbox + a light cadence board." },
  { id: "sales", label: "Sales", phase: "A", roles: ["sales"],
    purpose: "Turn a lead into a signed 12-month client without discounting method or price. The IRS assessment does the selling.",
    surface: ["Pipeline board: Lead → Qualified → Discovery → Assessment → Proposal → Signed", "Deal cards: company, vertical, revenue, source, ICP check, IRS result, proposal status, price, next action", "Assessment stage launches the IRS portal; the score + range attaches to the deal", "On Signed → creates the client in Onboarding + triggers the first invoice in Finance"],
    carries: "Pitch deck (FW-19), objection kit (FW-20), the pricing card, the discovery script.",
    handoff: "Signed → Onboarding + Finance.",
    today: "Nothing yet — the IRS portal stands alone, not attached to a deal. The deep, build-first room." },
  { id: "onboarding", label: "Onboarding", phase: "A", roles: ["onboarding"],
    purpose: "Take a signed client live within 5 business days. Triggers on contract signed AND first payment cleared.",
    surface: ["Per-client onboarding checklist (the SOP-03 steps, tracked)", "Create client + 00–11 data room · billing on · send FW-23 intake · schedule cadence · kickoff · assign pod · set QA gates", "Payment-cleared + intake-received gates: delivery can't start until both are green", "Assign the client to one delivery employee (feeds Delivery scoping)"],
    carries: "FW-23 intake, FW-15 data-room protocol, the kickoff script.",
    handoff: "→ Delivery, when the checklist is complete.",
    today: "The end pieces (client create, data room, intake) exist in Delivery; the checklist, payment gate, and assignment do not." },
  { id: "delivery", label: "Delivery", phase: "A", roles: ["delivery"], live: true,
    purpose: "Produce the quarter's deliverables to standard. Scoped — an operator sees only their assigned client(s)." },
  { id: "success", label: "Client Success", phase: "A", roles: ["success"],
    purpose: "One outcome: the client stays, grows, and refers. Runs on a monthly cycle + renewal windows.",
    surface: ["Relationship cadence — last contact + the 10-day-rule alert, monthly session, check-ins; a who's-overdue list", "MGR delivery — receive the QA'd report from Delivery, add framing, deliver by the 5th, mark sent", "Health — monthly satisfaction / NPS (>8.0), churn-signal flags", "Renewal & expansion — contract dates, 3-month / 30-day windows, step-up off the founder rate", "Advocacy — referrals from month 2, testimonials, case studies → Demand Gen", "Feedback loop — priorities → Delivery; realized outcomes → Product/IP"],
    carries: "MGR template (FW-21), referral script, renewal script.",
    handoff: "Referrals → Demand/Sales; realized data → Product/IP.",
    today: "Only the engagement editor (IRS/valuation) exists. No cadence, health, renewal, or MGR send — second-biggest gap." },
  { id: "partners", label: "Partners", phase: "B", roles: ["partners"],
    purpose: "The referral-partner network — accountants, lawyers, consultants who send qualified leads for a commission. Built: a partner pipeline (potential → onboarding → signed) and per-partner referrals with dates, status, and commission roll-ups." },
  { id: "talent", label: "Talent", phase: "C", roles: ["talent"],
    purpose: "The people who deliver — the 5-per-client moat. Triggers on the cohort funnel (16-week rule) + pod need.",
    surface: ["Cohort funnel — recruiting pipeline (apply → screen → interview → select 5–7), 16-week countdown", "The visa gate — legality confirmed before any flight; blocks pod assignment until green", "Pods & capacity — who's on which client pod, capacity vs demand", "Training library, intern records, offboarding / alumni"],
    carries: "Recruiting templates, the training library, the university MOU, the estágio contract.",
    handoff: "Trained, visa-cleared interns → Delivery.",
    today: "Nothing. Full build waits (interns ~September); the 16-week countdown + visa-gate checklist are worth a stub sooner." },
  { id: "finance", label: "Finance", phase: "B", ownerOnly: true,
    purpose: "The company's money and its legal standing. Owner-only.",
    surface: ["Receivables — per-client invoice status (day-5 recurring): issued / paid / late + chase list", "Compliance calendar — DAS, Fator-R watch, ECD/DEFIS, INPI, CNPJ, your CRNM + intern-visa admin", "Contracts store — client, NDA, estágio, partner", "Cash snapshot — position / runway, the R$15–20k buffer flag, cost-to-deliver vs retainer"],
    carries: "FW-13 Tax & Fator-R, contract templates.",
    handoff: "Clears payment → unblocks Onboarding / Delivery.",
    today: "Nothing. Conta Azul stays the book of record — the OS surface is receivables, the compliance board, and contracts." },
  { id: "product", label: "Product / IP", phase: "B", ownerOnly: true,
    purpose: "The asset every client runs on — defensible accuracy, not software. The moat. Owner-guarded.",
    surface: ["Roadmap / backlog — what to build next, prioritized against accuracy needs", "Comps coverage — library status (40 today), coverage by sector, confidence, stale-comp hygiene", "Recalibration inbox — realized outcomes from Client Success, folded into multiples + score mapping", "The science — methodology, rubric, sectors, engine / portal version status"],
    carries: "The science: methodology, comps, rubric, the engine repo (FW-01/02/03/11).",
    handoff: "Supplies the engine + frameworks to Delivery.",
    today: "The knowledge exists as catalogs (see Reference). No roadmap, comps-coverage, or recalibration surface yet." },
];
const ROOM_BY_ID = {}; ROOMS.forEach(r => { ROOM_BY_ID[r.id] = r; });
// Existing reference/library views — owner-level for now. The depth phase distributes the
// relevant slice of these into the rooms above (no global shelf long-term).
const REFERENCE = [
  { id: "deliverables", label: "Deliverables" },
  { id: "frameworks", label: "Frameworks" },
  { id: "methodology", label: "Methodology" },
  { id: "tools", label: "Tools" },
  { id: "operations", label: "Operations" },
  { id: "brand", label: "Brand" },
];

/* ---------- monoline icon set (replaces emoji — currentColor, 24px grid) --- */
function Icon({ name }) {
  const p = { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.7, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true" };
  switch (name) {
    case "deliverables": return <svg {...p}><rect x="3" y="3" width="7" height="7" rx="1.5" /><rect x="14" y="3" width="7" height="7" rx="1.5" /><rect x="3" y="14" width="7" height="7" rx="1.5" /><rect x="14" y="14" width="7" height="7" rx="1.5" /></svg>;
    case "frameworks": return <svg {...p}><path d="M12 3 21 8 12 13 3 8z" /><path d="M3 12 12 17 21 12" /><path d="M3 16 12 21 21 16" /></svg>;
    case "methodology": return <svg {...p}><circle cx="12" cy="12" r="8.5" /><circle cx="12" cy="12" r="3.2" /></svg>;
    case "tools": return <svg {...p}><circle cx="12" cy="12" r="9" /><path d="M15.6 8.4 13.2 13.2 8.4 15.6 10.8 10.8z" /></svg>;
    case "operations": return <svg {...p}><path d="M4 7h9" /><path d="M19 7h1" /><circle cx="16" cy="7" r="2.3" /><path d="M4 17h3" /><path d="M11 17h9" /><circle cx="9" cy="17" r="2.3" /></svg>;
    case "clients": case "delivery": return <svg {...p}><circle cx="9" cy="8" r="3.2" /><path d="M3.5 19c0-3 2.6-5 5.5-5s5.5 2 5.5 5" /><path d="M16 5.5a3 3 0 0 1 0 6" /><path d="M17.5 14c2 .6 3.5 2.3 3.5 4.6" /></svg>;
    case "demand": return <svg {...p}><path d="M4 10v4a1 1 0 0 0 1 1h2l8 4V5L7 9H5a1 1 0 0 0-1 1z" /><path d="M18 9a3 3 0 0 1 0 6" /></svg>;
    case "sales": return <svg {...p}><path d="M4 5h16l-6 7v6l-4 2v-8z" /></svg>;
    case "onboarding": return <svg {...p}><path d="M13 4h5a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-5" /><path d="M3 12h10" /><path d="M9 8l4 4-4 4" /></svg>;
    case "success": return <svg {...p}><path d="M12 20.5C6.5 16.5 4 13.5 4 10.2 4 7.6 6 6 8.2 6c1.6 0 3 .9 3.8 2.2C12.8 6.9 14.2 6 15.8 6 18 6 20 7.6 20 10.2c0 3.3-2.5 6.3-8 10.3z" /></svg>;
    case "talent": return <svg {...p}><path d="M12 4 2 9l10 5 10-5z" /><path d="M6 11v4c0 1.5 2.7 3 6 3s6-1.5 6-3v-4" /></svg>;
    case "finance": return <svg {...p}><rect x="3" y="6" width="18" height="12" rx="2" /><circle cx="12" cy="12" r="2.6" /></svg>;
    case "product": return <svg {...p}><path d="M12 2.5 20.5 7v10L12 21.5 3.5 17V7z" /><path d="M3.5 7 12 11.6 20.5 7" /><path d="M12 11.6V21.5" /></svg>;
    case "partners": return <svg {...p}><circle cx="6" cy="7" r="2.3" /><circle cx="18" cy="9" r="2.3" /><circle cx="9" cy="18" r="2.3" /><path d="M8 7.7 15.8 8.6M7.7 9 8.6 15.8" /></svg>;
    case "brand": return <svg {...p}><path d="M12 2.5 14.6 9.4 21.5 12 14.6 14.6 12 21.5 9.4 14.6 2.5 12 9.4 9.4z" /></svg>;
    case "dashboard": return <svg {...p}><rect x="4" y="12" width="4" height="8" rx="1" /><rect x="10" y="5" width="4" height="15" rx="1" /><rect x="16" y="9" width="4" height="11" rx="1" /></svg>;
    case "dataroom": case "folder": return <svg {...p}><path d="M3 7.5a2 2 0 0 1 2-2h3.6a2 2 0 0 1 1.4.6l1.4 1.4H19a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" /></svg>;
    case "intake": return <svg {...p}><path d="M4 14v3.5A1.5 1.5 0 0 0 5.5 19h13a1.5 1.5 0 0 0 1.5-1.5V14" /><path d="M12 4v9" /><path d="M8.5 9.5 12 13l3.5-3.5" /></svg>;
    case "eye": return <svg {...p}><path d="M2.5 12S6 5.5 12 5.5 21.5 12 21.5 12 18 18.5 12 18.5 2.5 12 2.5 12z" /><circle cx="12" cy="12" r="3" /></svg>;
    case "doc": return <svg {...p}><path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z" /><path d="M14 3v5h5" /></svg>;
    case "chevron": return <svg {...p}><path d="M6 9l6 6 6-6" /></svg>;
    case "close": return <svg {...p}><path d="M6 6l12 12M18 6L6 18" /></svg>;
    case "check": return <svg {...p}><path d="M5 12.5 10 17.5 19 7" /></svg>;
    case "back": return <svg {...p}><path d="M19 12H5M11 18l-6-6 6-6" /></svg>;
    default: return null;
  }
}
function FileTag({ ext }) { return <span className="os-ftag">{EXT_LABEL[ext] || String(ext || "").toUpperCase()}</span>; }

// Deliverable status vocabulary (matches db check + os-seed).
const DSTATUS = {
  not_started: { label: "Not started", pt: "Não iniciado", cls: "ns" },
  in_progress: { label: "In progress", pt: "Em andamento", cls: "ip" },
  review:      { label: "In review",   pt: "Em revisão",   cls: "rv" },
  delivered:   { label: "Delivered",   pt: "Entregue",     cls: "dl" },
};
const STATUS_ORDER = ["not_started", "in_progress", "review", "delivered"];

/* ---------- formatting + math helpers ----------------------------------- */
function fmtMoney(n) {
  if (n == null || isNaN(n)) return "—";
  const a = Math.abs(n);
  if (a >= 1e6) return "R$ " + (n / 1e6).toFixed(1).replace(".", ",") + " mi";
  if (a >= 1e3) return "R$ " + Math.round(n / 1e3) + " mil";
  return "R$ " + n;
}
function fmtFull(n) {
  if (n == null || isNaN(n)) return "—";
  try { return "R$ " + Number(n).toLocaleString("pt-BR"); } catch (e) { return "R$ " + n; }
}
// Readiness factor from doctrine: (IRS/100)^0.55 — the fraction of the fair-max
// multiple unlocked at a given readiness score.
function readiness(irs) {
  if (irs == null || isNaN(irs) || irs <= 0) return 0;
  return Math.pow(irs / 100, 0.55);
}
function pctDelta(from, to) {
  if (!from || !to) return null;
  return Math.round(((to - from) / from) * 100);
}

/* ---------- async data hook --------------------------------------------- */
function useAsync(fn, deps) {
  const [state, setState] = useState({ loading: true, data: null, error: null });
  const [tick, setTick] = useState(0);
  useEffect(() => {
    let alive = true;
    setState(s => ({ ...s, loading: true }));
    Promise.resolve().then(fn).then(d => { if (alive) setState({ loading: false, data: d, error: null }); })
      .catch(e => { if (alive) setState({ loading: false, data: null, error: e }); });
    return () => { alive = false; };
    // eslint-disable-next-line
  }, (deps || []).concat([tick]));
  const reload = useCallback(() => setTick(t => t + 1), []);
  return { ...state, reload };
}

/* ===================================================================== */
/* PHASE 1 — employee deliverable-first views (unchanged)                */
/* ===================================================================== */
function FileIcons({ files }) {
  if (!files || !files.length) return null;
  return (
    <span className="os-fileicons">
      {files.filter(f => f.ext !== "html").map((f, i) => (
        <a key={i} className="os-fi" href={f.href} target="_blank" rel="noopener" aria-label={f.label + " (" + f.ext + ")"} title={f.label + " (" + f.ext + ")"}>{EXT_LABEL[f.ext] || String(f.ext || "").toUpperCase()}</a>
      ))}
    </span>
  );
}
function FwChip({ fwId }) {
  const f = A.frameworks[fwId];
  if (!f) return <span className="os-chip miss">{fwId}</span>;
  return (
    <span className="os-chipwrap">
      <a className="os-chip" href={f.master || "#"} target="_blank" rel="noopener"><b>{f.code}</b> {f.name}</a>
      <FileIcons files={f.files} />
    </span>
  );
}
function DeliverableCard({ d }) {
  const [open, setOpen] = useState(false);
  const disc = (DISCIPLINES[d.discipline] && DISCIPLINES[d.discipline].label) || d.discipline;
  const irs = d.irs && d.irs.max > 0 ? "+" + d.irs.min + "–" + d.irs.max + " IRS" : (d.recurring ? "recurring" : "");
  return (
    <div className="os-card">
      <div className="os-card-h">
        <span className="os-code">{d.code}</span>
        <span className="os-nm">{d.name}</span>
        <span className="os-disc">{disc}</span>
        {irs ? <span className={"os-irs" + (d.irs && d.irs.max > 0 ? "" : " rec")}>{irs}</span> : null}
      </div>
      {d.tagline ? <div className="os-tag">{d.tagline}</div> : null}
      {d.riskKilled ? <div className="os-kill"><b>Kills:</b> {d.riskKilled}</div> : null}
      <div className="os-bw">
        <span className="os-bwl">Built with</span>
        {(d.fw || []).length ? (d.fw || []).map(id => <FwChip key={id} fwId={id} />) : <span className="os-muted">—</span>}
      </div>
      <button className="os-spec-toggle" onClick={() => setOpen(o => !o)}>{open ? "Hide build spec" : "Build spec"}<span className={"os-chev" + (open ? " open" : "")}><Icon name="chevron" /></span></button>
      {open ? (
        <div className="os-spec">
          {d.purpose ? <p><b>Purpose.</b> {d.purpose}</p> : null}
          {d.valuationImpact ? <p><b>Valuation impact.</b> {d.valuationImpact}</p> : null}
          {d.inputs && d.inputs.length ? (<div><p><b>Inputs (from the client):</b></p><ul>{d.inputs.map((x, i) => <li key={i}>{x}</li>)}</ul></div>) : null}
          {d.structure && d.structure.length ? (<div><p><b>Structure:</b></p><ul>{d.structure.map((x, i) => <li key={i}>{x}</li>)}</ul></div>) : null}
          <p className="os-meta">{d.owner ? "Owner: " + d.owner : ""}{d.estHours ? (d.owner ? "   ·   " : "") + "Est. " + d.estHours : ""}{d.founderHours ? "   ·   Founder " + d.founderHours : ""}</p>
          {d.qa ? <p className="os-qa"><b>QA gate:</b> {d.qa}</p> : null}
        </div>
      ) : null}
    </div>
  );
}
function DeliverablesView() {
  const [q, setQ] = useState("");
  const term = q.trim().toLowerCase();
  const match = d => !term || [d.name, d.tagline, d.code, d.discipline, d.purpose].join(" ").toLowerCase().includes(term);
  return (
    <div>
      <div className="os-view-h">
        <div><h1>Deliverable Library</h1><p>Everything a client receives, by trimester. Each links to the frameworks that build it.</p></div>
        <input className="os-search" placeholder="Search deliverables…" value={q} onChange={e => setQ(e.target.value)} />
      </div>
      {QUARTERS.map(qq => {
        const ds = DELIVERABLES.filter(d => qkey(d.quarter) === qq.key && match(d))
          .sort((a, b) => String(a.code).localeCompare(String(b.code), undefined, { numeric: true }));
        if (!ds.length) return null;
        return (
          <section key={qq.key} className="os-section">
            <div className="os-qh"><span className="os-qt">{qq.tag}</span><h2>{qq.name}</h2><span className="os-qs">{qq.sub} · {ds.length}</span></div>
            <div className="os-grid">{ds.map(d => <DeliverableCard key={d.id} d={d} />)}</div>
          </section>
        );
      })}
    </div>
  );
}
function FrameworksView() {
  const fws = FRAMEWORKS.slice().sort((a, b) => String(a.code).localeCompare(String(b.code), undefined, { numeric: true }));
  return (
    <div>
      <div className="os-view-h"><div><h1>Framework Library</h1><p>The 25 reusable engines & templates — master build-spec + working files.</p></div></div>
      <div className="os-grid">
        {fws.map(fw => {
          const a = A.frameworks[fw.id] || {};
          return (
            <div className="os-card" key={fw.id}>
              <div className="os-card-h"><span className="os-code gold">{fw.code}</span><span className="os-nm">{fw.name}</span></div>
              <div className="os-bw">
                {a.master ? <a className="os-chip" href={a.master} target="_blank" rel="noopener"><Icon name="doc" /> Build spec</a> : <span className="os-muted">master only</span>}
                <FileIcons files={a.files} />
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}
function LinkRows({ items }) {
  if (!items || !items.length) return <p className="os-muted">Nothing here yet.</p>;
  return (
    <div className="os-rows">
      {items.map((m, i) => (
        <a key={i} className="os-row" href={m.href} target="_blank" rel="noopener">
          <span className="os-ri"><Icon name="doc" /></span><span>{m.label}{m.note ? <em> — {m.note}</em> : null}</span>
        </a>
      ))}
    </div>
  );
}
function SimpleView({ title, lead, items }) {
  return (
    <div>
      <div className="os-view-h"><div><h1>{title}</h1>{lead ? <p>{lead}</p> : null}</div></div>
      <LinkRows items={items} />
    </div>
  );
}

/* ===================================================================== */
/* SHARED Phase-2 widgets                                                 */
/* ===================================================================== */

// Horizontal IRS meter with baseline + current + target markers + readiness.
function IrsMeter({ baseline, current, target, lang }) {
  const cur = current != null ? current : baseline;
  const rb = Math.round(readiness(baseline) * 100);
  const rc = Math.round(readiness(cur) * 100);
  const L = lang === "pt";
  const pos = v => Math.max(0, Math.min(100, v || 0));
  return (
    <div className="os-irsmeter">
      <div className="os-irsmeter-top">
        <div className="os-irsbig"><b>{cur != null ? cur : "—"}</b><span>/100 IRS</span></div>
        <div className="os-irsread" title="Readiness = (IRS/100)^0.55">
          {L ? "Fator de prontidão" : "Readiness factor"} <b>{rc}%</b>
          {baseline != null && rc !== rb ? <em> (de {rb}%)</em> : null}
        </div>
      </div>
      <div className="os-track">
        <div className="os-track-fill" style={{ width: pos(cur) + "%" }} />
        {baseline != null ? <div className="os-tick base" style={{ left: pos(baseline) + "%" }} title={(L ? "Baseline " : "Baseline ") + baseline} /> : null}
        {target != null ? <div className="os-tick tgt" style={{ left: pos(target) + "%" }} title={(L ? "Meta " : "Target ") + target} /> : null}
        {cur != null ? <div className="os-tick cur" style={{ left: pos(cur) + "%" }} /> : null}
      </div>
      <div className="os-track-legend">
        <span><i className="dot base" /> {L ? "Baseline" : "Baseline"} {baseline != null ? baseline : "—"}</span>
        <span><i className="dot cur" /> {L ? "Hoje" : "Today"} {cur != null ? cur : "—"}</span>
        <span><i className="dot tgt" /> {L ? "Meta" : "Target"} {target != null ? target : "—"}</span>
      </div>
    </div>
  );
}

// Valuation: baseline → today → target stat cards + comparative bar.
function ValuationPanel({ eng, lang }) {
  const L = lang === "pt";
  const vb = eng.valuation_baseline, vc = eng.valuation_current, vt = eng.valuation_target;
  // scale to the largest high (fall back to base if a range only has a base set, so
  // a base-only entry can't blow the bar to millions-of-percent)
  const max = Math.max(vt && (vt.high || vt.base) || 0, vc && (vc.high || vc.base) || 0, vb && (vb.high || vb.base) || 0) || 1;
  const bar = (v, cls) => v ? (
    <div className="os-vbar">
      <div className={"os-vbar-fill " + cls} style={{ width: (100 * (v.base || 0) / max) + "%" }} />
      <div className="os-vbar-rng" style={{ left: (100 * (v.low || 0) / max) + "%", width: (100 * ((v.high || 0) - (v.low || 0)) / max) + "%" }} />
    </div>
  ) : <div className="os-vbar" />;
  const upNow = vb && vc ? pctDelta(vb.base, vc.base) : null;
  const upTgt = vc && vt ? pctDelta(vc.base, vt.base) : null;
  const card = (title, v, cls, sub) => (
    <div className={"os-vcard " + cls}>
      <span className="os-vcard-t">{title}</span>
      <b className="os-vcard-n" title={v ? fmtFull(v.base) : ""}>{v ? fmtMoney(v.base) : "—"}</b>
      <span className="os-vcard-r">{v ? fmtMoney(v.low) + " – " + fmtMoney(v.high) : ""}</span>
      {bar(v, cls)}
      {sub ? <span className="os-vcard-d">{sub}</span> : null}
    </div>
  );
  return (
    <div className="os-vpanel">
      {card(L ? "Baseline" : "Baseline", vb, "base", null)}
      {card(L ? "Hoje" : "Today", vc, "cur", upNow != null ? (upNow >= 0 ? "+" : "") + upNow + (L ? "% vs baseline" : "% vs baseline") : null)}
      {card(L ? "Meta (12 meses)" : "Target (12 months)", vt, "tgt", upTgt != null ? (upTgt >= 0 ? "+" : "") + upTgt + (L ? "% potencial" : "% potential") : null)}
    </div>
  );
}

function PillarBars({ baseline, current, lang }) {
  const L = lang === "pt";
  const keys = Object.keys(PILLARS).length ? Object.keys(PILLARS) : Object.keys(current || baseline || {});
  const labelOf = k => (DISCIPLINES[k] && DISCIPLINES[k].label) || (k.charAt(0).toUpperCase() + k.slice(1));
  return (
    <div className="os-pillars">
      {keys.map(k => {
        const cv = (current && current[k]) || 0;
        const bv = (baseline && baseline[k]) || 0;
        return (
          <div className="os-pillar" key={k}>
            <div className="os-pillar-h"><span>{labelOf(k)}</span><b>{cv}</b></div>
            <div className="os-pillar-track">
              {bv ? <div className="os-pillar-base" style={{ width: bv + "%" }} title={(L ? "baseline " : "baseline ") + bv} /> : null}
              <div className="os-pillar-fill" style={{ width: cv + "%" }} />
            </div>
          </div>
        );
      })}
    </div>
  );
}

function StatusPill({ status, lang }) {
  const s = DSTATUS[status] || DSTATUS.not_started;
  return <span className={"os-stp " + s.cls}>{lang === "pt" ? s.pt : s.label}</span>;
}

// Deliverable status board grouped by quarter. editable → status dropdowns.
function StatusBoard({ statusMap, editable, onChange, lang }) {
  const L = lang === "pt";
  return (
    <div className="os-board">
      {QUARTERS.map(qq => {
        const ds = DELIVERABLES.filter(d => qkey(d.quarter) === qq.key)
          .sort((a, b) => String(a.code).localeCompare(String(b.code), undefined, { numeric: true }));
        if (!ds.length) return null;
        const done = ds.filter(d => statusMap[d.id] === "delivered").length;
        return (
          <div className="os-boardq" key={qq.key}>
            <div className="os-boardq-h">
              <span className="os-qt sm">{qq.tag}</span><span className="os-boardq-nm">{qq.name}</span>
              <span className="os-boardq-ct">{done}/{ds.length} {L ? "entregues" : "delivered"}</span>
            </div>
            {ds.map(d => {
              const st = statusMap[d.id] || "not_started";
              return (
                <div className="os-boardrow" key={d.id}>
                  <span className="os-boardrow-code">{d.code}</span>
                  <span className="os-boardrow-nm">{d.name}</span>
                  {editable ? (
                    <select className={"os-stsel " + (DSTATUS[st] || {}).cls} aria-label={d.code + " " + d.name + " status"} value={st} onChange={e => onChange(d.id, e.target.value)}>
                      {STATUS_ORDER.map(s => <option key={s} value={s}>{L ? DSTATUS[s].pt : DSTATUS[s].label}</option>)}
                    </select>
                  ) : <StatusPill status={st} lang={lang} />}
                </div>
              );
            })}
          </div>
        );
      })}
    </div>
  );
}

// The 00–11 data-room browser. Reads documents[]; opens via D.getDownloadUrl.
function DataRoom({ clientId, documents, lang, manage, onChanged }) {
  const L = lang === "pt";
  const [folder, setFolder] = useState("00");
  const [q, setQ] = useState("");
  const countByFolder = useMemo(() => {
    const m = {}; (documents || []).forEach(d => { m[d.folder] = (m[d.folder] || 0) + 1; }); return m;
  }, [documents]);
  const term = q.trim().toLowerCase();
  const docs = (documents || []).filter(d => d.folder === folder && (!term || d.name.toLowerCase().includes(term)))
    .sort((a, b) => (b.date || "").localeCompare(a.date || ""));
  const open = async (doc) => {
    const url = await D.getDownloadUrl(doc);
    if (url) window.open(url, "_blank", "noopener");
    else alert(L ? "Arquivo recebido do cliente — pré-visualização indisponível no modo local." : "Client-supplied file — preview unavailable in local preview.");
  };
  const fmeta = PORTAL.folderById[folder] || {};
  return (
    <div className="os-dr">
      <div className="os-dr-folders">
        {FOLDERS.map(f => (
          <button key={f.id} className={"os-drf" + (folder === f.id ? " active" : "")} onClick={() => setFolder(f.id)}>
            <span className="os-drf-ic"><Icon name="folder" /></span>
            <span className="os-drf-nm"><b>{f.id}</b> {f.name}</span>
            <span className="os-drf-ct">{countByFolder[f.id] || 0}</span>
          </button>
        ))}
      </div>
      <div className="os-dr-main">
        <div className="os-dr-h">
          <div><h3>{fmeta.id} {fmeta.name}</h3><p className="os-muted">{fmeta.desc}</p></div>
          <input className="os-search sm" placeholder={L ? "Buscar arquivos…" : "Search files…"} value={q} onChange={e => setQ(e.target.value)} />
        </div>
        {manage ? <AddDocForm clientId={clientId} folder={folder} lang={lang} onAdded={onChanged} /> : null}
        {docs.length ? (
          <div className="os-doclist">
            {docs.map(doc => (
              <div className="os-docrow" key={doc.id}>
                <FileTag ext={doc.ext} />
                <span className="os-doc-nm">{doc.name}</span>
                <span className={"os-doc-src " + doc.source}>{doc.source === "delivered" ? (L ? "Entregue" : "Delivered") : (L ? "Recebido" : "Received")}</span>
                <span className="os-doc-dt">{doc.date}</span>
                {doc.source === "delivered"
                  ? <button className="os-doc-open" aria-label={(L ? "Abrir " : "Open ") + doc.name} onClick={() => open(doc)}>{L ? "Abrir" : "Open"}</button>
                  : <span className="os-doc-noopen">{L ? "Sem prévia" : "No preview"}</span>}
                {manage ? <button className="os-doc-rm" aria-label={(L ? "Remover " : "Remove ") + doc.name} title="Remove" onClick={async () => { await D.removeDocument(clientId, doc.id); onChanged && onChanged(); }}><Icon name="close" /></button> : null}
              </div>
            ))}
          </div>
        ) : <p className="os-muted" style={{ marginTop: 16 }}>{L ? "Nenhum arquivo nesta pasta ainda." : "No files in this folder yet."}</p>}
      </div>
    </div>
  );
}

function AddDocForm({ clientId, folder, lang, onAdded }) {
  const L = lang === "pt";
  const [name, setName] = useState("");
  const [fwRef, setFwRef] = useState("");
  const [busy, setBusy] = useState(false);
  const add = async () => {
    if (!name.trim()) return;
    setBusy(true);
    try {
      await D.addDocument(clientId, { folder, name: name.trim(), fwRef: fwRef || undefined, ext: (name.split(".").pop() || "").toLowerCase(), source: "delivered" });
      setName(""); setFwRef(""); onAdded && onAdded();
    } catch (e) { alert((e && e.message) || "Error"); }
    setBusy(false);
  };
  return (
    <div className="os-adddoc">
      <input placeholder={L ? "Nome do arquivo (ex. 02_Cliente_Modelo_v1.xlsx)" : "File name (e.g. 02_Client_Model_v1.xlsx)"} value={name} onChange={e => setName(e.target.value)} />
      <select value={fwRef} onChange={e => setFwRef(e.target.value)} title={L ? "Vincular a um arquivo de framework (abre o real)" : "Link to a framework working file (opens the real one)"}>
        <option value="">{L ? "— sem link —" : "— no link —"}</option>
        {FRAMEWORKS.map(fw => <option key={fw.id} value={fw.id}>{fw.code} {fw.name}</option>)}
      </select>
      <button onClick={add} disabled={busy}>{busy ? "…" : (L ? "Adicionar" : "Add")}</button>
    </div>
  );
}

/* ---------- intake form rendering --------------------------------------- */
function IntakeFieldInput({ item, value, onChange, lang }) {
  const L = lang === "pt";
  const label = item.label ? (L ? item.label.pt : item.label.en) : item.id;
  const help = item.help ? (L ? item.help.pt : item.help.en) : null;
  const t = item.type;
  let control;
  if (t === "file") {
    control = (
      <div className="os-filefield">
        <input type="file" onChange={e => onChange(e.target.files && e.target.files[0] ? { file: e.target.files[0], name: e.target.files[0].name } : null)} />
        {value && (value.name || typeof value === "string") ? <span className="os-fileok"><Icon name="check" /> {value.name || value}</span> : null}
      </div>
    );
  } else if (t === "textarea") {
    control = <textarea rows={2} value={value || ""} onChange={e => onChange(e.target.value)} />;
  } else if (t === "number" || t === "currency" || t === "percent") {
    control = <input type="number" step="any" value={value == null ? "" : value} onChange={e => onChange(e.target.value)} />;
  } else {
    control = <input type="text" value={value || ""} onChange={e => onChange(e.target.value)} />;
  }
  return (
    <div className={"os-ifield" + (item.required ? " req" : "")}>
      <label>
        <span className="os-ifield-id">{item.id}</span>
        <span className="os-ifield-lab">{label}{item.required ? <em className="os-req">*</em> : null}
          {t === "percent" ? " (%)" : t === "currency" ? " (R$)" : ""}</span>
      </label>
      {control}
      {help ? <p className="os-ifield-help">{help}</p> : null}
    </div>
  );
}

function IntakeFormRenderer({ form, clientId, existing, lang, onDone, onCancel }) {
  const L = lang === "pt";
  const [vals, setVals] = useState(() => {
    // map of file-type item ids so a stored filename string round-trips as { name }
    const fileItems = {};
    form.sections.forEach(s => s.items.forEach(it => { if (it.type === "file") fileItems[it.id] = true; }));
    const seed = {};
    if (existing && existing.payload) Object.keys(existing.payload).forEach(k => {
      if (k[0] === "_") return;
      const v = existing.payload[k];
      seed[k] = (fileItems[k] && typeof v === "string") ? { name: v } : v;
    });
    return seed;
  });
  const [busy, setBusy] = useState(false);
  const set = (id, v) => setVals(s => ({ ...s, [id]: v }));

  const allItems = form.sections.reduce((a, s) => a.concat(s.items.map(it => ({ it, tier: s.tier }))), []);
  const tier1 = allItems.filter(x => x.tier === 1 && x.it.required);
  const tier1Have = tier1.filter(x => {
    const v = vals[x.it.id];
    return v != null && v !== "" && !(typeof v === "object" && !v.name);
  }).length;
  const gateOpen = tier1Have >= tier1.length;

  const submit = async (asDraft) => {
    setBusy(true);
    try {
      const files = [], payload = {};
      allItems.forEach(({ it }) => {
        const v = vals[it.id];
        if (v == null || v === "") return;
        if (it.type === "file" && v && v.file) files.push({ itemId: it.id, folder: it.folder, file: v.file, name: v.name });
        else if (it.type === "file" && v && v.name) payload[it.id] = v.name;
        else payload[it.id] = v;
      });
      await D.submitIntake(clientId, form.id, payload, {
        status: asDraft ? "in_progress" : "submitted", tier1Done: tier1Have, files
      });
      onDone && onDone();
    } catch (e) { alert((e && e.message) || "Error"); }
    setBusy(false);
  };

  return (
    <div className="os-intakeform">
      <div className="os-if-head">
        <button className="os-back" onClick={onCancel}><Icon name="back" /> {L ? "Voltar" : "Back"}</button>
        <div>
          <h2>{form.code} · {L ? form.name.pt : form.name.en}</h2>
          <p className="os-muted">{L ? form.intro.pt : form.intro.en}</p>
        </div>
      </div>
      <div className={"os-gate " + (gateOpen ? "open" : "closed")}>
        <b>{L ? "Portão de coleta (Tier 1)" : "Collection gate (Tier 1)"}:</b> {tier1Have}/{tier1.length}
        <div className="os-gate-track"><div className="os-gate-fill" style={{ width: (tier1.length ? 100 * tier1Have / tier1.length : 0) + "%" }} /></div>
        <span>{gateOpen ? (L ? "Pronto para enviar — análise pode começar." : "Ready to submit — analysis can start.") : (L ? "Itens Tier 1 obrigatórios faltando." : "Mandatory Tier-1 items still missing.")}</span>
      </div>
      {form.sections.map((sec, i) => (
        <div className={"os-isec tier" + sec.tier} key={i}>
          <h4>{L ? sec.title.pt : sec.title.en}</h4>
          <div className="os-igrid">
            {sec.items.map(it => (
              <IntakeFieldInput key={it.id} item={it} value={vals[it.id]} onChange={v => set(it.id, v)} lang={lang} />
            ))}
          </div>
        </div>
      ))}
      <div className="os-if-actions">
        <button className="os-btn ghost" disabled={busy} onClick={() => submit(true)}>{L ? "Salvar rascunho" : "Save draft"}</button>
        <button className="os-btn gold" disabled={busy} onClick={() => submit(false)}>{busy ? "…" : (L ? "Enviar formulário" : "Submit form")}</button>
      </div>
    </div>
  );
}

/* ===================================================================== */
/* CLIENT PORTAL (role=client, or employee preview)                      */
/* ===================================================================== */
function PortalDashboard({ data, statusMap, documents, intake, lang }) {
  const L = lang === "pt";
  const eng = data.engagement || {};
  // count ALL deliverables (incl. recurring) so the headline % reconciles with the
  // StatusBoard below it (which groups recurring items under "Spine").
  const total = DELIVERABLES.length;
  const delivered = DELIVERABLES.filter(d => statusMap[d.id] === "delivered").length;
  const pctDone = total ? Math.round(100 * delivered / total) : 0;
  const recentDocs = (documents || []).slice().sort((a, b) => (b.date || "").localeCompare(a.date || "")).slice(0, 5);
  const upNow = eng.valuation_baseline && eng.valuation_current ? pctDelta(eng.valuation_baseline.base, eng.valuation_current.base) : null;
  return (
    <div>
      <div className="os-view-h">
        <div>
          <h1>{data.client.name}</h1>
          <p>{L ? "Sua prontidão para investimento e o que já entregamos." : "Your investment readiness and what we've delivered so far."}
            {eng.current_quarter ? " · " + (L ? "Trimestre atual " : "Current quarter ") + "Q" + eng.current_quarter : ""}</p>
        </div>
      </div>

      <div className="os-dashgrid">
        <div className="os-pcard">
          <h3>{L ? "Investment Readiness Score" : "Investment Readiness Score"}</h3>
          <IrsMeter baseline={eng.irs_baseline} current={eng.irs_current} target={eng.irs_target} lang={lang} />
          <p className="os-pnote">{L
            ? "A valuation é Base × Múltiplo × Prontidão. Subir o IRS destrava o múltiplo que sua empresa já merece — sem mudar a receita."
            : "Valuation is Basis × Multiple × Readiness. Raising the IRS unlocks the multiple your company already deserves — without changing revenue."}</p>
        </div>
        <div className="os-pcard">
          <h3>{L ? "Progresso" : "Progress"}</h3>
          <div className="os-progbig"><b>{pctDone}%</b><span>{delivered}/{total} {L ? "entregáveis" : "deliverables"}</span></div>
          <div className="os-track sm"><div className="os-track-fill" style={{ width: pctDone + "%" }} /></div>
          {eng.next_milestone ? <p className="os-pnote"><b>{L ? "Próximo:" : "Next:"}</b> {eng.next_milestone}</p> : null}
        </div>
      </div>

      <section className="os-section">
        <div className="os-qh"><span className="os-qt">{L ? "Valuation" : "Valuation"}</span><h2>{L ? "Faixa de valuation" : "Valuation range"}</h2>
          {upNow != null ? <span className="os-qs">{(upNow >= 0 ? "+" : "") + upNow}% {L ? "desde o baseline" : "since baseline"}</span> : null}</div>
        <ValuationPanel eng={eng} lang={lang} />
      </section>

      {(eng.pillar_current && Object.keys(eng.pillar_current).length) ? (
        <section className="os-section">
          <div className="os-qh"><span className="os-qt">{L ? "Pilares" : "Pillars"}</span><h2>{L ? "Prontidão por dimensão" : "Readiness by dimension"}</h2></div>
          <div className="os-pcard"><PillarBars baseline={eng.pillar_baseline} current={eng.pillar_current} lang={lang} /></div>
        </section>
      ) : null}

      <section className="os-section">
        <div className="os-qh"><span className="os-qt">{L ? "Entregáveis" : "Deliverables"}</span><h2>{L ? "Status do programa" : "Program status"}</h2></div>
        <StatusBoard statusMap={statusMap} editable={false} lang={lang} />
      </section>

      {recentDocs.length ? (
        <section className="os-section">
          <div className="os-qh"><span className="os-qt">{L ? "Data Room" : "Data Room"}</span><h2>{L ? "Entregas recentes" : "Recent deliveries"}</h2></div>
          <div className="os-doclist">
            {recentDocs.map(doc => (
              <div className="os-docrow" key={doc.id}>
                <FileTag ext={doc.ext} />
                <span className="os-doc-nm">{doc.name}</span>
                <span className={"os-doc-src " + doc.source}>{doc.source === "delivered" ? (L ? "Entregue" : "Delivered") : (L ? "Recebido" : "Received")}</span>
                <span className="os-doc-dt">{doc.date}</span>
              </div>
            ))}
          </div>
        </section>
      ) : null}
    </div>
  );
}

function PortalIntake({ clientId, intake, lang, onChanged }) {
  const L = lang === "pt";
  const [active, setActive] = useState(null); // form id being filled
  const byForm = {}; (intake || []).forEach(s => { byForm[s.formId] = s; });
  if (active) {
    const form = PORTAL.formById[active];
    return <IntakeFormRenderer form={form} clientId={clientId} existing={byForm[active]} lang={lang}
      onCancel={() => setActive(null)} onDone={() => { setActive(null); onChanged && onChanged(); }} />;
  }
  return (
    <div>
      <div className="os-view-h"><div><h1>{L ? "Coleta de dados" : "Intake"}</h1>
        <p>{L ? "Os formulários que abrem cada trimestre. A qualidade dos dados define o teto do que provamos ao investidor." : "The forms that open each quarter. Data quality sets the ceiling on what we can prove to an investor."}</p></div></div>
      <div className="os-grid">
        {FORMS.map(f => {
          const sub = byForm[f.id];
          const st = sub ? sub.status : "not_started";
          const t1 = sub ? (sub.tier1Done || 0) : 0;
          return (
            <div className="os-card" key={f.id}>
              <div className="os-card-h">
                <span className="os-code">{f.code}</span>
                <span className="os-nm">{L ? f.name.pt : f.name.en}</span>
                <StatusPill status={st === "submitted" ? "delivered" : (st === "in_progress" ? "in_progress" : "not_started")} lang={lang} />
              </div>
              <div className="os-tag">Q{f.quarter} · {f.month} → {f.feeds}</div>
              <div className="os-gate mini">
                <div className="os-gate-track"><div className="os-gate-fill" style={{ width: (f.tier1Required ? 100 * Math.min(t1, f.tier1Required) / f.tier1Required : 0) + "%" }} /></div>
                <span>{t1}/{f.tier1Required} Tier 1</span>
              </div>
              <button className="os-btn gold sm" onClick={() => setActive(f.id)}>
                {st === "submitted" ? (L ? "Revisar / reenviar" : "Review / resubmit") : (st === "in_progress" ? (L ? "Continuar" : "Continue") : (L ? "Preencher" : "Fill out"))}
              </button>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function ClientPortal({ clientId, profile, preview, onExit }) {
  const lang = "pt"; // client-facing UI in PT (Brazilian founders)
  const [view, setView] = useState("dashboard");
  const { data, loading, error, reload } = useAsync(async () => {
    if (!clientId) return null;
    const base = await D.getClient(clientId);
    if (!base) return null;
    const [statusMap, documents, intake] = await Promise.all([
      D.getDeliverableStatus(clientId), D.listDocuments(clientId), D.listIntake(clientId)
    ]);
    return { ...base, statusMap, documents, intake };
  }, [clientId]);

  if (loading) return <div className="os-splash"><b>VALIORO</b><span>Portal</span><i>carregando…</i></div>;
  if (error || !data) return (
    <div className="os-login"><div className="os-login-card">
      <div className="os-login-brand"><b>VALIORO</b><span>Portal</span></div>
      <p className="os-login-sub">Não encontramos um engajamento ligado à sua conta.</p>
      <button onClick={onExit ? onExit : () => AUTH.signOut().then(() => location.reload())}>{preview ? "Sair da prévia" : "Sair"}</button>
    </div></div>
  );

  let body;
  if (view === "dataroom") body = <DataRoom clientId={clientId} documents={data.documents} lang={lang} manage={false} />;
  else if (view === "intake") body = <PortalIntake clientId={clientId} intake={data.intake} lang={lang} onChanged={reload} />;
  else body = <PortalDashboard data={data} statusMap={data.statusMap} documents={data.documents} intake={data.intake} lang={lang} />;

  return (
    <div className={"os-shell portal" + (preview ? " previewing" : "")}>
      {preview ? <div className="os-previewbar"><Icon name="eye" /> Prévia do portal do cliente — <b>{data.client.name}</b><button onClick={onExit}>Sair da prévia</button></div> : null}
      <aside className="os-side">
        <div className="os-logo"><b>VALIORO</b><span>{data.client.name.split(" ")[0]}</span></div>
        <nav>
          {PORTAL.PORTAL_NAV.map(n => (
            <button key={n.id} className={"os-navbtn" + (view === n.id ? " active" : "")} onClick={() => setView(n.id)}>
              <span className="os-navi"><Icon name={n.id} /></span><span>{n.label}</span>
            </button>
          ))}
        </nav>
        <div className="os-side-foot">
          <span className="os-badge authed">● {data.client.name}</span>
          {preview ? <button className="os-signout" onClick={onExit}>Sair da prévia</button>
            : <button className="os-signout" onClick={async () => { await AUTH.signOut(); location.reload(); }}>Sair</button>}
          {!preview ? <a className="os-sitelink" href={SITE_HREF}><Icon name="back" /> Site</a> : null}
        </div>
      </aside>
      <main className="os-main">{body}</main>
    </div>
  );
}

/* ===================================================================== */
/* EMPLOYEE — Clients management (replaces the Phase-1 placeholder)       */
/* ===================================================================== */
function ClientsView({ onPreview }) {
  const lang = "en";
  const [selected, setSelected] = useState(null);
  const { data, loading, reload } = useAsync(() => D.listClients(), []);
  const [adding, setAdding] = useState(false);

  if (selected) return <ClientDetail clientId={selected} onBack={() => { setSelected(null); reload(); }} onPreview={onPreview} />;

  return (
    <div>
      <div className="os-view-h">
        <div><h1>Clients</h1><p>One engagement per client — IRS, valuation, deliverable status, the 00–11 data room, and intake.</p></div>
        <button className="os-btn gold" onClick={() => setAdding(a => !a)}>{adding ? "Close" : "+ New client"}</button>
      </div>
      {adding ? <NewClientForm onCreated={() => { setAdding(false); reload(); }} /> : null}
      {D && D.mode === "local" ? <p className="os-muted">Local preview — demo data. <button className="os-linkbtn" onClick={async () => { if (confirm("Reset demo data to seed?")) { D.resetLocal(); reload(); } }}>Reset demo data</button></p> : null}
      {loading ? <p className="os-muted">Loading…</p> : (
        <div className="os-grid">
          {(data || []).map(c => {
            const v = c.valuation_current;
            return (
              <div className="os-card client" key={c.id} onClick={() => setSelected(c.id)}>
                <div className="os-card-h">
                  <span className="os-nm">{c.name}</span>
                  {c.current_quarter ? <span className="os-disc">Q{c.current_quarter}</span> : null}
                </div>
                <div className="os-clientstats">
                  <span><b>{c.irs_current != null ? c.irs_current : "—"}</b> IRS{c.irs_target ? " → " + c.irs_target : ""}</span>
                  <span>{v ? fmtMoney(v.base) : "—"}</span>
                </div>
                <button className="os-btn ghost sm" onClick={e => { e.stopPropagation(); onPreview(c.id); }}><Icon name="eye" /> Open client portal</button>
              </div>
            );
          })}
          {!(data || []).length ? <p className="os-muted">No clients yet. Add one to begin.</p> : null}
        </div>
      )}
    </div>
  );
}

function NewClientForm({ onCreated }) {
  const [name, setName] = useState("");
  const [sector, setSector] = useState("");
  const [busy, setBusy] = useState(false);
  const create = async () => {
    if (!name.trim()) return;
    setBusy(true);
    try { await D.createClient({ name: name.trim(), sector: sector || null }); onCreated(); }
    catch (e) { alert((e && e.message) || "Error"); setBusy(false); }
  };
  return (
    <div className="os-panel" style={{ maxWidth: 560 }}>
      <h3>New client</h3>
      <div className="os-formrow"><input placeholder="Company name" value={name} onChange={e => setName(e.target.value)} /></div>
      <div className="os-formrow"><input placeholder="Sector (optional)" value={sector} onChange={e => setSector(e.target.value)} /></div>
      <button className="os-btn gold" disabled={busy} onClick={create}>{busy ? "…" : "Create engagement"}</button>
    </div>
  );
}

function ClientDetail({ clientId, onBack, onPreview }) {
  const lang = "en";
  const [tab, setTab] = useState("engagement");
  const { data, loading, reload } = useAsync(async () => {
    const base = await D.getClient(clientId);
    if (!base) return null;
    const [statusMap, documents, intake] = await Promise.all([
      D.getDeliverableStatus(clientId), D.listDocuments(clientId), D.listIntake(clientId)
    ]);
    return { ...base, statusMap, documents, intake };
  }, [clientId]);

  if (loading) return <p className="os-muted">Loading…</p>;
  if (!data) return <div><button className="os-back" onClick={onBack}><Icon name="back" /> Back</button><p className="os-muted">Client not found.</p></div>;

  const setStatus = async (delivId, status) => { await D.setDeliverableStatus(clientId, delivId, status); reload(); };

  const TABS = [
    { id: "engagement", label: "Engagement" },
    { id: "board", label: "Deliverable status" },
    { id: "dataroom", label: "Data room" },
    { id: "intake", label: "Intake" },
  ];
  return (
    <div>
      <div className="os-view-h">
        <div>
          <button className="os-back" onClick={onBack}><Icon name="back" /> Clients</button>
          <h1>{data.client.name}</h1>
          <p>{data.client.sector || "—"}{data.client.city ? " · " + data.client.city : ""} · Q{(data.engagement || {}).current_quarter || 1}</p>
        </div>
        <button className="os-btn ghost" onClick={() => onPreview(clientId)}><Icon name="eye" /> Open client portal</button>
      </div>
      <div className="os-tabs">
        {TABS.map(t => <button key={t.id} className={"os-tab" + (tab === t.id ? " active" : "")} onClick={() => setTab(t.id)}>{t.label}</button>)}
      </div>
      {tab === "engagement" ? <EngagementEditor clientId={clientId} engagement={data.engagement} onSaved={reload} /> : null}
      {tab === "board" ? <StatusBoard statusMap={data.statusMap} editable onChange={setStatus} lang={lang} /> : null}
      {tab === "dataroom" ? <DataRoom clientId={clientId} documents={data.documents} lang={lang} manage onChanged={reload} /> : null}
      {tab === "intake" ? <EmployeeIntakeView intake={data.intake} lang={lang} /> : null}
    </div>
  );
}

function EngagementEditor({ clientId, engagement, onSaved }) {
  const e = engagement || {};
  const [f, setF] = useState({
    current_quarter: e.current_quarter || 1,
    irs_baseline: e.irs_baseline ?? "", irs_current: e.irs_current ?? "", irs_target: e.irs_target ?? "",
    vb: e.valuation_baseline || {}, vc: e.valuation_current || {}, vt: e.valuation_target || {},
    next_milestone: e.next_milestone || "",
  });
  const [busy, setBusy] = useState(false);
  const num = v => (v === "" || v == null ? null : Number(v));
  const setV = (k, v) => setF(s => ({ ...s, [k]: v }));
  const setVal = (which, key, v) => setF(s => ({ ...s, [which]: { ...s[which], [key]: num(v) } }));
  const save = async () => {
    setBusy(true);
    try {
      await D.updateEngagement(clientId, {
        current_quarter: Number(f.current_quarter),
        irs_baseline: num(f.irs_baseline), irs_current: num(f.irs_current), irs_target: num(f.irs_target),
        valuation_baseline: f.vb, valuation_current: f.vc, valuation_target: f.vt,
        next_milestone: f.next_milestone,
      });
      onSaved && onSaved();
    } catch (ex) { alert((ex && ex.message) || "Error"); }
    setBusy(false);
  };
  const valRow = (label, which) => (
    <div className="os-formrow vals">
      <span className="os-flabel">{label}</span>
      <input type="number" placeholder="low" value={f[which].low ?? ""} onChange={ev => setVal(which, "low", ev.target.value)} />
      <input type="number" placeholder="base" value={f[which].base ?? ""} onChange={ev => setVal(which, "base", ev.target.value)} />
      <input type="number" placeholder="high" value={f[which].high ?? ""} onChange={ev => setVal(which, "high", ev.target.value)} />
    </div>
  );
  return (
    <div className="os-panel" style={{ maxWidth: 720 }}>
      <h3>Engagement</h3>
      <div className="os-formrow">
        <span className="os-flabel">Current quarter</span>
        <select value={f.current_quarter} onChange={ev => setV("current_quarter", ev.target.value)}>
          {[1, 2, 3, 4].map(q => <option key={q} value={q}>Q{q}</option>)}
        </select>
      </div>
      <div className="os-formrow vals">
        <span className="os-flabel">IRS (baseline / today / target)</span>
        <input type="number" placeholder="baseline" value={f.irs_baseline} onChange={ev => setV("irs_baseline", ev.target.value)} />
        <input type="number" placeholder="today" value={f.irs_current} onChange={ev => setV("irs_current", ev.target.value)} />
        <input type="number" placeholder="target" value={f.irs_target} onChange={ev => setV("irs_target", ev.target.value)} />
      </div>
      <p className="os-muted" style={{ margin: "10px 0 4px" }}>Valuation ranges (R$):</p>
      {valRow("Baseline", "vb")}
      {valRow("Today", "vc")}
      {valRow("Target", "vt")}
      <div className="os-formrow"><span className="os-flabel">Next milestone</span><input value={f.next_milestone} onChange={ev => setV("next_milestone", ev.target.value)} /></div>
      <button className="os-btn gold" disabled={busy} onClick={save}>{busy ? "…" : "Save engagement"}</button>
    </div>
  );
}

function EmployeeIntakeView({ intake, lang }) {
  const byForm = {}; (intake || []).forEach(s => { byForm[s.formId] = s; });
  return (
    <div>
      {FORMS.map(f => {
        const sub = byForm[f.id];
        const payload = (sub && sub.payload) || {};
        const keys = Object.keys(payload).filter(k => k[0] !== "_");
        return (
          <div className="os-panel" key={f.id} style={{ marginTop: 14, maxWidth: 820 }}>
            <h3>{f.code} · {f.name.en} {sub ? <StatusPill status={sub.status === "submitted" ? "delivered" : "in_progress"} lang="en" /> : <span className="os-muted">not started</span>}</h3>
            {sub ? <p className="os-muted">Tier-1: {sub.tier1Done || 0}/{f.tier1Required}{sub.submittedAt ? " · submitted " + sub.submittedAt : " · draft"}</p> : null}
            {keys.length ? <table className="os-kv"><tbody>{keys.map(k => <tr key={k}><td>{k}</td><td>{String(payload[k])}</td></tr>)}</tbody></table> : <p className="os-muted">No responses yet.</p>}
          </div>
        );
      })}
    </div>
  );
}

/* ===================================================================== */
/* SHELL + AUTH                                                           */
/* ===================================================================== */
/* PT/EN for the sign-in screen (persisted in localStorage; defaults to
   Portuguese for the Brazilian audience). Note: the rest of the OS is still
   English-only for now — this toggle currently covers the login screen. */
const LOGIN_STR = {
  pt: { os: "Sistema Operacional", sub: "Entre para continuar", email: "E-mail", password: "Senha",
        signIn: "Entrar", signingIn: "Entrando…", foot: "Acesso de equipe e clientes · Valioro",
        back: "Voltar ao site", failed: "Falha ao entrar. Verifique o e-mail e a senha." },
  en: { os: "Operating System", sub: "Sign in to continue", email: "Email", password: "Password",
        signIn: "Sign in", signingIn: "Signing in…", foot: "Team & client access · Valioro",
        back: "Back to site", failed: "Sign-in failed. Check your email and password." }
};
function getOsLang() { try { return localStorage.getItem("valioro_os_lang") === "en" ? "en" : "pt"; } catch (e) { return "pt"; } }
function setOsLang(l) { try { localStorage.setItem("valioro_os_lang", l); } catch (e) {} }

function LoginScreen({ onSignedIn }) {
  const [email, setEmail] = useState(""); const [pw, setPw] = useState("");
  const [err, setErr] = useState(""); const [busy, setBusy] = useState(false);
  const [lang, setLang] = useState(getOsLang);
  const t = LOGIN_STR[lang];
  const pick = (l) => { setOsLang(l); setLang(l); };
  const submit = async (e) => {
    e.preventDefault(); setErr(""); setBusy(true);
    try { const u = await AUTH.signIn(email.trim(), pw); onSignedIn(u); }
    catch (ex) { setErr(ex && ex.message ? ex.message : t.failed); setBusy(false); }
  };
  return (
    <div className="os-login">
      <div className="os-login-lang" role="group" aria-label="Idioma / Language">
        <button type="button" className={lang === "pt" ? "on" : ""} aria-pressed={lang === "pt"} onClick={() => pick("pt")}>PT</button>
        <button type="button" className={lang === "en" ? "on" : ""} aria-pressed={lang === "en"} onClick={() => pick("en")}>EN</button>
      </div>
      <form className="os-login-card" onSubmit={submit}>
        <div className="os-login-brand"><b>VALIORO</b><span>{t.os}</span></div>
        <p className="os-login-sub">{t.sub}</p>
        <input type="email" placeholder={t.email} value={email} onChange={e => setEmail(e.target.value)} autoFocus required />
        <input type="password" placeholder={t.password} value={pw} onChange={e => setPw(e.target.value)} required />
        {err ? <div className="os-login-err">{err}</div> : null}
        <button type="submit" disabled={busy}>{busy ? t.signingIn : t.signIn}</button>
        <p className="os-login-foot">{t.foot}</p>
        <a className="os-sitelink center" href={SITE_HREF}><Icon name="back" /> {t.back}</a>
      </form>
    </div>
  );
}

/* ===================================================================== */
/* SALES ROOM — the pipeline (Lead → … → Signed). The IRS assessment      */
/* attaches to a deal; a signed deal converts into a client engagement.   */
/* ===================================================================== */
const SALES_STAGES = [
  { id: "lead", label: "Lead" },
  { id: "qualified", label: "Qualified" },
  { id: "discovery", label: "Discovery" },
  { id: "assessment", label: "Assessment" },
  { id: "proposal", label: "Proposal" },
  { id: "signed", label: "Signed" },
];
const ICP_CHECKS = [
  { id: "revenue", label: "Revenue ≥ R$500k" },
  { id: "vertical", label: "Digital-services vertical" },
  { id: "founderLed", label: "Post-revenue & founder-led" },
  { id: "intent", label: "Real raise / exit intent" },
  { id: "region", label: "South Brazil / reachable" },
];
const SOURCE_LABEL = { content: "Content", outreach: "Outreach", referral: "Referral" };

function DealCard({ d, onOpen }) {
  return (
    <div className="os-card client" style={{ marginBottom: 10, cursor: "pointer" }} onClick={onOpen}>
      <div className="os-card-h"><span className="os-nm">{d.company}</span></div>
      <div className="os-clientstats">
        <span>{d.sector || "—"}{d.revenue ? " · " + fmtMoney(d.revenue) : ""}</span>
        {d.irs && d.irs.score != null ? <span><b>{d.irs.score}</b> IRS</span> : null}
      </div>
      {d.next_action ? <div className="os-tag">{d.next_action}{d.next_date ? " · " + d.next_date : ""}</div> : null}
    </div>
  );
}

function NewDealForm({ onCreated }) {
  const [f, setF] = useState({ company: "", sector: "", revenue: "", source: "content" });
  const [busy, setBusy] = useState(false);
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const create = async () => {
    if (!f.company.trim()) return;
    setBusy(true);
    try { await D.createDeal({ company: f.company.trim(), sector: f.sector || null, revenue: f.revenue ? Number(f.revenue) : null, source: f.source, price: 8000 }); onCreated(); }
    catch (e) { alert((e && e.message) || "Error"); setBusy(false); }
  };
  return (
    <div className="os-panel" style={{ maxWidth: 560 }}>
      <h3>New deal</h3>
      <div className="os-formrow"><input placeholder="Company" value={f.company} onChange={e => set("company", e.target.value)} /></div>
      <div className="os-formrow"><input placeholder="Sector (e.g. fintech, saas, agency)" value={f.sector} onChange={e => set("sector", e.target.value)} /></div>
      <div className="os-formrow"><input type="number" placeholder="Annual revenue (R$)" value={f.revenue} onChange={e => set("revenue", e.target.value)} /></div>
      <div className="os-formrow">
        <select value={f.source} onChange={e => set("source", e.target.value)}>
          <option value="content">Content</option><option value="outreach">Outreach</option><option value="referral">Referral</option>
        </select>
      </div>
      <button className="os-btn gold" disabled={busy} onClick={create}>{busy ? "…" : "Add to pipeline"}</button>
    </div>
  );
}

function DealDetail({ dealId, onBack, onConverted }) {
  const { data: deal, loading, reload } = useAsync(() => D.getDeal(dealId), [dealId]);
  const [f, setF] = useState(null);
  const [busy, setBusy] = useState(false);
  useEffect(() => { if (deal) setF({ ...deal, icp: { ...(deal.icp || {}) }, irs: deal.irs ? { ...deal.irs } : null }); }, [deal]);
  if (loading || !f) return <div><button className="os-back" onClick={onBack}><Icon name="back" /> Sales</button><p className="os-muted">Loading…</p></div>;

  const num = v => (v === "" || v == null ? null : Number(v));
  const setV = (k, v) => setF(s => ({ ...s, [k]: v }));
  const setIcp = (k, v) => setF(s => ({ ...s, icp: { ...s.icp, [k]: v } }));
  const setIrs = (k, v) => setF(s => ({ ...s, irs: { ...(s.irs || {}), [k]: (k === "confidence" ? v : num(v)) } }));
  const icpPass = ICP_CHECKS.every(c => !!f.icp[c.id]);
  const converted = !!f.signed_client_id;

  const save = async () => {
    setBusy(true);
    try {
      await D.updateDeal(dealId, {
        company: f.company, contact: f.contact || null, sector: f.sector || null,
        revenue: num(f.revenue), source: f.source || null, stage: f.stage,
        icp: f.icp, irs: f.irs, price: num(f.price),
        next_action: f.next_action || null, next_date: f.next_date || null, notes: f.notes || null
      });
      reload();
    } catch (e) { alert((e && e.message) || "Error"); }
    setBusy(false);
  };

  const del = async () => {
    if (!confirm("Delete this deal / lead? This can't be undone.")) return;
    setBusy(true);
    try { await D.deleteDeal(dealId); onBack(); }
    catch (e) { alert((e && e.message) || "Error"); setBusy(false); }
  };

  const convert = async () => {
    if (!confirm("Mark this deal Signed and create the client engagement? This hands it to Onboarding.")) return;
    setBusy(true);
    try {
      const client = await D.createClient({ name: f.company, sector: f.sector || null });
      if (f.irs && f.irs.score != null) {
        await D.updateEngagement(client.id, {
          irs_baseline: f.irs.score, irs_current: f.irs.score,
          valuation_baseline: { low: f.irs.low, base: f.irs.base, high: f.irs.high },
          valuation_current: { low: f.irs.low, base: f.irs.base, high: f.irs.high }
        });
      }
      // Sales → Finance handoff: the first retainer invoice (issued, day-5 cadence
      // set by Finance). Optional — a failure here must not orphan the new client.
      try { await D.addItem("finance_invoices", { client_id: client.id, client_name: f.company, kind: "retainer", amount: f.price || 8000, due_date: null, paid_date: null, method: "pix", status: "issued", notes: "Mês 1 retainer — Sales Signed handoff." }); } catch (e2) { /* non-fatal */ }
      await D.updateDeal(dealId, { stage: "signed", signed_client_id: client.id });
      onConverted && onConverted(client.id);
    } catch (e) { alert((e && e.message) || "Error"); setBusy(false); }
  };

  return (
    <div>
      <div className="os-view-h">
        <div>
          <button className="os-back" onClick={onBack}><Icon name="back" /> Sales</button>
          <h1>{f.company}</h1>
          <p>{f.sector || "—"}{f.revenue ? " · " + fmtMoney(f.revenue) : ""}{f.source ? " · " + (SOURCE_LABEL[f.source] || f.source) : ""}</p>
        </div>
      </div>

      <div className="os-formrow" style={{ maxWidth: 720 }}>
        <span className="os-flabel">Stage</span>
        <select value={f.stage} onChange={e => setV("stage", e.target.value)}>
          {SALES_STAGES.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}
        </select>
      </div>

      <div className="os-panel" style={{ maxWidth: 720 }}>
        <h3>Deal</h3>
        <div className="os-formrow"><span className="os-flabel">Company</span><input value={f.company} onChange={e => setV("company", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Contact</span><input value={f.contact || ""} onChange={e => setV("contact", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Sector</span><input value={f.sector || ""} onChange={e => setV("sector", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Annual revenue (R$)</span><input type="number" value={f.revenue ?? ""} onChange={e => setV("revenue", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Monthly price (R$)</span><input type="number" value={f.price ?? ""} onChange={e => setV("price", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Next action</span><input value={f.next_action || ""} onChange={e => setV("next_action", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Next date</span><input type="date" value={f.next_date || ""} onChange={e => setV("next_date", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Notes</span><input value={f.notes || ""} onChange={e => setV("notes", e.target.value)} /></div>
        <button className="os-btn gold" disabled={busy} onClick={save}>{busy ? "…" : "Save deal"}</button>
        <button className="os-btn ghost" disabled={busy} onClick={del} style={{ marginLeft: 8 }}>Delete</button>
      </div>

      <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
        <h3>Qualify — ICP gate</h3>
        <p className="os-muted">Fails the check → nurture list, not the pipeline. Don't run the assessment for people who'll never buy.</p>
        {ICP_CHECKS.map(c => (
          <label key={c.id} className="os-formrow" style={{ cursor: "pointer", alignItems: "center" }}>
            <input type="checkbox" checked={!!f.icp[c.id]} onChange={e => setIcp(c.id, e.target.checked)} style={{ width: "auto", marginRight: 8 }} />
            <span>{c.label}</span>
          </label>
        ))}
        <p style={{ marginTop: 8 }}><b className={icpPass ? "" : "os-muted"}>{icpPass ? "ICP fit — proceed." : "Not a full ICP fit yet."}</b></p>
        <button className="os-btn ghost" disabled={busy} onClick={save}>{busy ? "…" : "Save qualification"}</button>
      </div>

      <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
        <h3>IRS assessment</h3>
        <p className="os-muted">Run the assessment in the IRS portal, then record the result here. Always a range with disclosed method — never a point estimate. This seeds the client's baseline on signing.</p>
        <div className="os-formrow vals">
          <span className="os-flabel">Score / range (R$)</span>
          <input type="number" placeholder="IRS" value={(f.irs && f.irs.score) ?? ""} onChange={e => setIrs("score", e.target.value)} />
          <input type="number" placeholder="low" value={(f.irs && f.irs.low) ?? ""} onChange={e => setIrs("low", e.target.value)} />
          <input type="number" placeholder="base" value={(f.irs && f.irs.base) ?? ""} onChange={e => setIrs("base", e.target.value)} />
          <input type="number" placeholder="high" value={(f.irs && f.irs.high) ?? ""} onChange={e => setIrs("high", e.target.value)} />
        </div>
        <div className="os-formrow">
          <span className="os-flabel">Confidence</span>
          <select value={(f.irs && f.irs.confidence) || ""} onChange={e => setIrs("confidence", e.target.value)}>
            <option value="">—</option><option value="low">Low</option><option value="medium">Medium</option><option value="high">High</option>
          </select>
        </div>
        <button className="os-btn ghost" disabled={busy} onClick={save}>{busy ? "…" : "Save assessment"}</button>
      </div>

      <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
        <h3>Close</h3>
        {converted ? (
          <p>Signed — client engagement created. <button className="os-linkbtn" onClick={() => onConverted && onConverted(f.signed_client_id)}>Open client</button></p>
        ) : (
          <div>
            <p className="os-muted">Marks the deal Signed and creates the client engagement (carrying the assessment as baseline). Hands off to Onboarding.</p>
            <button className="os-btn gold" disabled={busy} onClick={convert}>{busy ? "…" : "Mark signed & create client"}</button>
          </div>
        )}
      </div>
    </div>
  );
}

function SalesView({ onPreview }) {
  const [sel, setSel] = useState(null);
  const [adding, setAdding] = useState(false);
  const { data, loading, reload } = useAsync(() => D.listDeals(), []);
  if (sel) return <DealDetail dealId={sel} onBack={() => { setSel(null); reload(); }} onConverted={(cid) => { setSel(null); reload(); if (cid) onPreview(cid); }} />;
  const deals = data || [];
  return (
    <div>
      <div className="os-view-h">
        <div><h1>Sales</h1><p>Lead → Qualified → Discovery → Assessment → Proposal → Signed. The IRS assessment does the selling.</p></div>
        <button className="os-btn gold" onClick={() => setAdding(a => !a)}>{adding ? "Close" : "+ New deal"}</button>
      </div>
      {adding ? <NewDealForm onCreated={() => { setAdding(false); reload(); }} /> : null}
      {D && D.mode === "local" ? <p className="os-muted">Local preview — demo deals.</p> : null}
      {loading ? <p className="os-muted">Loading…</p> : (
        <div style={{ display: "flex", gap: 12, overflowX: "auto", paddingBottom: 8, marginTop: 8 }}>
          {SALES_STAGES.map(st => {
            const ds = deals.filter(d => d.stage === st.id);
            return (
              <div key={st.id} style={{ minWidth: 210, flex: "1 0 210px" }}>
                <div className="os-qh" style={{ marginBottom: 8 }}><span className="os-qt sm">{st.label}</span><span className="os-qs">{ds.length}</span></div>
                {ds.map(d => <DealCard key={d.id} d={d} onOpen={() => setSel(d.id)} />)}
                {!ds.length ? <p className="os-muted" style={{ fontSize: 12 }}>—</p> : null}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

/* ===================================================================== */
/* ONBOARDING ROOM — the SOP-03 checklist that takes a signed client live. */
/* Two gates (payment, intake) block delivery; assigns the delivery owner. */
/* ===================================================================== */
const ONBOARDING_STEPS = [
  { id: "create_client", label: "Client created + 00–11 data room spun up" },
  { id: "billing", label: "Recurring invoice set up + first payment cleared", gate: true },
  { id: "intake", label: "FW-23 intake sent + received", gate: true },
  { id: "schedule", label: "Kickoff + monthly cadence scheduled" },
  { id: "kickoff", label: "Kickoff done — Q1 scope, spiral logic, pod intro" },
  { id: "pod", label: "Pod assigned (visa legality confirmed first)" },
  { id: "qa_gates", label: "Start date logged + 3 Q1 QA gates scheduled" },
];
function obState(onb) {
  const steps = (onb && onb.steps) || {};
  const total = ONBOARDING_STEPS.length;
  const done = ONBOARDING_STEPS.filter(s => steps[s.id]).length;
  const gatesOpen = ONBOARDING_STEPS.filter(s => s.gate).every(s => steps[s.id]);
  return { done, total, gatesOpen, live: done === total };
}

function OnbCard({ c, st, onOpen }) {
  return (
    <div className="os-card client" style={{ cursor: "pointer" }} onClick={onOpen}>
      <div className="os-card-h"><span className="os-nm">{c.name}</span>{st.live ? <span className="os-disc">Live</span> : null}</div>
      <div className="os-clientstats">
        <span>{c.sector || "—"}</span>
        <span><b>{st.done}/{st.total}</b> steps</span>
      </div>
      <div className="os-track sm"><div className="os-track-fill" style={{ width: (st.total ? 100 * st.done / st.total : 0) + "%" }} /></div>
      {!st.gatesOpen ? <div className="os-tag">Delivery blocked — payment + intake pending</div>
        : (!st.live ? <div className="os-tag">Gates clear — finishing setup</div> : null)}
    </div>
  );
}

function OnboardingDetail({ clientId, onBack }) {
  const { data, loading, reload } = useAsync(() => D.getClient(clientId), [clientId]);
  const [onb, setOnb] = useState(null);
  const [busy, setBusy] = useState(false);
  useEffect(() => {
    if (data) {
      const o = (data.engagement && data.engagement.onboarding) || { steps: { create_client: true }, delivery_owner: null, start_date: null };
      setOnb({ steps: { ...(o.steps || {}) }, delivery_owner: o.delivery_owner || "", start_date: o.start_date || "" });
    }
  }, [data]);
  if (loading || !onb) return <div><button className="os-back" onClick={onBack}><Icon name="back" /> Onboarding</button><p className="os-muted">Loading…</p></div>;

  const st = obState({ steps: onb.steps });
  const toggle = id => setOnb(s => ({ ...s, steps: { ...s.steps, [id]: !s.steps[id] } }));
  const save = async () => {
    setBusy(true);
    try { await D.updateEngagement(clientId, { onboarding: { steps: onb.steps, delivery_owner: onb.delivery_owner || null, start_date: onb.start_date || null } }); reload(); }
    catch (e) { alert((e && e.message) || "Error"); }
    setBusy(false);
  };

  return (
    <div>
      <div className="os-view-h">
        <div>
          <button className="os-back" onClick={onBack}><Icon name="back" /> Onboarding</button>
          <h1>{data.client.name}</h1>
          <p>{data.client.sector || "—"} · {st.done}/{st.total} steps{st.live ? " · live" : ""}</p>
        </div>
      </div>
      <div className={"os-gate " + (st.gatesOpen ? "open" : "closed")}>
        <b>Delivery gate:</b> {st.gatesOpen
          ? "Payment cleared + intake received — delivery can start."
          : "Blocked — payment must clear and intake must be received before delivery starts."}
      </div>
      <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
        <h3>Onboarding checklist</h3>
        {ONBOARDING_STEPS.map(s => (
          <label key={s.id} className="os-formrow" style={{ cursor: "pointer", alignItems: "center" }}>
            <input type="checkbox" checked={!!onb.steps[s.id]} onChange={() => toggle(s.id)} style={{ width: "auto", marginRight: 8 }} />
            <span>{s.label}{s.gate ? <em className="os-muted"> · gate</em> : null}</span>
          </label>
        ))}
      </div>
      <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
        <h3>Assignment</h3>
        <div className="os-formrow"><span className="os-flabel">Delivery employee</span><input value={onb.delivery_owner} onChange={e => setOnb(s => ({ ...s, delivery_owner: e.target.value }))} placeholder="Who owns this client in Delivery" /></div>
        <div className="os-formrow"><span className="os-flabel">Start date</span><input type="date" value={onb.start_date} onChange={e => setOnb(s => ({ ...s, start_date: e.target.value }))} /></div>
        <p className="os-muted">This client is scoped to the assigned delivery employee once employee accounts are on.</p>
      </div>
      <button className="os-btn gold" disabled={busy} onClick={save} style={{ marginTop: 14 }}>{busy ? "…" : "Save onboarding"}</button>
    </div>
  );
}

function OnboardingView() {
  const [sel, setSel] = useState(null);
  const { data, loading, reload } = useAsync(() => D.listClients(), []);
  if (sel) return <OnboardingDetail clientId={sel} onBack={() => { setSel(null); reload(); }} />;
  const withState = (data || []).map(c => ({ c, st: obState(c.onboarding) }));
  const onboarding = withState.filter(x => !x.st.live);
  const live = withState.filter(x => x.st.live);
  return (
    <div>
      <div className="os-view-h"><div><h1>Onboarding</h1><p>Signed → live in 5 business days. Delivery can't start until payment clears and intake is received.</p></div></div>
      <section className="os-section">
        <div className="os-qh"><span className="os-qt">In onboarding</span><h2>Clients being set up</h2><span className="os-qs">{onboarding.length}</span></div>
        {loading ? <p className="os-muted">Loading…</p> : (
          onboarding.length
            ? <div className="os-grid">{onboarding.map(({ c, st }) => <OnbCard key={c.id} c={c} st={st} onOpen={() => setSel(c.id)} />)}</div>
            : <p className="os-muted">No clients in onboarding. New signings from Sales land here.</p>
        )}
      </section>
      {live.length ? (
        <section className="os-section">
          <div className="os-qh"><span className="os-qt">Live</span><h2>Handed to Delivery</h2><span className="os-qs">{live.length}</span></div>
          <div className="os-grid">{live.map(({ c, st }) => <OnbCard key={c.id} c={c} st={st} onOpen={() => setSel(c.id)} />)}</div>
        </section>
      ) : null}
    </div>
  );
}

/* ===================================================================== */
/* CLIENT SUCCESS ROOM — cadence (10-day rule), MGR delivery, health,     */
/* renewal. The do-or-churn spine; advocacy layered on top.               */
/* ===================================================================== */
const MGR_STATUS = { pending: "Pending", drafting: "Drafting (Delivery)", sent: "Sent" };
function daysBetween(a, b) { return Math.floor((b - a) / 86400000); }
function csState(success) {
  const s = success || {};
  const today = new Date();
  const daysSince = s.last_contact ? daysBetween(new Date(s.last_contact), today) : null;
  const contactOverdue = daysSince != null && daysSince > 10;
  const npsLow = s.nps != null && s.nps < 8;
  const mgrSent = s.mgr_status === "sent";
  let monthsElapsed = null, renewalDue = false;
  if (s.contract_start) {
    monthsElapsed = Math.floor(daysBetween(new Date(s.contract_start), today) / 30.44);
    renewalDue = monthsElapsed >= 2; // past the 2-month mark → the 3-month-minimum decision is near
  }
  const attention = contactOverdue || npsLow || !!s.churn_risk || !mgrSent;
  return { daysSince, contactOverdue, npsLow, mgrSent, monthsElapsed, renewalDue, attention };
}

function CSCard({ c, cs, onOpen }) {
  const s = c.success || {};
  return (
    <div className="os-card client" style={{ cursor: "pointer" }} onClick={onOpen}>
      <div className="os-card-h"><span className="os-nm">{c.name}</span>{cs.attention ? <span className="os-irs rec">attention</span> : null}</div>
      <div className="os-clientstats">
        <span>{cs.daysSince != null ? cs.daysSince + "d since contact" : "no contact logged"}</span>
        <span>{s.nps != null ? "NPS " + s.nps : "NPS —"}</span>
      </div>
      <div className="os-tag">{cs.contactOverdue ? "10-day rule breached — " : ""}MGR {MGR_STATUS[s.mgr_status] || "pending"}{cs.renewalDue ? " — renewal due" : ""}</div>
    </div>
  );
}

function CSDetail({ clientId, onBack }) {
  const { data, loading, reload } = useAsync(() => D.getClient(clientId), [clientId]);
  const [f, setF] = useState(null);
  const [busy, setBusy] = useState(false);
  useEffect(() => {
    if (data) {
      const s = (data.engagement && data.engagement.success) || {};
      const fallbackStart = (data.engagement && data.engagement.onboarding && data.engagement.onboarding.start_date) || "";
      setF({
        last_contact: s.last_contact || "", mgr_status: s.mgr_status || "pending", mgr_last_sent: s.mgr_last_sent || "",
        nps: s.nps != null ? s.nps : "", churn_risk: !!s.churn_risk, contract_start: s.contract_start || fallbackStart,
        notes: s.notes || "", referral_asked: !!s.referral_asked, testimonial: !!s.testimonial
      });
    }
  }, [data]);
  if (loading || !f) return <div><button className="os-back" onClick={onBack}><Icon name="back" /> Client Success</button><p className="os-muted">Loading…</p></div>;

  const num = v => (v === "" || v == null ? null : Number(v));
  const setV = (k, v) => setF(s => ({ ...s, [k]: v }));
  const cs = csState({ last_contact: f.last_contact, nps: num(f.nps), churn_risk: f.churn_risk, mgr_status: f.mgr_status, contract_start: f.contract_start });
  const save = async () => {
    setBusy(true);
    try {
      await D.updateEngagement(clientId, { success: {
        last_contact: f.last_contact || null, mgr_status: f.mgr_status, mgr_last_sent: f.mgr_last_sent || null,
        nps: num(f.nps), churn_risk: f.churn_risk, contract_start: f.contract_start || null,
        notes: f.notes || null, referral_asked: f.referral_asked, testimonial: f.testimonial
      } });
      reload();
    } catch (e) { alert((e && e.message) || "Error"); }
    setBusy(false);
  };

  return (
    <div>
      <div className="os-view-h">
        <div>
          <button className="os-back" onClick={onBack}><Icon name="back" /> Client Success</button>
          <h1>{data.client.name}</h1>
          <p>{cs.daysSince != null ? cs.daysSince + " days since last contact" : "no contact logged"}{cs.monthsElapsed != null ? " · month " + (cs.monthsElapsed + 1) + " of engagement" : ""}</p>
        </div>
      </div>
      <div className={"os-gate " + (cs.contactOverdue ? "closed" : "open")}>
        <b>10-day rule:</b> {cs.contactOverdue ? "Breached — reach out today. Never let 10 days pass without contact." : "On track."}
      </div>

      <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
        <h3>Cadence</h3>
        <div className="os-formrow"><span className="os-flabel">Last contact</span><input type="date" value={f.last_contact} onChange={e => setV("last_contact", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Notes</span><input value={f.notes} onChange={e => setV("notes", e.target.value)} placeholder="Last touchpoint, concerns, next step" /></div>
      </div>

      <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
        <h3>Monthly Growth Report</h3>
        <p className="os-muted">Built by Delivery, delivered by you by the 5th. Set to Sent once it's in the client's portal.</p>
        <div className="os-formrow">
          <span className="os-flabel">This cycle</span>
          <select value={f.mgr_status} onChange={e => setV("mgr_status", e.target.value)}>
            <option value="pending">Pending</option><option value="drafting">Drafting (Delivery)</option><option value="sent">Sent</option>
          </select>
        </div>
        <div className="os-formrow"><span className="os-flabel">Last sent</span><input type="date" value={f.mgr_last_sent} onChange={e => setV("mgr_last_sent", e.target.value)} /></div>
      </div>

      <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
        <h3>Health</h3>
        <div className="os-formrow"><span className="os-flabel">Satisfaction / NPS (target &gt; 8)</span><input type="number" step="any" value={f.nps} onChange={e => setV("nps", e.target.value)} /></div>
        <label className="os-formrow" style={{ cursor: "pointer", alignItems: "center" }}>
          <input type="checkbox" checked={f.churn_risk} onChange={e => setV("churn_risk", e.target.checked)} style={{ width: "auto", marginRight: 8 }} /><span>Churn risk</span>
        </label>
        {cs.npsLow ? <p className="os-kill"><b>Below target.</b> Satisfaction under 8 — own the intervention.</p> : null}
      </div>

      <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
        <h3>Renewal &amp; advocacy</h3>
        <div className="os-formrow"><span className="os-flabel">Contract start</span><input type="date" value={f.contract_start} onChange={e => setV("contract_start", e.target.value)} /></div>
        <p className="os-muted">3-month minimum, then 30-day notice.{cs.renewalDue ? " Renewal/retention touchpoint due — run the conversation before the window." : ""}</p>
        <label className="os-formrow" style={{ cursor: "pointer", alignItems: "center" }}>
          <input type="checkbox" checked={f.referral_asked} onChange={e => setV("referral_asked", e.target.checked)} style={{ width: "auto", marginRight: 8 }} /><span>Referral asked (month 2+)</span>
        </label>
        <label className="os-formrow" style={{ cursor: "pointer", alignItems: "center" }}>
          <input type="checkbox" checked={f.testimonial} onChange={e => setV("testimonial", e.target.checked)} style={{ width: "auto", marginRight: 8 }} /><span>Testimonial / case study captured → Demand Gen</span>
        </label>
      </div>

      <button className="os-btn gold" disabled={busy} onClick={save} style={{ marginTop: 14 }}>{busy ? "…" : "Save"}</button>
    </div>
  );
}

function CSView() {
  const [sel, setSel] = useState(null);
  const { data, loading, reload } = useAsync(() => D.listClients(), []);
  if (sel) return <CSDetail clientId={sel} onBack={() => { setSel(null); reload(); }} />;
  const rows = (data || []).map(c => ({ c, cs: csState(c.success) }));
  const flagged = rows.filter(x => x.cs.attention);
  return (
    <div>
      <div className="os-view-h"><div><h1>Client Success</h1><p>Stays, grows, refers. The spine: MGR by the 5th, the monthly session, the 10-day rule, satisfaction, renewal.</p></div></div>
      {flagged.length
        ? <div className="os-gate closed"><b>Needs attention ({flagged.length}):</b> {flagged.map(x => x.c.name).join(" · ")}</div>
        : <div className="os-gate open"><b>All clients on track.</b></div>}
      {loading ? <p className="os-muted">Loading…</p> : (
        <div className="os-grid" style={{ marginTop: 14 }}>
          {rows.map(({ c, cs }) => <CSCard key={c.id} c={c} cs={cs} onOpen={() => setSel(c.id)} />)}
          {!rows.length ? <p className="os-muted">No active clients yet.</p> : null}
        </div>
      )}
    </div>
  );
}

/* ===================================================================== */
/* DEMAND GENERATION ROOM — content cadence board + lead inbox.            */
/* The lead inbox REUSES deals at stage "lead"; "Send to Sales" promotes.   */
/* ===================================================================== */
const CADENCE_STAGES = [
  { id: "idea", label: "Idea" }, { id: "drafting", label: "Drafting" },
  { id: "scheduled", label: "Scheduled" }, { id: "published", label: "Published" },
];
const CHANNEL_LABEL = { linkedin: "LinkedIn", youtube: "YouTube", carousel: "Carousel" };
const MINI_IRS_CTA = "Find out how investment-ready you are — free mini-assessment.";

function LeadCard({ d, onOpen, onSend }) {
  return (
    <div className="os-card client" style={{ cursor: "pointer" }} onClick={onOpen}>
      <div className="os-card-h"><span className="os-nm">{d.company}</span></div>
      <div className="os-clientstats">
        <span>{d.sector || "—"}{d.revenue ? " · " + fmtMoney(d.revenue) : ""}</span>
        <span>{SOURCE_LABEL[d.source] || d.source || "—"}</span>
      </div>
      {d.notes ? <div className="os-tag">{d.notes}</div> : null}
      <button className="os-btn ghost sm" onClick={e => { e.stopPropagation(); onSend(); }}>Send to Sales</button>
    </div>
  );
}

function PieceCard({ p, onOpen }) {
  return (
    <div className="os-card client" style={{ marginBottom: 10, cursor: "pointer" }} onClick={onOpen}>
      <div className="os-card-h"><span className="os-nm">{p.title}</span></div>
      <div className="os-clientstats"><span>{CHANNEL_LABEL[p.channel] || p.channel}</span><span>{p.publish_date || "—"}</span></div>
      {p.angle ? <div className="os-tag">{p.angle}</div> : null}
    </div>
  );
}

function NewPieceForm({ onCreated }) {
  const [f, setF] = useState({ title: "", channel: "linkedin", stage: "idea", angle: "" });
  const [busy, setBusy] = useState(false);
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const create = async () => {
    if (!f.title.trim()) return;
    setBusy(true);
    try { await D.addItem("content_pieces", { title: f.title.trim(), channel: f.channel, stage: f.stage, angle: f.angle || null, cta: MINI_IRS_CTA, publish_date: null, fwRef: null, notes: null }); onCreated(); }
    catch (e) { alert((e && e.message) || "Error"); setBusy(false); }
  };
  return (
    <div className="os-panel" style={{ maxWidth: 560 }}>
      <h3>New piece</h3>
      <div className="os-formrow"><input placeholder="Title / angle" value={f.title} onChange={e => set("title", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Channel</span><select value={f.channel} onChange={e => set("channel", e.target.value)}><option value="linkedin">LinkedIn</option><option value="youtube">YouTube</option><option value="carousel">Carousel</option></select></div>
      <div className="os-formrow"><span className="os-flabel">Stage</span><select value={f.stage} onChange={e => set("stage", e.target.value)}>{CADENCE_STAGES.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}</select></div>
      <div className="os-formrow"><input placeholder="The valuation / IR idea" value={f.angle} onChange={e => set("angle", e.target.value)} /></div>
      <button className="os-btn gold" disabled={busy} onClick={create}>{busy ? "…" : "Add to board"}</button>
    </div>
  );
}

function PieceDetail({ pieceId, onBack }) {
  const { data, loading, reload } = useAsync(() => D.listItems("content_pieces").then(a => a.find(x => x.id === pieceId)), [pieceId]);
  const [f, setF] = useState(null);
  const [busy, setBusy] = useState(false);
  useEffect(() => { if (data) setF({ ...data }); }, [data]);
  if (loading || !f) return <div><button className="os-back" onClick={onBack}><Icon name="back" /> Demand Generation</button><p className="os-muted">Loading…</p></div>;
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const save = async () => { setBusy(true); try { await D.updateItem("content_pieces", pieceId, { title: f.title, channel: f.channel, stage: f.stage, angle: f.angle || null, cta: f.cta || null, publish_date: f.publish_date || null, notes: f.notes || null }); reload(); } catch (e) { alert((e && e.message) || "Error"); } setBusy(false); };
  const del = async () => { if (!confirm("Delete this content piece?")) return; await D.removeItem("content_pieces", pieceId); onBack(); };
  return (
    <div>
      <div className="os-view-h"><div><button className="os-back" onClick={onBack}><Icon name="back" /> Demand Generation</button><h1>{f.title}</h1><p>{CHANNEL_LABEL[f.channel] || f.channel}</p></div></div>
      {f.stage === "published" && !f.publish_date ? <div className="os-gate closed"><b>Published with no date.</b> Set the publish date.</div> : null}
      <div className="os-panel" style={{ maxWidth: 720 }}>
        <h3>Content piece</h3>
        <div className="os-formrow"><span className="os-flabel">Title</span><input value={f.title} onChange={e => set("title", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Channel</span><select value={f.channel} onChange={e => set("channel", e.target.value)}><option value="linkedin">LinkedIn</option><option value="youtube">YouTube</option><option value="carousel">Carousel</option></select></div>
        <div className="os-formrow"><span className="os-flabel">Stage</span><select value={f.stage} onChange={e => set("stage", e.target.value)}>{CADENCE_STAGES.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}</select></div>
        <div className="os-formrow"><span className="os-flabel">Angle</span><input value={f.angle || ""} onChange={e => set("angle", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">CTA</span><input value={f.cta || ""} onChange={e => set("cta", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Publish date</span><input type="date" value={f.publish_date || ""} onChange={e => set("publish_date", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Notes</span><input value={f.notes || ""} onChange={e => set("notes", e.target.value)} /></div>
        <p className="os-muted">One CTA only — the mini-IRS.{f.fwRef ? " · source: " + f.fwRef : ""}</p>
        <button className="os-btn gold" disabled={busy} onClick={save}>{busy ? "…" : "Save"}</button>
        <button className="os-btn ghost" onClick={del} style={{ marginLeft: 8 }}>Delete</button>
      </div>
    </div>
  );
}

function DemandView({ onPreview }) {
  const [selPiece, setSelPiece] = useState(null);
  const [selLead, setSelLead] = useState(null);
  const [adding, setAdding] = useState(false);
  const { data, loading, reload } = useAsync(() => Promise.all([D.listItems("content_pieces"), D.listDeals()]), []);
  if (selPiece) return <PieceDetail pieceId={selPiece} onBack={() => { setSelPiece(null); reload(); }} />;
  if (selLead) return <DealDetail dealId={selLead} onBack={() => { setSelLead(null); reload(); }} onConverted={(cid) => { setSelLead(null); reload(); if (cid && onPreview) onPreview(cid); }} />;
  const pieces = (data && data[0]) || [];
  const leads = ((data && data[1]) || []).filter(d => d.stage === "lead");
  const sendToSales = async (id) => { await D.updateDeal(id, { stage: "qualified" }); reload(); };
  return (
    <div>
      <div className="os-view-h">
        <div><h1>Demand Generation</h1><p>Steady inbound so Sales always has someone to qualify. The hook is the free mini-IRS.</p></div>
        <button className="os-btn gold" onClick={() => setAdding(a => !a)}>{adding ? "Close" : "+ New piece"}</button>
      </div>
      {adding ? <NewPieceForm onCreated={() => { setAdding(false); reload(); }} /> : null}
      {D && D.mode === "local" ? <p className="os-muted">Local preview — demo data.</p> : null}
      <section className="os-section">
        <div className="os-qh"><span className="os-qt">Lead inbox</span><h2>Captured leads</h2><span className="os-qs">{leads.length}</span></div>
        {loading ? <p className="os-muted">Loading…</p> : (
          leads.length ? <div className="os-grid">{leads.map(d => <LeadCard key={d.id} d={d} onOpen={() => setSelLead(d.id)} onSend={() => sendToSales(d.id)} />)}</div>
            : <p className="os-muted">No new leads — mini-IRS submissions land here.</p>
        )}
      </section>
      <section className="os-section">
        <div className="os-qh"><span className="os-qt">Cadence</span><h2>Content board</h2><span className="os-qs">{pieces.length}</span></div>
        <div style={{ display: "flex", gap: 12, overflowX: "auto", paddingBottom: 8 }}>
          {CADENCE_STAGES.map(st => {
            const ps = pieces.filter(p => p.stage === st.id);
            return (
              <div key={st.id} style={{ minWidth: 210, flex: "1 0 210px" }}>
                <div className="os-qh" style={{ marginBottom: 8 }}><span className="os-qt sm">{st.label}</span><span className="os-qs">{ps.length}</span></div>
                {ps.map(p => <PieceCard key={p.id} p={p} onOpen={() => setSelPiece(p.id)} />)}
                {!ps.length ? <p className="os-muted" style={{ fontSize: 12 }}>—</p> : null}
              </div>
            );
          })}
        </div>
      </section>
    </div>
  );
}

/* ===================================================================== */
/* FINANCE & ADMIN ROOM (owner-only) — receivables, compliance, contracts. */
/* Conta Azul stays the book of record; this is status + reminders.        */
/* ===================================================================== */
const INV_KIND = { retainer: "Retainer", facilitation: "Facilitation", expansion: "Expansion" };
const CMP_OBLIG = { das: "DAS", fator_r: "Fator-R", ecd: "ECD", defis: "DEFIS", inpi: "INPI", cnpj: "CNPJ", crnm: "CRNM", intern_visa: "Intern visa" };
const CON_TYPE = { client: "Client", nda: "NDA", estagio: "Estágio", partner: "Partner" };
function isOverdue(dateISO) { if (!dateISO) return false; return new Date(dateISO) < new Date(); }
function invLate(inv) { return inv.status === "late" || (inv.status === "issued" && !inv.paid_date && isOverdue(inv.due_date)); }

function InvoiceCard({ inv, onOpen }) {
  const late = invLate(inv);
  return (
    <div className="os-card client" style={{ cursor: "pointer" }} onClick={onOpen}>
      <div className="os-card-h"><span className="os-nm">{inv.client_name}</span>{inv.status === "paid" ? <span className="os-disc">paid</span> : null}</div>
      <div className="os-clientstats"><span>{fmtMoney(inv.amount)} · {INV_KIND[inv.kind] || inv.kind}</span><span>{inv.due_date}</span></div>
      <div className="os-tag">{late ? "Late — chase" : (inv.status === "paid" ? "Paid" : "Issued")}</div>
    </div>
  );
}
function ComplianceCard({ c, onOpen }) {
  const over = c.status === "upcoming" && isOverdue(c.due_date);
  return (
    <div className="os-card client" style={{ cursor: "pointer" }} onClick={onOpen}>
      <div className="os-card-h"><span className="os-nm">{c.title}</span>{c.status === "done" ? <span className="os-disc">done</span> : null}</div>
      <div className="os-clientstats"><span>{CMP_OBLIG[c.obligation] || c.obligation} · {c.cadence}</span><span>{c.due_date}</span></div>
      <div className="os-tag">{over ? "Overdue" : c.owner}</div>
    </div>
  );
}
function ContractCard({ c, onOpen }) {
  return (
    <div className="os-card client" style={{ cursor: "pointer" }} onClick={onOpen}>
      <div className="os-card-h"><span className="os-nm">{c.name}</span></div>
      <div className="os-clientstats"><span>{CON_TYPE[c.type] || c.type}</span><span>{c.counterparty}</span></div>
      <div className="os-tag">{c.status}{c.docusign ? " · DocuSign" : ""}</div>
    </div>
  );
}

function NewInvoiceForm({ clients, onCreated }) {
  const [f, setF] = useState({ client_id: (clients[0] && clients[0].id) || "", kind: "retainer", amount: "8000", due_date: "", method: "pix" });
  const [busy, setBusy] = useState(false);
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const create = async () => {
    const cl = clients.find(c => c.id === f.client_id);
    setBusy(true);
    try { await D.addItem("finance_invoices", { client_id: f.client_id || null, client_name: cl ? cl.name : "—", kind: f.kind, amount: f.amount ? Number(f.amount) : null, due_date: f.due_date || null, paid_date: null, method: f.method, status: "issued", notes: null }); onCreated(); }
    catch (e) { alert((e && e.message) || "Error"); setBusy(false); }
  };
  return (
    <div className="os-panel" style={{ maxWidth: 560 }}>
      <h3>New invoice</h3>
      <div className="os-formrow"><span className="os-flabel">Client</span><select value={f.client_id} onChange={e => set("client_id", e.target.value)}>{clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}</select></div>
      <div className="os-formrow"><span className="os-flabel">Kind</span><select value={f.kind} onChange={e => set("kind", e.target.value)}>{Object.keys(INV_KIND).map(k => <option key={k} value={k}>{INV_KIND[k]}</option>)}</select></div>
      <div className="os-formrow"><span className="os-flabel">Amount (R$)</span><input type="number" value={f.amount} onChange={e => set("amount", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Due date</span><input type="date" value={f.due_date} onChange={e => set("due_date", e.target.value)} /></div>
      <button className="os-btn gold" disabled={busy} onClick={create}>{busy ? "…" : "Issue invoice"}</button>
    </div>
  );
}

function FinanceDetail({ sel, onBack }) {
  const { data, loading, reload } = useAsync(() => D.listItems(sel.collection).then(a => a.find(x => x.id === sel.id)), [sel.collection, sel.id]);
  const [f, setF] = useState(null);
  const [busy, setBusy] = useState(false);
  useEffect(() => { if (data) setF({ ...data }); }, [data]);
  if (loading || !f) return <div><button className="os-back" onClick={onBack}><Icon name="back" /> Finance</button><p className="os-muted">Loading…</p></div>;
  const num = v => (v === "" || v == null ? null : Number(v));
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const save = async (patch) => { setBusy(true); try { await D.updateItem(sel.collection, sel.id, patch); reload(); } catch (e) { alert((e && e.message) || "Error"); } setBusy(false); };
  const title = f.client_name || f.title || f.name || "Item";
  return (
    <div>
      <div className="os-view-h"><div><button className="os-back" onClick={onBack}><Icon name="back" /> Finance</button><h1>{title}</h1></div></div>
      {sel.collection === "finance_invoices" ? (
        <div>
          <div className={"os-gate " + (invLate(f) ? "closed" : "open")}><b>{invLate(f) ? "Late — past due, on the chase list." : "Current."}</b></div>
          <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
            <h3>Invoice</h3>
            <div className="os-formrow"><span className="os-flabel">Kind</span><select value={f.kind} onChange={e => set("kind", e.target.value)}>{Object.keys(INV_KIND).map(k => <option key={k} value={k}>{INV_KIND[k]}</option>)}</select></div>
            <div className="os-formrow"><span className="os-flabel">Amount (R$)</span><input type="number" value={f.amount ?? ""} onChange={e => set("amount", e.target.value)} /></div>
            <div className="os-formrow"><span className="os-flabel">Due date</span><input type="date" value={f.due_date || ""} onChange={e => set("due_date", e.target.value)} /></div>
            <div className="os-formrow"><span className="os-flabel">Paid date</span><input type="date" value={f.paid_date || ""} onChange={e => set("paid_date", e.target.value)} /></div>
            <div className="os-formrow"><span className="os-flabel">Method</span><select value={f.method} onChange={e => set("method", e.target.value)}><option value="pix">PIX</option><option value="boleto">Boleto</option></select></div>
            <div className="os-formrow"><span className="os-flabel">Status</span><select value={f.status} onChange={e => set("status", e.target.value)}><option value="issued">Issued</option><option value="paid">Paid</option><option value="late">Late</option></select></div>
            <div className="os-formrow"><span className="os-flabel">Notes</span><input value={f.notes || ""} onChange={e => set("notes", e.target.value)} /></div>
            <button className="os-btn gold" disabled={busy} onClick={() => save({ kind: f.kind, amount: num(f.amount), due_date: f.due_date || null, paid_date: f.paid_date || null, method: f.method, status: f.status, notes: f.notes || null })}>{busy ? "…" : "Save invoice"}</button>
          </div>
        </div>
      ) : null}
      {sel.collection === "finance_compliance" ? (
        <div className="os-panel" style={{ maxWidth: 720 }}>
          <h3>Obligation</h3>
          <div className="os-formrow"><span className="os-flabel">Title</span><input value={f.title || ""} onChange={e => set("title", e.target.value)} /></div>
          <div className="os-formrow"><span className="os-flabel">Obligation</span><select value={f.obligation} onChange={e => set("obligation", e.target.value)}>{Object.keys(CMP_OBLIG).map(k => <option key={k} value={k}>{CMP_OBLIG[k]}</option>)}</select></div>
          <div className="os-formrow"><span className="os-flabel">Cadence</span><select value={f.cadence} onChange={e => set("cadence", e.target.value)}><option value="monthly">Monthly</option><option value="annual">Annual</option><option value="watch">Watch</option><option value="one_off">One-off</option></select></div>
          <div className="os-formrow"><span className="os-flabel">Due date</span><input type="date" value={f.due_date || ""} onChange={e => set("due_date", e.target.value)} /></div>
          <div className="os-formrow"><span className="os-flabel">Status</span><select value={f.status} onChange={e => set("status", e.target.value)}><option value="upcoming">Upcoming</option><option value="done">Done</option><option value="overdue">Overdue</option></select></div>
          <div className="os-formrow"><span className="os-flabel">Owner</span><select value={f.owner} onChange={e => set("owner", e.target.value)}><option value="bureau">Bureau</option><option value="founder">Founder</option></select></div>
          <div className="os-formrow"><span className="os-flabel">Notes</span><input value={f.notes || ""} onChange={e => set("notes", e.target.value)} /></div>
          <button className="os-btn gold" disabled={busy} onClick={() => save({ title: f.title, obligation: f.obligation, cadence: f.cadence, due_date: f.due_date || null, status: f.status, owner: f.owner, notes: f.notes || null })}>{busy ? "…" : "Save"}</button>
        </div>
      ) : null}
      {sel.collection === "finance_contracts" ? (
        <div className="os-panel" style={{ maxWidth: 720 }}>
          <h3>Contract</h3>
          <div className="os-formrow"><span className="os-flabel">Name</span><input value={f.name || ""} onChange={e => set("name", e.target.value)} /></div>
          <div className="os-formrow"><span className="os-flabel">Type</span><select value={f.type} onChange={e => set("type", e.target.value)}>{Object.keys(CON_TYPE).map(k => <option key={k} value={k}>{CON_TYPE[k]}</option>)}</select></div>
          <div className="os-formrow"><span className="os-flabel">Counterparty</span><input value={f.counterparty || ""} onChange={e => set("counterparty", e.target.value)} /></div>
          <div className="os-formrow"><span className="os-flabel">Signed date</span><input type="date" value={f.signed_date || ""} onChange={e => set("signed_date", e.target.value)} /></div>
          <div className="os-formrow"><span className="os-flabel">Status</span><select value={f.status} onChange={e => set("status", e.target.value)}><option value="draft">Draft</option><option value="sent">Sent</option><option value="signed">Signed</option></select></div>
          <label className="os-formrow" style={{ cursor: "pointer", alignItems: "center" }}><input type="checkbox" checked={!!f.docusign} onChange={e => set("docusign", e.target.checked)} style={{ width: "auto", marginRight: 8 }} /><span>Routed via DocuSign</span></label>
          <button className="os-btn gold" disabled={busy} onClick={() => save({ name: f.name, type: f.type, counterparty: f.counterparty || null, signed_date: f.signed_date || null, status: f.status, docusign: !!f.docusign })}>{busy ? "…" : "Save"}</button>
        </div>
      ) : null}
    </div>
  );
}

function FinanceView() {
  const [sel, setSel] = useState(null);
  const [adding, setAdding] = useState(false);
  const { data, loading, reload } = useAsync(() => Promise.all([D.listItems("finance_invoices"), D.listItems("finance_compliance"), D.listItems("finance_contracts"), D.listClients()]), []);
  if (sel) return <FinanceDetail sel={sel} onBack={() => { setSel(null); reload(); }} />;
  const invoices = (data && data[0]) || [], compliance = (data && data[1]) || [], contracts = (data && data[2]) || [], clients = (data && data[3]) || [];
  const outstanding = invoices.filter(i => i.status !== "paid");
  const owed = outstanding.reduce((s, i) => s + (i.amount || 0), 0);
  const lateCount = invoices.filter(invLate).length;
  return (
    <div>
      <div className="os-view-h">
        <div><h1>Finance</h1><p>The company's money and its legal standing. Receivables, the compliance calendar, the contracts store. Conta Azul stays the book of record.</p></div>
        <button className="os-btn gold" onClick={() => setAdding(a => !a)}>{adding ? "Close" : "+ New invoice"}</button>
      </div>
      <div className={"os-gate " + (lateCount ? "closed" : "open")}><b>{lateCount ? "Outstanding receivables: " + outstanding.length + " · " + fmtMoney(owed) + " (" + lateCount + " late)." : "Receivables current."}</b></div>
      {adding ? <NewInvoiceForm clients={clients} onCreated={() => { setAdding(false); reload(); }} /> : null}
      {loading ? <p className="os-muted">Loading…</p> : (
        <div>
          <section className="os-section"><div className="os-qh"><span className="os-qt">Receivables</span><h2>Invoices</h2><span className="os-qs">{invoices.length}</span></div>
            <div className="os-grid">{invoices.map(i => <InvoiceCard key={i.id} inv={i} onOpen={() => setSel({ collection: "finance_invoices", id: i.id })} />)}</div></section>
          <section className="os-section"><div className="os-qh"><span className="os-qt">Compliance</span><h2>Calendar</h2><span className="os-qs">{compliance.length}</span></div>
            <div className="os-grid">{compliance.map(c => <ComplianceCard key={c.id} c={c} onOpen={() => setSel({ collection: "finance_compliance", id: c.id })} />)}</div></section>
          <section className="os-section"><div className="os-qh"><span className="os-qt">Contracts</span><h2>Store</h2><span className="os-qs">{contracts.length}</span></div>
            <div className="os-grid">{contracts.map(c => <ContractCard key={c.id} c={c} onOpen={() => setSel({ collection: "finance_contracts", id: c.id })} />)}</div></section>
        </div>
      )}
    </div>
  );
}

/* ===================================================================== */
/* TALENT / HR ROOM — cohort funnel (16-week clock) + intern pipeline      */
/* with the visa gate (hard block on pod assignment) + training library.   */
/* ===================================================================== */
const INTERN_STAGES = [
  { id: "applied", label: "Applied" }, { id: "screened", label: "Screened" },
  { id: "interviewed", label: "Interviewed" }, { id: "selected", label: "Selected" },
  { id: "active", label: "Active" }, { id: "alumni", label: "Alumni" },
];
const SPECIALIZATIONS = [{ id: "finance", label: "Finance" }, { id: "strategy", label: "Strategy" }, { id: "legal", label: "Legal" }, { id: "diagnostic", label: "Diagnostic" }];
const COHORT_STATUS = { planning: "Planning", recruiting: "Recruiting", selected: "Selected", closed: "Closed" };
function weeksUntil(dateISO) { if (!dateISO) return null; return Math.ceil((new Date(dateISO) - new Date()) / (7 * 86400000)); }
function visaCleared(v) { v = v || {}; return !!(v.guidance_sent && v.docs_submitted && v.legality_confirmed); }
function specLabel(id) { return (SPECIALIZATIONS.find(s => s.id === id) || {}).label || id; }

function InternCard({ i, onOpen }) {
  const cleared = visaCleared(i.visa);
  return (
    <div className="os-card client" style={{ marginBottom: 10, cursor: "pointer" }} onClick={onOpen}>
      <div className="os-card-h"><span className="os-nm">{i.name}</span>{cleared ? null : <span className="os-irs rec">visa</span>}</div>
      <div className="os-clientstats"><span>{specLabel(i.specialization)}</span><span>{i.english}</span></div>
      <div className="os-tag">{cleared ? (i.pod_client_id ? "Assigned to a pod" : "Visa cleared — assignable") : "Visa pending — pod blocked"}</div>
    </div>
  );
}
function TrainingCard({ t }) {
  return (
    <div className="os-card client">
      <div className="os-card-h"><span className="os-nm">{t.title}</span><span className="os-disc">{t.category}</span></div>
      <div className="os-tag">{t.required ? "Required for pod" : "Optional"}{t.fwRef ? " · " + t.fwRef : ""}</div>
    </div>
  );
}

function NewInternForm({ cohorts, onCreated }) {
  const [f, setF] = useState({ name: "", specialization: "finance", english: "B2", cohort_id: (cohorts[0] && cohorts[0].id) || "" });
  const [busy, setBusy] = useState(false);
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const create = async () => {
    if (!f.name.trim()) return;
    setBusy(true);
    try { await D.addItem("talent_interns", { name: f.name.trim(), cohort_id: f.cohort_id || null, university: "", specialization: f.specialization, stage: "applied", english: f.english, visa: { guidance_sent: false, docs_submitted: false, legality_confirmed: false, confirmed_date: null }, pod_client_id: null, start_date: null, notes: null }); onCreated(); }
    catch (e) { alert((e && e.message) || "Error"); setBusy(false); }
  };
  return (
    <div className="os-panel" style={{ maxWidth: 560 }}>
      <h3>New candidate</h3>
      <div className="os-formrow"><input placeholder="Name" value={f.name} onChange={e => set("name", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Specialization</span><select value={f.specialization} onChange={e => set("specialization", e.target.value)}>{SPECIALIZATIONS.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}</select></div>
      <div className="os-formrow"><span className="os-flabel">English</span><select value={f.english} onChange={e => set("english", e.target.value)}><option value="B1">B1</option><option value="B2">B2</option><option value="C1">C1</option><option value="C2">C2</option></select></div>
      <button className="os-btn gold" disabled={busy} onClick={create}>{busy ? "…" : "Add candidate"}</button>
    </div>
  );
}

function InternDetail({ internId, clients, onBack }) {
  const { data, loading, reload } = useAsync(() => D.listItems("talent_interns").then(a => a.find(x => x.id === internId)), [internId]);
  const [f, setF] = useState(null);
  const [busy, setBusy] = useState(false);
  useEffect(() => { if (data) setF({ ...data, visa: { ...(data.visa || {}) } }); }, [data]);
  if (loading || !f) return <div><button className="os-back" onClick={onBack}><Icon name="back" /> Talent</button><p className="os-muted">Loading…</p></div>;
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const setVisa = (k, v) => setF(s => ({ ...s, visa: { ...s.visa, [k]: v } }));
  const cleared = visaCleared(f.visa);
  const save = async (patch) => { setBusy(true); try { await D.updateItem("talent_interns", internId, patch); reload(); } catch (e) { alert((e && e.message) || "Error"); } setBusy(false); };
  return (
    <div>
      <div className="os-view-h"><div><button className="os-back" onClick={onBack}><Icon name="back" /> Talent</button><h1>{f.name}</h1><p>{specLabel(f.specialization)} · {f.stage}</p></div></div>
      <div className={"os-gate " + (cleared ? "open" : "closed")}><b>Visa gate:</b> {cleared ? "Cleared — assignable to a pod." : "Blocked — confirm legality before any flight or pod assignment. Non-negotiable."}</div>
      <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
        <h3>Candidate</h3>
        <div className="os-formrow"><span className="os-flabel">Name</span><input value={f.name} onChange={e => set("name", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">University</span><input value={f.university || ""} onChange={e => set("university", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Specialization</span><select value={f.specialization} onChange={e => set("specialization", e.target.value)}>{SPECIALIZATIONS.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}</select></div>
        <div className="os-formrow"><span className="os-flabel">English</span><select value={f.english} onChange={e => set("english", e.target.value)}><option value="B1">B1</option><option value="B2">B2</option><option value="C1">C1</option><option value="C2">C2</option></select></div>
        <div className="os-formrow"><span className="os-flabel">Stage</span><select value={f.stage} onChange={e => set("stage", e.target.value)}>{INTERN_STAGES.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}</select></div>
        <div className="os-formrow"><span className="os-flabel">Notes</span><input value={f.notes || ""} onChange={e => set("notes", e.target.value)} /></div>
        <button className="os-btn gold" disabled={busy} onClick={() => save({ name: f.name, university: f.university || null, specialization: f.specialization, english: f.english, stage: f.stage, notes: f.notes || null })}>{busy ? "…" : "Save"}</button>
      </div>
      <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
        <h3>Visa gate</h3>
        <label className="os-formrow" style={{ cursor: "pointer", alignItems: "center" }}><input type="checkbox" checked={!!f.visa.guidance_sent} onChange={e => setVisa("guidance_sent", e.target.checked)} style={{ width: "auto", marginRight: 8 }} /><span>Visa guidance sent</span></label>
        <label className="os-formrow" style={{ cursor: "pointer", alignItems: "center" }}><input type="checkbox" checked={!!f.visa.docs_submitted} onChange={e => setVisa("docs_submitted", e.target.checked)} style={{ width: "auto", marginRight: 8 }} /><span>Documents submitted</span></label>
        <label className="os-formrow" style={{ cursor: "pointer", alignItems: "center" }}><input type="checkbox" checked={!!f.visa.legality_confirmed} onChange={e => setVisa("legality_confirmed", e.target.checked)} style={{ width: "auto", marginRight: 8 }} /><span>Legality confirmed (the hard gate)</span></label>
        <div className="os-formrow"><span className="os-flabel">Confirmed date</span><input type="date" value={f.visa.confirmed_date || ""} onChange={e => setVisa("confirmed_date", e.target.value)} /></div>
        <button className="os-btn ghost" disabled={busy} onClick={() => save({ visa: f.visa })}>{busy ? "…" : "Save visa status"}</button>
      </div>
      <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
        <h3>Pod assignment</h3>
        {cleared ? (
          <div>
            <div className="os-formrow"><span className="os-flabel">Pod (client)</span><select value={f.pod_client_id || ""} onChange={e => set("pod_client_id", e.target.value || null)}><option value="">— unassigned —</option>{clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}</select></div>
            <div className="os-formrow"><span className="os-flabel">Start date</span><input type="date" value={f.start_date || ""} onChange={e => set("start_date", e.target.value)} /></div>
            <button className="os-btn gold" disabled={busy} onClick={() => save({ pod_client_id: f.pod_client_id || null, start_date: f.start_date || null })}>{busy ? "…" : "Save assignment"}</button>
          </div>
        ) : <p className="os-kill"><b>Confirm visa legality first.</b> Pod assignment is blocked until the gate clears.</p>}
      </div>
    </div>
  );
}

function TalentView() {
  const [sel, setSel] = useState(null);
  const [adding, setAdding] = useState(false);
  const { data, loading, reload } = useAsync(() => Promise.all([D.listItems("talent_cohorts"), D.listItems("talent_interns"), D.listItems("talent_training"), D.listClients()]), []);
  if (sel) return <InternDetail internId={sel} clients={(data && data[3]) || []} onBack={() => { setSel(null); reload(); }} />;
  const cohorts = (data && data[0]) || [], interns = (data && data[1]) || [], training = (data && data[2]) || [];
  const blocked = interns.filter(i => (i.stage === "selected" || i.stage === "active") && !visaCleared(i.visa));
  return (
    <div>
      <div className="os-view-h">
        <div><h1>Talent</h1><p>The 5-per-client moat. The 16-week clock and the visa gate are the two non-negotiables.</p></div>
        <button className="os-btn gold" onClick={() => setAdding(a => !a)}>{adding ? "Close" : "+ New candidate"}</button>
      </div>
      <div className={"os-gate " + (blocked.length ? "closed" : "open")}><b>{blocked.length ? "Visa gate: " + blocked.length + " selected/active intern(s) awaiting legality — blocked from pods." : "All selected interns visa-cleared."}</b></div>
      {adding ? <NewInternForm cohorts={cohorts} onCreated={() => { setAdding(false); reload(); }} /> : null}
      {loading ? <p className="os-muted">Loading…</p> : (
        <div>
          <section className="os-section"><div className="os-qh"><span className="os-qt">Cohorts</span><h2>16-week funnel</h2><span className="os-qs">{cohorts.length}</span></div>
            <div className="os-grid">{cohorts.map(c => {
              const wk = weeksUntil(c.start_date);
              const pct = wk == null ? 0 : Math.max(0, Math.min(100, 100 * (16 - wk) / 16));
              return (<div className="os-card client" key={c.id}>
                <div className="os-card-h"><span className="os-nm">{c.name}</span><span className="os-disc">{COHORT_STATUS[c.status] || c.status}</span></div>
                <div className="os-clientstats"><span>{c.university}</span><span>{wk == null ? "—" : (wk + " wk to start")}</span></div>
                <div className="os-track sm"><div className="os-track-fill" style={{ width: pct + "%" }} /></div>
              </div>);
            })}</div></section>
          <section className="os-section"><div className="os-qh"><span className="os-qt">Recruiting</span><h2>Pipeline</h2><span className="os-qs">{interns.length}</span></div>
            <div style={{ display: "flex", gap: 12, overflowX: "auto", paddingBottom: 8 }}>
              {INTERN_STAGES.map(st => {
                const is = interns.filter(i => i.stage === st.id);
                return (<div key={st.id} style={{ minWidth: 200, flex: "1 0 200px" }}>
                  <div className="os-qh" style={{ marginBottom: 8 }}><span className="os-qt sm">{st.label}</span><span className="os-qs">{is.length}</span></div>
                  {is.map(i => <InternCard key={i.id} i={i} onOpen={() => setSel(i.id)} />)}
                  {!is.length ? <p className="os-muted" style={{ fontSize: 12 }}>—</p> : null}
                </div>);
              })}
            </div></section>
          <section className="os-section"><div className="os-qh"><span className="os-qt">Training</span><h2>Library</h2><span className="os-qs">{training.length}</span></div>
            <div className="os-grid">{training.map(t => <TrainingCard key={t.id} t={t} />)}</div></section>
        </div>
      )}
    </div>
  );
}

/* ===================================================================== */
/* PRODUCT / IP ROOM (owner-guarded) — roadmap, comps coverage, recalib.   */
/* The moat: defensible accuracy. No client knocks, so protect its time.   */
/* ===================================================================== */
const RM_STATUS = [{ id: "backlog", label: "Backlog" }, { id: "next", label: "Next" }, { id: "building", label: "Building" }, { id: "shipped", label: "Shipped" }];
const RM_AREAS = ["science", "comps", "engine", "portal", "frameworks"];
const STALE_DAYS = 180;
function isStale(dateISO) { if (!dateISO) return true; return daysBetween(new Date(dateISO), new Date()) > STALE_DAYS; }

function RoadmapCard({ r, onOpen }) {
  return (
    <div className="os-card client" style={{ marginBottom: 10, cursor: "pointer" }} onClick={onOpen}>
      <div className="os-card-h"><span className="os-nm">{r.title}</span>{r.accuracy_impact ? <span className="os-disc">accuracy</span> : null}</div>
      <div className="os-clientstats"><span>{r.area}</span><span>{r.priority}</span></div>
    </div>
  );
}

function ProductItemForm({ collection, item, clients, onDone, onBack }) {
  function defaultsFor(col) {
    if (col === "product_roadmap") return { title: "", area: "science", status: "backlog", priority: "medium", accuracy_impact: false, notes: "" };
    if (col === "product_comps") return { sector: "saas", sub_vertical: "", count: 0, confidence: "low", mode: "fallback", date_accessed: "", notes: "" };
    return { client_id: (clients[0] && clients[0].id) || "", summary: "", realized_metric: "valuation", realized_value: null, status: "new", notes: "" };
  }
  const [f, setF] = useState(null);
  const [busy, setBusy] = useState(false);
  // resync when the selected item/collection changes (the inline form is not remounted
  // by an early return like the other rooms; this prevents stale-state cross-writes)
  useEffect(() => { setF(item ? { ...item } : defaultsFor(collection)); }, [item, collection]);
  if (!f) return null;
  const isNew = !(item && item.id);
  const num = v => (v === "" || v == null ? null : Number(v));
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const save = async (patch) => { setBusy(true); try { if (isNew) await D.addItem(collection, patch); else await D.updateItem(collection, item.id, patch); onDone(); } catch (e) { alert((e && e.message) || "Error"); } setBusy(false); };
  if (collection === "product_roadmap") return (
    <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
      <h3>Roadmap item</h3>
      <div className="os-formrow"><span className="os-flabel">Title</span><input value={f.title} onChange={e => set("title", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Area</span><select value={f.area} onChange={e => set("area", e.target.value)}>{RM_AREAS.map(a => <option key={a} value={a}>{a}</option>)}</select></div>
      <div className="os-formrow"><span className="os-flabel">Status</span><select value={f.status} onChange={e => set("status", e.target.value)}>{RM_STATUS.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}</select></div>
      <div className="os-formrow"><span className="os-flabel">Priority</span><select value={f.priority} onChange={e => set("priority", e.target.value)}><option value="low">Low</option><option value="medium">Medium</option><option value="high">High</option></select></div>
      <label className="os-formrow" style={{ cursor: "pointer", alignItems: "center" }}><input type="checkbox" checked={!!f.accuracy_impact} onChange={e => set("accuracy_impact", e.target.checked)} style={{ width: "auto", marginRight: 8 }} /><span>Moves defensibility (accuracy impact)</span></label>
      <div className="os-formrow"><span className="os-flabel">Notes</span><input value={f.notes || ""} onChange={e => set("notes", e.target.value)} /></div>
      <button className="os-btn gold" disabled={busy} onClick={() => save({ title: f.title, area: f.area, status: f.status, priority: f.priority, accuracy_impact: !!f.accuracy_impact, notes: f.notes || null })}>{busy ? "…" : "Save"}</button>
      <button className="os-btn ghost" onClick={onBack} style={{ marginLeft: 8 }}>Cancel</button>
    </div>
  );
  if (collection === "product_comps") return (
    <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
      <h3>Comps cell</h3>
      <div className="os-formrow"><span className="os-flabel">Sector</span><input value={f.sector} onChange={e => set("sector", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Sub-vertical</span><input value={f.sub_vertical} onChange={e => set("sub_vertical", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Count</span><input type="number" value={f.count ?? ""} onChange={e => set("count", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Confidence</span><select value={f.confidence} onChange={e => set("confidence", e.target.value)}><option value="low">Low</option><option value="medium">Medium</option><option value="high">High</option></select></div>
      <div className="os-formrow"><span className="os-flabel">Mode</span><select value={f.mode} onChange={e => set("mode", e.target.value)}><option value="fallback">Fallback</option><option value="data_driven">Data-driven</option></select></div>
      <div className="os-formrow"><span className="os-flabel">Date accessed</span><input type="date" value={f.date_accessed || ""} onChange={e => set("date_accessed", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Notes</span><input value={f.notes || ""} onChange={e => set("notes", e.target.value)} /></div>
      <button className="os-btn gold" disabled={busy} onClick={() => save({ sector: f.sector, sub_vertical: f.sub_vertical, count: num(f.count), confidence: f.confidence, mode: f.mode, date_accessed: f.date_accessed || null, notes: f.notes || null })}>{busy ? "…" : "Save"}</button>
      <button className="os-btn ghost" onClick={onBack} style={{ marginLeft: 8 }}>Cancel</button>
    </div>
  );
  if (collection === "product_recalibration") return (
    <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
      <h3>Recalibration item</h3>
      <div className="os-formrow"><span className="os-flabel">Client</span><select value={f.client_id} onChange={e => set("client_id", e.target.value)}>{clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}</select></div>
      <div className="os-formrow"><span className="os-flabel">Summary</span><input value={f.summary} onChange={e => set("summary", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Metric</span><select value={f.realized_metric} onChange={e => set("realized_metric", e.target.value)}><option value="valuation">Valuation</option><option value="multiple">Multiple</option><option value="raise">Raise</option><option value="exit">Exit</option><option value="irs_check">IRS check</option></select></div>
      <div className="os-formrow"><span className="os-flabel">Value</span><input type="number" value={f.realized_value ?? ""} onChange={e => set("realized_value", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Status</span><select value={f.status} onChange={e => set("status", e.target.value)}><option value="new">New</option><option value="reviewing">Reviewing</option><option value="folded">Folded</option></select></div>
      <div className="os-formrow"><span className="os-flabel">Notes</span><input value={f.notes || ""} onChange={e => set("notes", e.target.value)} /></div>
      <button className="os-btn gold" disabled={busy} onClick={() => save({ client_id: f.client_id, summary: f.summary, realized_metric: f.realized_metric, realized_value: num(f.realized_value), status: f.status, notes: f.notes || null })}>{busy ? "…" : "Save"}</button>
      <button className="os-btn ghost" onClick={onBack} style={{ marginLeft: 8 }}>Cancel</button>
    </div>
  );
  return null;
}

function ProductView() {
  const [edit, setEdit] = useState(null);
  const { data, loading, reload } = useAsync(() => Promise.all([D.listItems("product_roadmap"), D.listItems("product_comps"), D.listItems("product_recalibration"), D.listClients()]), []);
  const roadmap = (data && data[0]) || [], comps = (data && data[1]) || [], recal = (data && data[2]) || [], clients = (data && data[3]) || [];
  const clientName = id => (clients.find(c => c.id === id) || {}).name || id;
  const staleCount = comps.filter(c => isStale(c.date_accessed)).length;
  const newRecal = recal.filter(r => r.status === "new").length;
  const compsTotal = comps.reduce((s, c) => s + (c.count || 0), 0);
  const done = () => { setEdit(null); reload(); };
  return (
    <div>
      <div className="os-view-h"><div><h1>Product / IP</h1><p>The moat — defensible accuracy, not software. The one room with no client knocking, so its time is protected.</p></div></div>
      <div className={"os-gate " + (staleCount || newRecal ? "closed" : "open")}><b>{staleCount || newRecal ? "Moat hygiene: " + staleCount + " stale comp cell(s), " + newRecal + " unreviewed outcome(s)." : "Moat hygiene clean."}</b></div>
      {edit ? <ProductItemForm key={edit.collection + ":" + (edit.item ? edit.item.id : "new")} collection={edit.collection} item={edit.item} clients={clients} onDone={done} onBack={() => setEdit(null)} /> : null}
      {loading ? <p className="os-muted">Loading…</p> : (
        <div>
          <section className="os-section"><div className="os-qh"><span className="os-qt">Roadmap</span><h2>Backlog</h2><span className="os-qs">{roadmap.length}</span><button className="os-btn ghost sm" onClick={() => setEdit({ collection: "product_roadmap", item: null })}>+ New</button></div>
            <div style={{ display: "flex", gap: 12, overflowX: "auto", paddingBottom: 8 }}>
              {RM_STATUS.map(st => {
                const rs = roadmap.filter(r => r.status === st.id);
                return (<div key={st.id} style={{ minWidth: 210, flex: "1 0 210px" }}>
                  <div className="os-qh" style={{ marginBottom: 8 }}><span className="os-qt sm">{st.label}</span><span className="os-qs">{rs.length}</span></div>
                  {rs.map(r => <RoadmapCard key={r.id} r={r} onOpen={() => setEdit({ collection: "product_roadmap", item: r })} />)}
                  {!rs.length ? <p className="os-muted" style={{ fontSize: 12 }}>—</p> : null}
                </div>);
              })}
            </div></section>
          <section className="os-section"><div className="os-qh"><span className="os-qt">Comps</span><h2>Coverage</h2><span className="os-qs">~{compsTotal} comps · {comps.length} cells</span><button className="os-btn ghost sm" onClick={() => setEdit({ collection: "product_comps", item: null })}>+ New</button></div>
            <div className="os-grid">{comps.map(c => {
              const stale = isStale(c.date_accessed);
              return (<div className="os-card client" key={c.id} style={{ cursor: "pointer" }} onClick={() => setEdit({ collection: "product_comps", item: c })}>
                <div className="os-card-h"><span className="os-nm">{c.sector} · {c.sub_vertical}</span>{stale ? <span className="os-irs rec">stale</span> : null}</div>
                <div className="os-clientstats"><span><b>{c.count}</b> comps · {c.confidence}</span><span>{c.mode}</span></div>
                {stale ? <p className="os-kill"><b>Stale.</b> Last accessed {c.date_accessed || "—"} — refresh.</p> : null}
              </div>);
            })}</div></section>
          <section className="os-section"><div className="os-qh"><span className="os-qt">Recalibration</span><h2>Inbox</h2><span className="os-qs">{recal.length}</span><button className="os-btn ghost sm" onClick={() => setEdit({ collection: "product_recalibration", item: null })}>+ New</button></div>
            <div className="os-grid">{recal.map(r => (
              <div className="os-card client" key={r.id} style={{ cursor: "pointer" }} onClick={() => setEdit({ collection: "product_recalibration", item: r })}>
                <div className="os-card-h"><span className="os-nm">{clientName(r.client_id)}</span>{r.status === "new" ? <span className="os-irs rec">new</span> : null}</div>
                <div className="os-clientstats"><span>{r.realized_metric}</span><span>{r.realized_value != null ? r.realized_value : "—"}</span></div>
                <div className="os-tag">{r.summary}</div>
              </div>
            ))}</div></section>
        </div>
      )}
    </div>
  );
}

/* ===================================================================== */
/* PARTNER NETWORK ROOM — referral partners (potential→onboarding→signed). */
/* Each partner card opens to their referrals: dates, status, commissions. */
/* ===================================================================== */
const PARTNER_STAGES = [
  { id: "potential", label: "Lead / potential" },
  { id: "onboarding", label: "Onboarding" },
  { id: "signed", label: "Signed" },
];
const PARTNER_TYPE = { accountant: "Accountant", lawyer: "Lawyer", consultant: "Consultant", banker: "Banker", community: "Community", other: "Other" };
const REFERRAL_STATUS = { introduced: "Introduced", qualified: "Qualified", signed: "Signed", lost: "Lost" };
const COMMISSION_STATUS = { pending: "Pending", paid: "Paid" };
function partnerStats(refs) {
  const r = refs || [];
  const signed = r.filter(x => x.status === "signed").length;
  const total = r.reduce((s, x) => s + (x.commission || 0), 0);
  const paid = r.filter(x => x.commission_status === "paid").reduce((s, x) => s + (x.commission || 0), 0);
  return { count: r.length, signed, total, paid, pending: total - paid };
}

function PartnerCard({ p, refs, onOpen }) {
  const st = partnerStats(refs);
  return (
    <div className="os-card client" style={{ marginBottom: 10, cursor: "pointer" }} onClick={onOpen}>
      <div className="os-card-h"><span className="os-nm">{p.name}</span><span className="os-disc">{PARTNER_TYPE[p.type] || p.type}</span></div>
      <div className="os-clientstats"><span>{st.count} referral{st.count === 1 ? "" : "s"} · {st.signed} signed</span><span>{fmtMoney(st.total)}</span></div>
      {st.pending ? <div className="os-tag">{fmtMoney(st.pending)} commission pending</div> : null}
    </div>
  );
}

function NewPartnerForm({ onCreated }) {
  const [f, setF] = useState({ name: "", contact: "", type: "accountant", stage: "potential", commission_rate: "" });
  const [busy, setBusy] = useState(false);
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const create = async () => {
    if (!f.name.trim()) return;
    setBusy(true);
    try { await D.addItem("partners", { name: f.name.trim(), contact: f.contact || null, type: f.type, stage: f.stage, commission_rate: f.commission_rate || null, notes: null }); onCreated(); }
    catch (e) { alert((e && e.message) || "Error"); setBusy(false); }
  };
  return (
    <div className="os-panel" style={{ maxWidth: 560 }}>
      <h3>New partner</h3>
      <div className="os-formrow"><input placeholder="Partner / firm name" value={f.name} onChange={e => set("name", e.target.value)} /></div>
      <div className="os-formrow"><input placeholder="Contact" value={f.contact} onChange={e => set("contact", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Type</span><select value={f.type} onChange={e => set("type", e.target.value)}>{Object.keys(PARTNER_TYPE).map(k => <option key={k} value={k}>{PARTNER_TYPE[k]}</option>)}</select></div>
      <div className="os-formrow"><span className="os-flabel">Stage</span><select value={f.stage} onChange={e => set("stage", e.target.value)}>{PARTNER_STAGES.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}</select></div>
      <div className="os-formrow"><input placeholder="Commission terms (e.g. 10% of first-year retainer)" value={f.commission_rate} onChange={e => set("commission_rate", e.target.value)} /></div>
      <button className="os-btn gold" disabled={busy} onClick={create}>{busy ? "…" : "Add partner"}</button>
    </div>
  );
}

function ReferralForm({ partnerId, referral, onDone, onCancel }) {
  const isNew = !(referral && referral.id);
  const [f, setF] = useState(referral ? { ...referral } : { referred_company: "", date: "", status: "introduced", deal_value: null, commission: null, commission_status: "pending", notes: "" });
  const [busy, setBusy] = useState(false);
  const num = v => (v === "" || v == null ? null : Number(v));
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const save = async () => {
    setBusy(true);
    const payload = { partner_id: partnerId, referred_company: f.referred_company, date: f.date || null, status: f.status, deal_value: num(f.deal_value), commission: num(f.commission), commission_status: f.commission_status, notes: f.notes || null };
    try { if (isNew) await D.addItem("partner_referrals", payload); else await D.updateItem("partner_referrals", referral.id, payload); onDone(); }
    catch (e) { alert((e && e.message) || "Error"); setBusy(false); }
  };
  const del = async () => {
    if (!confirm("Delete this referral?")) return;
    setBusy(true);
    try { await D.removeItem("partner_referrals", referral.id); onDone(); }
    catch (e) { alert((e && e.message) || "Error"); setBusy(false); }
  };
  return (
    <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
      <h3>{isNew ? "New referral" : "Referral"}</h3>
      <div className="os-formrow"><span className="os-flabel">Referred company</span><input value={f.referred_company} onChange={e => set("referred_company", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Date</span><input type="date" value={f.date || ""} onChange={e => set("date", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Status</span><select value={f.status} onChange={e => set("status", e.target.value)}>{Object.keys(REFERRAL_STATUS).map(k => <option key={k} value={k}>{REFERRAL_STATUS[k]}</option>)}</select></div>
      <div className="os-formrow"><span className="os-flabel">Deal value (R$)</span><input type="number" value={f.deal_value ?? ""} onChange={e => set("deal_value", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Commission (R$)</span><input type="number" value={f.commission ?? ""} onChange={e => set("commission", e.target.value)} /></div>
      <div className="os-formrow"><span className="os-flabel">Commission status</span><select value={f.commission_status} onChange={e => set("commission_status", e.target.value)}>{Object.keys(COMMISSION_STATUS).map(k => <option key={k} value={k}>{COMMISSION_STATUS[k]}</option>)}</select></div>
      <div className="os-formrow"><span className="os-flabel">Notes</span><input value={f.notes || ""} onChange={e => set("notes", e.target.value)} /></div>
      <button className="os-btn gold" disabled={busy} onClick={save}>{busy ? "…" : (isNew ? "Add referral" : "Save")}</button>
      {!isNew ? <button className="os-btn ghost" disabled={busy} onClick={del} style={{ marginLeft: 8 }}>Delete</button> : null}
      <button className="os-btn ghost" onClick={onCancel} style={{ marginLeft: 8 }}>Cancel</button>
    </div>
  );
}

function PartnerDetail({ partnerId, onBack }) {
  const { data, loading, reload } = useAsync(() => Promise.all([D.listItems("partners").then(a => a.find(x => x.id === partnerId)), D.listItems("partner_referrals")]), [partnerId]);
  const [f, setF] = useState(null);
  const [busy, setBusy] = useState(false);
  const [refEdit, setRefEdit] = useState(null);
  useEffect(() => { if (data && data[0]) setF({ ...data[0] }); }, [data]);
  if (loading || !f) return <div><button className="os-back" onClick={onBack}><Icon name="back" /> Partners</button><p className="os-muted">Loading…</p></div>;
  const refs = ((data && data[1]) || []).filter(r => r.partner_id === partnerId);
  const st = partnerStats(refs);
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const save = async () => { setBusy(true); try { await D.updateItem("partners", partnerId, { name: f.name, contact: f.contact || null, type: f.type, stage: f.stage, commission_rate: f.commission_rate || null, notes: f.notes || null }); reload(); } catch (e) { alert((e && e.message) || "Error"); } setBusy(false); };
  const del = async () => {
    if (!confirm("Delete this partner and all their referrals? This can't be undone.")) return;
    setBusy(true);
    try {
      for (var i = 0; i < refs.length; i++) { await D.removeItem("partner_referrals", refs[i].id); }
      await D.removeItem("partners", partnerId);
      onBack();
    } catch (e) { alert((e && e.message) || "Error"); setBusy(false); }
  };
  if (refEdit) return (
    <div>
      <div className="os-view-h"><div><button className="os-back" onClick={() => setRefEdit(null)}><Icon name="back" /> {f.name}</button><h1>Referral</h1></div></div>
      <ReferralForm partnerId={partnerId} referral={refEdit === "new" ? null : refEdit} onDone={() => { setRefEdit(null); reload(); }} onCancel={() => setRefEdit(null)} />
    </div>
  );
  return (
    <div>
      <div className="os-view-h"><div><button className="os-back" onClick={onBack}><Icon name="back" /> Partners</button><h1>{f.name}</h1><p>{PARTNER_TYPE[f.type] || f.type} · {(PARTNER_STAGES.find(s => s.id === f.stage) || {}).label || f.stage}</p></div></div>
      <div className="os-dashgrid">
        <div className="os-pcard"><h3>Referrals</h3><div className="os-progbig"><b>{st.count}</b><span>{st.signed} signed</span></div></div>
        <div className="os-pcard"><h3>Commission</h3><div className="os-progbig"><b>{fmtMoney(st.total)}</b><span>{fmtMoney(st.paid)} paid · {fmtMoney(st.pending)} pending</span></div></div>
      </div>
      <div className="os-panel" style={{ maxWidth: 720, marginTop: 14 }}>
        <h3>Partner</h3>
        <div className="os-formrow"><span className="os-flabel">Name</span><input value={f.name} onChange={e => set("name", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Contact</span><input value={f.contact || ""} onChange={e => set("contact", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Type</span><select value={f.type} onChange={e => set("type", e.target.value)}>{Object.keys(PARTNER_TYPE).map(k => <option key={k} value={k}>{PARTNER_TYPE[k]}</option>)}</select></div>
        <div className="os-formrow"><span className="os-flabel">Stage</span><select value={f.stage} onChange={e => set("stage", e.target.value)}>{PARTNER_STAGES.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}</select></div>
        <div className="os-formrow"><span className="os-flabel">Commission terms</span><input value={f.commission_rate || ""} onChange={e => set("commission_rate", e.target.value)} /></div>
        <div className="os-formrow"><span className="os-flabel">Notes</span><input value={f.notes || ""} onChange={e => set("notes", e.target.value)} /></div>
        <button className="os-btn gold" disabled={busy} onClick={save}>{busy ? "…" : "Save partner"}</button>
        <button className="os-btn ghost" disabled={busy} onClick={del} style={{ marginLeft: 8 }}>Delete partner</button>
      </div>
      <section className="os-section">
        <div className="os-qh"><span className="os-qt">Referrals</span><h2>This partner</h2><span className="os-qs">{refs.length}</span><button className="os-btn ghost sm" onClick={() => setRefEdit("new")}>+ Add referral</button></div>
        {refs.length ? (
          <div className="os-doclist">
            {refs.map(r => (
              <div className="os-docrow" key={r.id} style={{ cursor: "pointer" }} onClick={() => setRefEdit(r)}>
                <span className="os-doc-nm">{r.referred_company}</span>
                <span className="os-doc-src">{REFERRAL_STATUS[r.status] || r.status}</span>
                <span className="os-doc-dt">{r.date || "—"}</span>
                <span>{fmtMoney(r.commission)} · {COMMISSION_STATUS[r.commission_status] || r.commission_status}</span>
              </div>
            ))}
          </div>
        ) : <p className="os-muted">No referrals logged yet.</p>}
      </section>
    </div>
  );
}

function PartnerView() {
  const [sel, setSel] = useState(null);
  const [adding, setAdding] = useState(false);
  const { data, loading, reload } = useAsync(() => Promise.all([D.listItems("partners"), D.listItems("partner_referrals")]), []);
  if (sel) return <PartnerDetail partnerId={sel} onBack={() => { setSel(null); reload(); }} />;
  const partners = (data && data[0]) || [], referrals = (data && data[1]) || [];
  const refsOf = id => referrals.filter(r => r.partner_id === id);
  return (
    <div>
      <div className="os-view-h">
        <div><h1>Partners</h1><p>The referral-partner network — accountants, lawyers, consultants who send qualified leads for a commission.</p></div>
        <button className="os-btn gold" onClick={() => setAdding(a => !a)}>{adding ? "Close" : "+ New partner"}</button>
      </div>
      {adding ? <NewPartnerForm onCreated={() => { setAdding(false); reload(); }} /> : null}
      {D && D.mode === "local" ? <p className="os-muted">Local preview — demo data.</p> : null}
      {loading ? <p className="os-muted">Loading…</p> : (
        <div style={{ display: "flex", gap: 12, overflowX: "auto", paddingBottom: 8, marginTop: 8 }}>
          {PARTNER_STAGES.map(st => {
            const ps = partners.filter(p => p.stage === st.id);
            return (
              <div key={st.id} style={{ minWidth: 230, flex: "1 0 230px" }}>
                <div className="os-qh" style={{ marginBottom: 8 }}><span className="os-qt sm">{st.label}</span><span className="os-qs">{ps.length}</span></div>
                {ps.map(p => <PartnerCard key={p.id} p={p} refs={refsOf(p.id)} onOpen={() => setSel(p.id)} />)}
                {!ps.length ? <p className="os-muted" style={{ fontSize: 12 }}>—</p> : null}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

// Shell for an operation room whose work surface isn't built yet. Renders the plan
// (purpose, the surface that's coming, what it carries, where it hands off) from the
// ROOMS config so the structure + access model are real now and depth fills in by phase.
function RoomShell({ room }) {
  return (
    <div>
      <div className="os-view-h">
        <div><h1>{room.label}</h1>{room.purpose ? <p>{room.purpose}</p> : null}</div>
        <span className="os-badge local" title={"Build phase " + room.phase}>Shell · Phase {room.phase}{room.ownerOnly ? " · owner-only" : ""}</span>
      </div>
      <div className="os-dashgrid">
        <div className="os-pcard">
          <h3>Work surface (coming)</h3>
          {room.surface && room.surface.length
            ? <ul>{room.surface.map((s, i) => <li key={i}>{s}</li>)}</ul>
            : <p className="os-muted">To be specified.</p>}
        </div>
        <div className="os-pcard">
          <h3>Carries</h3><p>{room.carries || "—"}</p>
          <h3 style={{ marginTop: 14 }}>Hands off to</h3><p>{room.handoff || "—"}</p>
          {room.today ? <p className="os-pnote"><b>Today:</b> {room.today}</p> : null}
        </div>
      </div>
      <p className="os-muted" style={{ marginTop: 18 }}>This room is a shell — its work surface is built in the phased rollout (see OS_Employee_Portal_Design.md).</p>
    </div>
  );
}

function EmployeeOS({ isLocal, profile }) {
  const [view, setView] = useState(() => { try { const v = localStorage.getItem("valioro_os_view"); return v === "clients" ? "delivery" : (v || "delivery"); } catch (e) { return "delivery"; } });
  const [preview, setPreview] = useState(null); // clientId being previewed
  useEffect(() => { try { localStorage.setItem("valioro_os_view", view); } catch (e) {} }, [view]);
  // Access choke point: owner sees the owner-only rooms (Finance, Product/IP). In local
  // preview / for any employee this is true (no sub-roles yet) so nothing is hidden today;
  // it's the single gate to tighten when employee accounts + sub-roles land.
  const isOwner = isLocal || !profile || profile.role !== "client";

  if (preview) return <ClientPortal clientId={preview} preview onExit={() => setPreview(null)} />;

  let body;
  if (view === "delivery") body = <ClientsView onPreview={setPreview} />;
  else if (view === "deliverables") body = <DeliverablesView />;
  else if (view === "frameworks") body = <FrameworksView />;
  else if (view === "methodology") body = <SimpleView title="Methodology & Doctrine" lead="Why every move is made." items={A.methodology} />;
  else if (view === "tools") body = <SimpleView title="Tools" lead="The live interactive apps." items={A.tools} />;
  else if (view === "operations") body = <SimpleView title="Operations (docs)" lead="How the work gets delivered." items={A.operations} />;
  else if (view === "brand") body = <SimpleView title="Brand & Assets" lead="The firm's identity kit." items={A.brand} />;
  else if (view === "sales") body = <SalesView onPreview={setPreview} />;
  else if (view === "onboarding") body = <OnboardingView />;
  else if (view === "success") body = <CSView />;
  else if (view === "partners") body = <PartnerView />;
  else if (view === "demand") body = <DemandView onPreview={setPreview} />;
  else if (view === "finance" && isOwner) body = <FinanceView />;
  else if (view === "talent") body = <TalentView />;
  else if (view === "product" && isOwner) body = <ProductView />;
  else if (ROOM_BY_ID[view]) body = <RoomShell room={ROOM_BY_ID[view]} />;
  else body = <ClientsView onPreview={setPreview} />;
  return (
    <div className="os-shell">
      <aside className="os-side">
        <div className="os-logo"><b>VALIORO</b><span>OS</span></div>
        <nav>
          <div className="os-navgroup" style={{ fontSize: 10, textTransform: "uppercase", letterSpacing: ".09em", opacity: .45, margin: "4px 14px 6px" }}>Operations</div>
          {ROOMS.filter(n => !n.ownerOnly || isOwner).map(n => (
            <button key={n.id} className={"os-navbtn" + (view === n.id ? " active" : "")} onClick={() => setView(n.id)}>
              <span className="os-navi"><Icon name={n.id} /></span><span>{n.label}</span>
            </button>
          ))}
          <div className="os-navgroup" style={{ fontSize: 10, textTransform: "uppercase", letterSpacing: ".09em", opacity: .45, margin: "16px 14px 6px" }}>Reference</div>
          {REFERENCE.map(n => (
            <button key={n.id} className={"os-navbtn" + (view === n.id ? " active" : "")} onClick={() => setView(n.id)}>
              <span className="os-navi"><Icon name={n.id} /></span><span>{n.label}</span>
            </button>
          ))}
        </nav>
        <div className="os-side-foot">
          {isLocal
            ? <span className="os-badge local" title="No Supabase keys configured — running locally with no login">● Local preview</span>
            : <span className="os-badge authed">● {profile && (profile.full_name || profile.email) || "Signed in"}{profile && profile.role ? " · " + profile.role : ""}</span>}
          {!isLocal ? <button className="os-signout" onClick={async () => { await AUTH.signOut(); location.reload(); }}>Sign out</button> : null}
          <a className="os-sitelink" href={SITE_HREF}><Icon name="back" /> Public site</a>
        </div>
      </aside>
      <main className="os-main">{body}</main>
    </div>
  );
}

function App() {
  const [status, setStatus] = useState("loading"); // loading | local | anon | authed
  const [profile, setProfile] = useState(null);

  const refreshAuth = useCallback(async () => {
    if (!AUTH.enabled) { setStatus("local"); return; }
    const u = await AUTH.getUser();
    if (u) { const p = await AUTH.getProfile(); setProfile(p); setStatus("authed"); }
    else setStatus("anon");
  }, []);
  useEffect(() => { refreshAuth(); }, [refreshAuth]);

  if (status === "loading") return <div className="os-splash"><b>VALIORO</b><span>Operating System</span><i>loading…</i></div>;
  if (status === "anon") return <LoginScreen onSignedIn={() => refreshAuth()} />;

  // Authenticated client → their portal only.
  if (status === "authed" && profile && profile.role === "client") {
    return <ClientPortal clientId={profile.client_id} profile={profile} />;
  }
  // Employee (authed) or local preview → the OS.
  return <EmployeeOS isLocal={status === "local"} profile={profile} />;
}

ReactDOM.render(<App />, document.getElementById("root"));
