// Finance pages: Overview, Cash Flow, AR/AP, Forecast

const { useState: useStateF, useMemo: useMemoF, useEffect: useEffectF, useRef: useRefF } = React;

// ─── Card wrapper ─────────────────────────────────────────────────────────
function Card({ title, subtitle, action, children, padding = 20, style }) {
  return (
    <div className="pc-card" style={style}>
      {(title || action) && (
        <div className="pc-card-hd">
          <div>
            {title && <div className="pc-card-title">{title}</div>}
            {subtitle && <div className="pc-card-subtitle">{subtitle}</div>}
          </div>
          {action}
        </div>
      )}
      <div style={{ padding }}>{children}</div>
    </div>
  );
}

function AIInsight({ children, action }) {
  return (
    <div className="pc-ai-insight">
      <div style={{ display: "flex", alignItems: "center", gap: 6, marginBottom: 6 }}>
        <span style={{ width: 14, height: 14, borderRadius: 4, background: "radial-gradient(circle at 30% 30%, var(--accent), var(--accent-2))", display: "flex", alignItems: "center", justifyContent: "center" }}>
          <Icon d={icons.ai} size={9} stroke="var(--on-accent)" strokeWidth={2.4} />
        </span>
        <span style={{ fontSize: 10, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.6, fontWeight: 500 }}>AI insight</span>
      </div>
      <div style={{ fontSize: 12.5, color: "var(--text-2)", lineHeight: 1.55 }}>{children}</div>
      {action && <div style={{ marginTop: 8 }}>{action}</div>}
    </div>
  );
}

// ────────────────────────────────────────────────────────────────────────
// FINANCIAL OVERVIEW
// ────────────────────────────────────────────────────────────────────────

// Plain-English terms — used when plain-English mode is on
const PLAIN_TERMS = {
  "Revenue": "Money in",
  "Gross profit": "Profit after making it",
  "Opex": "Running costs",
  "EBITDA": "Operating profit",
  "Cost of goods sold": "Cost to make it",
  "Operating expenses": "Running costs",
  "Gross margin %": "Profit per dollar sold",
  "EBITDA margin %": "Profit per dollar earned",
  "DSO": "Days customers take to pay",
  "AR aging": "Money owed to you",
  "Cash on hand": "Money in your bank",
  "Runway": "How long your cash lasts",
};
window.plain = function (term) {
  if (typeof window !== "undefined" && window.__perduraPlain && PLAIN_TERMS[term]) return PLAIN_TERMS[term];
  return term;
};

// ─── Outliers data (anomalies + dollar impact + recommended action) ─────
const buildOutliers = (bizType, data) => {
  const common = [
    {
      sev: "critical",
      headline: "Aurelius Pro Kit margin dropped 8 points — costing you $52K/month",
      explain: "Vendor V-201 raised input costs 9%. You haven't passed it through. Every month you don't fix this, you lose another $52K.",
      action: "Fix the margin",
      drillKey: "gp",
      impact: 52000,
      timeframe: "monthly",
    },
    {
      sev: "critical",
      headline: "Cascade Foods is 92 days late on $31.6K — they always pay in 38 days",
      explain: "This is a 2-sigma payment anomaly. Something is wrong: PO mismatch, dispute, or financial trouble at the customer. Call them today.",
      action: "Call Cascade",
      drillKey: null,
      impact: 31600,
      timeframe: "once",
    },
    {
      sev: "high",
      headline: "$48K of software is auto-renewing on tiers you barely use",
      explain: "4 SaaS tools renewed at enterprise tiers in March — usage on all four is under 30%. Downgrading recovers $48K annualized with zero impact.",
      action: "Cancel unused tiers",
      drillKey: "opex",
      impact: 48000,
      timeframe: "annual",
    },
    {
      sev: "high",
      headline: "South region pipeline is 0.9x quota — 4-month low",
      explain: "Other regions average 2.4x coverage. South is at 0.9x because 2 enterprise accounts went inactive and no replacements are in flight. Sales coverage needs reallocating this week.",
      action: "Reallocate SDR coverage",
      drillKey: null,
      impact: 84000,
      timeframe: "quarterly",
    },
  ];
  const productOnly = [
    {
      sev: "critical",
      headline: "Polaris Beacon stocks out in 11 days — and you have no PO open",
      explain: "Vendor lead time is 45 days. Even with an emergency order today, you'd be out for ~34 days. Air freight at +$2.4K saves 12 days and recovers ~$28K of lost sales.",
      action: "Place rush order",
      drillKey: null,
      impact: 28000,
      timeframe: "monthly",
    },
    {
      sev: "high",
      headline: "Solas line ties up $69K in dead capital — 14 months of stock on hand",
      explain: "Sell-through of 12 units/month vs 488 on hand. Liquidate at 35% off through Channel B and recover $46K in 7 months. Frees buy budget for fast-movers.",
      action: "Build liquidation plan",
      drillKey: null,
      impact: 46000,
      timeframe: "once",
    },
  ];
  const retailOnly = [
    {
      sev: "high",
      headline: "Cherry Creek lost money 3 months in a row — only store doing so",
      explain: "Foot traffic is 32% below West region average. Relocating to Cherry Hills (4 blocks east) would 2x traffic per demographics match. Closing saves $63K/yr. Status quo burns $64K/yr.",
      action: "Open decision card",
      drillKey: null,
      impact: 64000,
      timeframe: "annual",
    },
  ];
  const mfgOnly = [
    {
      sev: "high",
      headline: "Line 2 OEE fell to 71% — Press #4 bearing failure cost you 380 units",
      explain: "Spare bearings are now on 28-day lead time. Dual-sourcing the part + carrying 2-unit safety stock costs ~$840 and avoids ~$28K/yr in recurring downtime.",
      action: "Approve dual-source",
      drillKey: null,
      impact: 28000,
      timeframe: "annual",
    },
  ];
  const serviceOnly = [
    {
      sev: "high",
      headline: "Project Halcyon is 14% over budget — margin tracking to 8% vs. 32% target",
      explain: "Burn rate is $42K/wk vs. plan of $31K/wk. Scope variance + 1 additional engineer. Customer health is favorable (78), supporting a scope change order.",
      action: "Draft change order",
      drillKey: null,
      impact: 86000,
      timeframe: "once",
    },
  ];
  return [
    ...common,
    ...(bizType === "product" || bizType === "manufacturing" || bizType === "retail" ? productOnly : []),
    ...(bizType === "retail" ? retailOnly : []),
    ...(bizType === "manufacturing" ? mfgOnly : []),
    ...(bizType === "service" ? serviceOnly : []),
  ].slice(0, 5);
};

function OutliersCard({ bizType, data, onDrill }) {
  const outliers = buildOutliers(bizType, data);
  const totalImpact = outliers.reduce((s, o) => s + (o.timeframe === "annual" ? o.impact / 12 : o.timeframe === "quarterly" ? o.impact / 3 : o.impact), 0);

  return (
    <div className="pc-outliers-card">
      <div className="pc-outliers-hd">
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <div style={{ width: 36, height: 36, borderRadius: 10, background: "radial-gradient(circle at 30% 30%, var(--accent), var(--accent-2))", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
            <Icon d={icons.ai} size={18} stroke="var(--on-accent)" strokeWidth={2.4} />
          </div>
          <div>
            <div style={{ fontSize: 11, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.6, marginBottom: 2 }}>Strategic outliers this week</div>
            <div style={{ fontSize: 16, fontWeight: 600, letterSpacing: -0.2 }}>
              {outliers.length} things worth your attention · <span style={{ color: "var(--danger)" }}>~{fmtUSD(totalImpact, { compact: true })} monthly impact</span>
            </div>
          </div>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          <button className="pc-btn-mini ghost">Snooze all</button>
          <button className="pc-btn-mini">Review with Perdura</button>
        </div>
      </div>
      <div className="pc-outliers-list">
        {outliers.map((o, i) => (
          <OutlierRow key={i} outlier={o} onDrill={() => o.drillKey && onDrill(o.drillKey)} />
        ))}
      </div>
    </div>
  );
}

function OutlierRow({ outlier, onDrill }) {
  const [expanded, setExpanded] = useStateF(false);
  const sevColors = {
    critical: { dot: "var(--danger)",  glow: "rgba(248,113,113,0.4)" },
    high:     { dot: "var(--warning)", glow: "rgba(251,191,36,0.4)" },
    medium:   { dot: "var(--accent-2)", glow: "rgba(99,102,241,0.4)" },
  };
  const s = sevColors[outlier.sev] || sevColors.high;
  const tfLabel = outlier.timeframe === "annual" ? "/yr" : outlier.timeframe === "quarterly" ? "/qtr" : outlier.timeframe === "monthly" ? "/mo" : "";

  return (
    <div className="pc-outlier-row" onClick={() => setExpanded(v => !v)}>
      <div className="pc-outlier-sev-dot" style={{ background: s.dot, boxShadow: "0 0 12px " + s.glow }} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 14, flexWrap: "wrap" }}>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 14, fontWeight: 600, lineHeight: 1.4, color: "var(--text)" }}>{outlier.headline}</div>
            {expanded && (
              <div style={{ fontSize: 12.5, color: "var(--text-2)", lineHeight: 1.6, marginTop: 8 }}>
                {outlier.explain}
              </div>
            )}
          </div>
          <div className="pc-outlier-impact">
            <div className="pc-outlier-amount">{fmtUSD(outlier.impact, { compact: true })}<span style={{ fontSize: 10.5, color: "var(--text-3)", fontWeight: 400 }}>{tfLabel}</span></div>
            <div style={{ fontSize: 10, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.5 }}>$ impact</div>
          </div>
          <button className="pc-outlier-action" onClick={(e) => { e.stopPropagation(); onDrill && onDrill(); }}>
            {outlier.action}
            <Icon d={icons.chevron} size={11} />
          </button>
        </div>
      </div>
    </div>
  );
}


// Compare-to options mapped to month offset (negative = months back)
const COMPARE_OPTIONS = [
  { key: "prior_month",   label: "Prior month",     offset: -1 },
  { key: "prior_quarter", label: "Prior quarter",   offset: -3 },
  { key: "yoy",           label: "Same period last year", offset: -12 },
  { key: "budget",        label: "Budget",          offset: -1, mult: 1.05 }, // synthetic
  { key: "forecast",      label: "Forecast",        offset: -1, mult: 1.03 },
];

// Sub-account breakdowns for the line-item drill
const SUB_BREAKDOWNS = {
  revenue: [
    { acct: "4000", name: "Product Sales — Online",    share: 0.42 },
    { acct: "4010", name: "Wholesale Revenue",          share: 0.32 },
    { acct: "4020", name: "Marketplace Revenue",        share: 0.17 },
    { acct: "4050", name: "Subscription / Recurring",   share: 0.11 },
    { acct: "4090", name: "Returns & Allowances",       share: -0.02 },
  ],
  cogs: [
    { acct: "5000", name: "Direct Material",            share: 0.58 },
    { acct: "5100", name: "Direct Labor",               share: 0.18 },
    { acct: "5010", name: "Inbound Freight",            share: 0.11 },
    { acct: "5020", name: "Packaging",                  share: 0.07 },
    { acct: "5200", name: "Manufacturing Overhead",     share: 0.06 },
  ],
  opex: [
    { acct: "6010", name: "Personnel — Salaries & Benefits", share: 0.51 },
    { acct: "6200", name: "Sales & Marketing",          share: 0.18 },
    { acct: "6900", name: "Software & Subscriptions",   share: 0.09 },
    { acct: "6100", name: "Facilities & Rent",          share: 0.08 },
    { acct: "6500", name: "Professional Services",      share: 0.07 },
    { acct: "6700", name: "G&A — Other",                share: 0.07 },
  ],
  gp: [],     // Composite — handled differently
  ebitda: [], // Composite — handled differently
};

// KPI definitions per line item — surfaced in the drill modal
const LINE_KPIS = {
  revenue: [
    { label: "Orders",        format: "num",  base: 278,    delta: 6.2 },
    { label: "Avg order value", format: "usd", base: 5324,  delta: -1.4 },
    { label: "Active customers", format: "num", base: 84,   delta: 4.1 },
    { label: "% Repeat",      format: "pct",  base: 64,     delta: 2.8 },
    { label: "Net retention", format: "pct",  base: 112,    delta: 3.2 },
    { label: "New logos",     format: "num",  base: 7,      delta: 16.7 },
  ],
  cogs: [
    { label: "Unit material cost", format: "usd", base: 248, delta: 8.4 },
    { label: "Freight as % revenue", format: "pct", base: 5.4, delta: 0.6 },
    { label: "Yield %",        format: "pct",  base: 96.8,   delta: -0.4 },
    { label: "Scrap rate",     format: "pct",  base: 3.2,    delta: 0.4 },
    { label: "Lots received",  format: "num",  base: 14,     delta: 0 },
    { label: "Avg landed cost", format: "usd", base: 312,    delta: 6.1 },
  ],
  gp: [
    { label: "Gross margin %",   format: "pct", base: 49.2,  delta: -1.8 },
    { label: "Contribution margin %", format: "pct", base: 44.4, delta: -2.1 },
    { label: "Product GM%",      format: "pct", base: 51.8,  delta: -2.4 },
    { label: "Service GM%",      format: "pct", base: 64.2,  delta: 1.1 },
    { label: "Wholesale GM%",    format: "pct", base: 38.4,  delta: -1.4 },
    { label: "GP per FTE",       format: "usd", base: 30404, delta: 2.8 },
  ],
  opex: [
    { label: "Headcount",        format: "num", base: 24,    delta: 4.3 },
    { label: "Cost per customer", format: "usd", base: 4312, delta: -2.1 },
    { label: "Opex as % revenue", format: "pct", base: 24.4, delta: 1.1 },
    { label: "S&M efficiency",   format: "ratio", base: 2.84, delta: -8.4 },
    { label: "R&D / Revenue",    format: "pct", base: 6.1,   delta: 0.2 },
    { label: "G&A / Revenue",    format: "pct", base: 4.8,   delta: -0.4 },
  ],
  ebitda: [
    { label: "EBITDA margin",    format: "pct", base: 24.8,  delta: -3.2 },
    { label: "Rule of 40",       format: "num", base: 38.4,  delta: -4.1 },
    { label: "FCF (approx)",     format: "usd", base: 312000, delta: -8.4 },
    { label: "Cash conv. cycle", format: "num", base: 72,    delta: -1.4 },
    { label: "Debt / EBITDA",    format: "ratio", base: 1.4, delta: 0 },
    { label: "Interest coverage", format: "num", base: 11.2, delta: -0.4 },
  ],
};

function OverviewPage({ data, period: globalPeriod, setPeriod: setGlobalPeriod, density, onDrill, bizType }) {
  const { pl, exceptions } = data;
  const [drillKey, setDrillKey] = useStateF(null);
  const [plMode, setPlMode] = useStateF("variance");

  const { curIdx, cmpIdx, sumAt: sumPl, cmpMult, compareTo: compareKey, setCompareTo: setCompareKey,
          period, setPeriod, cmpLbl, PeriodComparerEl } = window.usePeriod(globalPeriod, setGlobalPeriod);

  const sumAt = (key, indices) => (indices || curIdx).reduce((s, m) => s + (pl[key][m] || 0), 0);

  // Current period totals
  const rev    = sumAt("revenue", curIdx);
  const cogs   = sumAt("cogs",    curIdx);
  const gp     = sumAt("gp",      curIdx);
  const opex   = sumAt("opex",    curIdx);
  const ebitda = sumAt("ebitda",  curIdx);

  // Comparison period totals
  const cmpRev    = Math.round(sumAt("revenue", cmpIdx) * cmpMult);
  const cmpCogs   = Math.round(sumAt("cogs",    cmpIdx) * cmpMult);
  const cmpGp     = cmpRev - cmpCogs;
  const cmpOpex   = Math.round(sumAt("opex",    cmpIdx) * cmpMult);
  const cmpEbitda = cmpGp - cmpOpex;

  const cmpIdxLast = cmpIdx.length > 0 ? cmpIdx[cmpIdx.length - 1] : 10;

  // Margin series for bar charts — always trailing 12 months
  const gmPctSeries = pl.gp.map((g, idx) => (g / pl.revenue[idx]) * 100);
  const ebitdaPctSeries = pl.ebitda.map((e, idx) => (e / pl.revenue[idx]) * 100);

  const localPeriodLabel = (window.PERIOD_OPTIONS || []).find(o => o.v === period)?.l || period;
  const cmpOpt = { label: cmpLbl || "prior period", key: compareKey };

  return (
    <div className="pc-page">
      {/* Outliers card — leading the page */}
      <OutliersCard bizType={bizType} data={data} onDrill={(k) => setDrillKey(k)} />

      {/* Period comparison bar */}
      <div className="pc-period-bar">
        <div style={{ flex: 1 }}>
          {PeriodComparerEl}
        </div>
        <div className="pc-period-bar-section">
          <span className="pc-pb-label">Show</span>
          <div className="pc-seg-sm">
            <button className={plMode === "variance" ? "active" : ""} onClick={() => setPlMode("variance")}>Variance view</button>
            <button className={plMode === "trailing" ? "active" : ""} onClick={() => setPlMode("trailing")}>6-month trailing</button>
          </div>
        </div>
        <ExportButton rows={[
          { Line: "Revenue", Current: rev, Comparison: cmpRev, Var$: rev - cmpRev, VarPct: deltaPct(rev, cmpRev).toFixed(1) + "%" },
          { Line: "COGS", Current: cogs, Comparison: cmpCogs, Var$: cogs - cmpCogs, VarPct: deltaPct(cogs, cmpCogs).toFixed(1) + "%" },
          { Line: "Gross profit", Current: gp, Comparison: cmpGp, Var$: gp - cmpGp, VarPct: deltaPct(gp, cmpGp).toFixed(1) + "%" },
          { Line: "Opex", Current: opex, Comparison: cmpOpex, Var$: opex - cmpOpex, VarPct: deltaPct(opex, cmpOpex).toFixed(1) + "%" },
          { Line: "EBITDA", Current: ebitda, Comparison: cmpEbitda, Var$: ebitda - cmpEbitda, VarPct: deltaPct(ebitda, cmpEbitda).toFixed(1) + "%" },
        ]} filename="Financial_Overview_PL" />
      </div>

      {/* Hero KPI strip — with comparison values + variance */}
      <div className="pc-kpi-grid pc-kpi-grid-4">
        <ComparisonKPI label={window.plain("Revenue")}      current={rev} comparison={cmpRev} cmpLabel={cmpLbl} spark={pl.revenue.slice(-12)} accent="var(--accent)" onClick={() => setDrillKey("revenue")} />
        <ComparisonKPI label={window.plain("Gross profit")} current={gp} comparison={cmpGp} cmpLabel={cmpLbl} sub={`${window.plain("Gross margin %").replace(" %","")} ${(gp/rev*100).toFixed(1)}%`} spark={pl.gp.slice(-12)} accent="var(--accent-2)" onClick={() => setDrillKey("gp")} />
        <ComparisonKPI label={window.plain("Opex")}         current={opex} comparison={cmpOpex} cmpLabel={cmpLbl} spark={pl.opex.slice(-12)} accent="var(--warning)" inverse onClick={() => setDrillKey("opex")} />
        <ComparisonKPI label={window.plain("EBITDA")}       current={ebitda} comparison={cmpEbitda} cmpLabel={cmpLbl} sub={`${(ebitda/rev*100).toFixed(1)}% margin`} spark={pl.ebitda.slice(-12)} accent="var(--positive)" onClick={() => setDrillKey("ebitda")} />
      </div>

      {/* AI Banner */}
      <div className="pc-ai-banner">
        <div style={{ display: "flex", alignItems: "flex-start", gap: 14, flex: 1, minWidth: 0 }}>
          <div style={{ width: 36, height: 36, borderRadius: 10, background: "radial-gradient(circle at 30% 30%, var(--accent), var(--accent-2))", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
            <Icon d={icons.ai} size={18} stroke="var(--on-accent)" strokeWidth={2.4} />
          </div>
          <div>
            <div style={{ fontSize: 11, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.6, marginBottom: 3 }}>What changed this period</div>
            <div style={{ fontSize: 14, color: "var(--text)", lineHeight: 1.5 }}>
              EBITDA margin compressed <b style={{ color: "var(--danger)" }}>3.2 pts</b> vs {cmpLbl} — a <b style={{ color: "var(--danger)" }}>1.8-pt GM decline</b> driven by Aurelius Pro Kit lots received after Apr 18 (vendor V-201 input cost +9%) plus <b style={{ color: "var(--danger)" }}>1.4-pt Opex growth</b> from auto-renewed software at enterprise tiers. Click any line item below to see the full breakdown.
            </div>
          </div>
        </div>
        <div style={{ display: "flex", gap: 8, flexShrink: 0 }}>
          <button className="pc-btn-mini" onClick={() => setDrillKey("ebitda")}>Drill EBITDA</button>
        </div>
      </div>

      {/* Margin Bar Charts */}
      <div className="pc-grid-2">
        <MarginBarCard title="Gross margin %" subtitle="Trailing 12 months · 30-day rolling"
          values={gmPctSeries} labels={pl.labels} target={56}
          current={gmPctSeries[gmPctSeries.length-1]} prior={gmPctSeries[gmPctSeries.length-2]}
          color="var(--accent-2)" onDrill={() => setDrillKey("gp")} />
        <MarginBarCard title="EBITDA margin %" subtitle="Trailing 12 months · 30-day rolling"
          values={ebitdaPctSeries} labels={pl.labels} target={28}
          current={ebitdaPctSeries[ebitdaPctSeries.length-1]} prior={ebitdaPctSeries[ebitdaPctSeries.length-2]}
          color="var(--positive)" onDrill={() => setDrillKey("ebitda")} />
      </div>

      {/* P&L Statement */}
      <PLDetailCard pl={pl} cmpOpt={cmpOpt} cmpIdx={cmpIdxLast} cmpMult={cmpMult}
                    curIdx={curIdx}
                    onDrill={(k) => setDrillKey(k)} />

      {/* Bottom row */}
      <div className="pc-grid-2">
        <Card title="Exceptions worth your time" subtitle={`${exceptions.length} open · ${exceptions.filter(e => e.sev === "critical").length} critical`}
              action={<button className="pc-btn-mini ghost">View inbox</button>}>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {exceptions.slice(0, 4).map(ex => (
              <div key={ex.id} className="pc-exception-row" onClick={() => onDrill && onDrill("exception", ex)}>
                <SevPill sev={ex.sev} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 12.5, fontWeight: 500, lineHeight: 1.35 }}>{ex.title}</div>
                  <div style={{ fontSize: 11, color: "var(--text-3)", marginTop: 2 }}>{ex.category} · {ex.ts}</div>
                </div>
                <Icon d={icons.chevron} size={12} stroke="var(--text-3)" />
              </div>
            ))}
          </div>
        </Card>

        <Card title={window.plain("Cash on hand") || "Cash position"} subtitle="90-day forward projection"
              action={<button className="pc-btn-mini ghost">Open cash flow</button>}>
          <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 14 }}>
            <div>
              <div style={{ fontSize: 10, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.5 }}>Today</div>
              <div style={{ fontSize: 22, fontWeight: 600, fontFamily: "ui-monospace, monospace" }}>{fmtUSD(data.cash.startCash, { compact: true })}</div>
            </div>
            <div style={{ textAlign: "right" }}>
              <div style={{ fontSize: 10, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.5 }}>In 90 days</div>
              <div style={{ fontSize: 22, fontWeight: 600, fontFamily: "ui-monospace, monospace" }}>{fmtUSD(data.cash.endCash, { compact: true })}</div>
            </div>
          </div>
          <AreaChart
            height={130}
            labels={Array.from({length: 90}, (_, idx) => idx % 30 === 0 ? "+" + idx + "d" : "")}
            series={[{ name: "Cash", values: data.cash.proj, color: "var(--accent)" }]}
            showAxis={true} legend={false}
          />
          <AIInsight>
            Runway healthy at <b>{data.cash.runwayDays > 365 ? "12+ months" : data.cash.runwayDays + " days"}</b>. If <b>Atlas Logistics ($48.2K, 47d)</b> pays this week, projected endpoint improves by 4.3%.
          </AIInsight>
        </Card>
      </div>

      {/* Line item drill modal */}
      {drillKey && (
        <LineItemDrillModal
          itemKey={drillKey}
          data={data}
          cmpOpt={cmpOpt}
          cmpIdx={cmpIdxLast}
          cmpMult={cmpMult}
          onClose={() => setDrillKey(null)}
        />
      )}
    </div>
  );
}

// ─── ComparisonKPI ────────────────────────────────────────────────────
function ComparisonKPI({ label, current, comparison, cmpLabel, sub, spark, accent, inverse = false, onClick }) {
  const delta$ = current - comparison;
  const deltaPctV = comparison === 0 ? 0 : (delta$ / Math.abs(comparison)) * 100;
  // For inverse metrics (Opex), an increase is bad
  const isGood = inverse ? delta$ < 0 : delta$ > 0;
  const color = isGood ? "var(--positive)" : delta$ === 0 ? "var(--text-3)" : "var(--danger)";

  return (
    <div className="pc-kpi pc-kpi-compare" onClick={onClick} style={{ cursor: onClick ? "pointer" : "default" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 8 }}>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div className="pc-kpi-label">{label}</div>
          <div className="pc-kpi-value">{fmtUSD(current, { compact: true })}</div>
          <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 6 }}>
            <span className="pc-delta" style={{ color, background: isGood ? "rgba(110,231,183,0.10)" : "rgba(248,113,113,0.10)" }}>
              {delta$ >= 0 ? "▲" : "▼"} {fmtUSD(Math.abs(delta$), { compact: true })} · {deltaPctV >= 0 ? "+" : ""}{deltaPctV.toFixed(1)}%
            </span>
          </div>
          <div style={{ fontSize: 10.5, color: "var(--text-3)", marginTop: 4, display: "flex", justifyContent: "space-between" }}>
            <span>vs {cmpLabel.toLowerCase()} · {fmtUSD(comparison, { compact: true })}</span>
            {sub && <span>{sub}</span>}
          </div>
        </div>
        {spark && (
          <div style={{ flexShrink: 0 }}>
            <Sparkline values={spark} color={accent} />
          </div>
        )}
      </div>
    </div>
  );
}

// ─── Margin Bar Card ──────────────────────────────────────────────────
function MarginBarCard({ title, subtitle, values, labels, target, current, prior, color, onDrill }) {
  return (
    <Card title={title} subtitle={subtitle}
          action={
            <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
              <div style={{ display: "flex", alignItems: "center", gap: 14, fontSize: 11 }}>
                <span style={{ color: "var(--text-3)" }}>Current <b style={{ color: "var(--text)", fontFamily: "ui-monospace, monospace" }}>{current.toFixed(1)}%</b></span>
                <span style={{ color: "var(--text-3)" }}>Prior <b style={{ color: "var(--text)", fontFamily: "ui-monospace, monospace" }}>{prior.toFixed(1)}%</b></span>
                <span style={{ color: current >= prior ? "var(--positive)" : "var(--danger)", fontFamily: "ui-monospace, monospace" }}>
                  {current >= prior ? "+" : ""}{(current - prior).toFixed(1)} pp
                </span>
              </div>
              <button className="pc-btn-mini ghost" onClick={onDrill}>Drill</button>
            </div>
          }>
      <MarginBars values={values} labels={labels} target={target} color={color} />
    </Card>
  );
}

function MarginBars({ values, labels, target, color, height = 180 }) {
  const ref = useRefF(null);
  const [width, setWidth] = useStateF(600);
  useEffectF(() => {
    if (!ref.current) return;
    const ro = new ResizeObserver(es => { for (const e of es) setWidth(Math.max(280, e.contentRect.width)); });
    ro.observe(ref.current); return () => ro.disconnect();
  }, []);

  const padL = 36, padR = 12, padT = 14, padB = 28;
  const innerW = width - padL - padR;
  const innerH = height - padT - padB;
  const max = Math.max(...values, target) * 1.08;
  const min = Math.min(...values, 0) * 0.9;
  const range = max - min || 1;
  const yFor = (v) => padT + innerH - ((v - min) / range) * innerH;
  const barW = (innerW / values.length) * 0.68;
  const gap = (innerW / values.length) * 0.32;

  return (
    <div ref={ref} style={{ width: "100%" }}>
      <svg width={width} height={height} style={{ display: "block" }}>
        {/* Y axis labels */}
        {[0, 0.5, 1].map(p => {
          const v = min + range * p;
          return (
            <g key={p}>
              <line x1={padL} x2={width - padR} y1={yFor(v)} y2={yFor(v)} stroke="var(--grid)" strokeDasharray="2 4" />
              <text x={padL - 6} y={yFor(v) + 3} textAnchor="end" fontSize="10" fill="var(--text-3)" fontFamily="ui-monospace, monospace">{v.toFixed(0)}%</text>
            </g>
          );
        })}
        {/* Target line */}
        <line x1={padL} x2={width - padR} y1={yFor(target)} y2={yFor(target)} stroke="var(--accent)" strokeWidth="1.5" strokeDasharray="5 4" opacity="0.7" />
        <text x={width - padR - 4} y={yFor(target) - 4} textAnchor="end" fontSize="10" fill="var(--accent)" fontFamily="ui-monospace, monospace">target {target}%</text>

        {/* Bars */}
        {values.map((v, idx) => {
          const x = padL + idx * (barW + gap) + gap/2;
          const y = yFor(v);
          const h = innerH - (y - padT);
          const isCurrent = idx === values.length - 1;
          const aboveTarget = v >= target;
          const fill = isCurrent ? color : aboveTarget ? color : "var(--warning)";
          return (
            <g key={idx}>
              <rect x={x} y={y} width={barW} height={Math.max(h, 1)} fill={fill} rx="2" opacity={isCurrent ? 1 : 0.55} />
              {isCurrent && (
                <text x={x + barW/2} y={y - 5} textAnchor="middle" fontSize="10.5" fill="var(--text)" fontFamily="ui-monospace, monospace" fontWeight="600">{v.toFixed(1)}%</text>
              )}
              <text x={x + barW/2} y={height - 8} textAnchor="middle" fontSize="10" fill="var(--text-3)">{labels[idx]}</text>
            </g>
          );
        })}
      </svg>
    </div>
  );
}

// ─── P&L Variance Table ──────────────────────────────────────────────
function PLVarianceTable({ pl, cmpIdx, cmpMult, cmpLabel, onDrill }) {
  const i = pl.revenue.length - 1;
  const rev = pl.revenue[i], cogs = pl.cogs[i], gp = pl.gp[i], opex = pl.opex[i], ebitda = pl.ebitda[i];
  const cmpRev = Math.round(pl.revenue[cmpIdx] * cmpMult);
  const cmpCogs = Math.round(pl.cogs[cmpIdx] * cmpMult);
  const cmpGp = cmpRev - cmpCogs;
  const cmpOpex = Math.round(pl.opex[cmpIdx] * cmpMult);
  const cmpEbitda = cmpGp - cmpOpex;

  // Sub-rows for Revenue, COGS, Opex
  const revSub = SUB_BREAKDOWNS.revenue.map(s => ({ ...s, current: Math.round(rev * s.share), compare: Math.round(cmpRev * s.share) }));
  const cogsSub = SUB_BREAKDOWNS.cogs.map(s => ({ ...s, current: Math.round(cogs * s.share), compare: Math.round(cmpCogs * s.share) }));
  const opexSub = SUB_BREAKDOWNS.opex.map(s => ({ ...s, current: Math.round(opex * s.share), compare: Math.round(cmpOpex * s.share) }));

  const rows = [
    { label: "Revenue",                    cur: rev,     cmp: cmpRev,     bold: true, key: "revenue", drillable: true },
    ...revSub.map(s => ({ label: s.name,   cur: s.current, cmp: s.compare, indent: true, acct: s.acct })),
    { label: "Cost of goods sold",         cur: cogs,    cmp: cmpCogs,    bold: true, neg: true, key: "cogs", drillable: true },
    ...cogsSub.map(s => ({ label: s.name,  cur: s.current, cmp: s.compare, indent: true, acct: s.acct, neg: true })),
    { label: "Gross profit",               cur: gp,      cmp: cmpGp,      bold: true, accent: true, key: "gp", drillable: true },
    { label: "  Gross margin %",           cur: (gp/rev*100), cmp: (cmpGp/cmpRev*100), pct: true, indent: true },
    { label: "Operating expenses",         cur: opex,    cmp: cmpOpex,    bold: true, neg: true, key: "opex", drillable: true },
    ...opexSub.map(s => ({ label: s.name,  cur: s.current, cmp: s.compare, indent: true, acct: s.acct, neg: true })),
    { label: "EBITDA",                     cur: ebitda,  cmp: cmpEbitda,  bold: true, accent: true, key: "ebitda", drillable: true },
    { label: "  EBITDA margin %",          cur: (ebitda/rev*100), cmp: (cmpEbitda/cmpRev*100), pct: true, indent: true },
  ];

  return (
    <div style={{ overflowX: "auto" }}>
      <table className="pc-table">
        <thead>
          <tr>
            <th style={{ minWidth: 240, textAlign: "left" }}>Line item</th>
            <th style={{ textAlign: "right" }}>Current</th>
            <th style={{ textAlign: "right" }}>{cmpLabel}</th>
            <th style={{ textAlign: "right" }}>Δ $</th>
            <th style={{ textAlign: "right" }}>Δ %</th>
            <th style={{ minWidth: 80 }}>vs target</th>
            <th></th>
          </tr>
        </thead>
        <tbody>
          {rows.map((r, ri) => {
            const dollarDelta = r.cur - r.cmp;
            const pctDelta = r.pct ? (r.cur - r.cmp) : deltaPct(r.cur, r.cmp);
            const isPositive = r.neg ? dollarDelta < 0 : dollarDelta > 0;
            const dColor = (r.bold || r.accent) ? (isPositive ? "var(--positive)" : dollarDelta === 0 ? "var(--text-3)" : "var(--danger)") : "var(--text-2)";
            const valColor = r.accent ? "var(--accent)" : (r.bold ? "var(--text)" : "var(--text-2)");
            return (
              <tr key={ri}
                  className={(r.bold ? "bold " : "") + (r.drillable ? "pc-clickable " : "")}
                  onClick={() => r.drillable && onDrill(r.key)}>
                <td style={{ paddingLeft: r.indent ? 28 : 14, color: r.indent ? "var(--text-2)" : "var(--text)", fontSize: r.indent ? 12 : 13 }}>
                  {r.acct && <span style={{ fontFamily: "ui-monospace, monospace", color: "var(--text-3)", fontSize: 10.5, marginRight: 8 }}>{r.acct}</span>}
                  {r.label.trim()}
                  {r.drillable && <Icon d={icons.chevron} size={11} stroke="var(--text-3)" style={{ marginLeft: 8, verticalAlign: "middle", opacity: 0.6 }} />}
                </td>
                <td style={{ fontFamily: "ui-monospace, 'Geist Mono', monospace", textAlign: "right", color: valColor, fontVariantNumeric: "tabular-nums" }}>
                  {r.pct ? r.cur.toFixed(1) + "%" : (r.neg && r.cur > 0 ? "(" + fmtUSD(r.cur, { compact: true }) + ")" : fmtUSD(r.cur, { compact: true }))}
                </td>
                <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", color: "var(--text-3)", fontVariantNumeric: "tabular-nums" }}>
                  {r.pct ? r.cmp.toFixed(1) + "%" : (r.neg && r.cmp > 0 ? "(" + fmtUSD(r.cmp, { compact: true }) + ")" : fmtUSD(r.cmp, { compact: true }))}
                </td>
                <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", color: dColor, fontVariantNumeric: "tabular-nums" }}>
                  {r.pct ? (dollarDelta >= 0 ? "+" : "") + dollarDelta.toFixed(1) + " pp" :
                   (dollarDelta >= 0 ? "+" : "−") + fmtUSD(Math.abs(dollarDelta), { compact: true })}
                </td>
                <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", color: dColor, fontVariantNumeric: "tabular-nums" }}>
                  {r.pct ? (pctDelta >= 0 ? "+" : "") + pctDelta.toFixed(1) + " pp" : fmtPct(pctDelta)}
                </td>
                <td>
                  <Bullet value={Math.min(Math.abs(pctDelta) + 50, 100)} target={50} max={100} accent={isPositive ? "var(--positive)" : "var(--danger)"} />
                </td>
                <td>
                  {r.drillable && <Icon d={icons.chevron} size={12} stroke="var(--text-3)" />}
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

// ─── Line Item Drill Modal ───────────────────────────────────────────
function LineItemDrillModal({ itemKey, data, cmpOpt, cmpIdx, cmpMult, onClose }) {
  const { pl } = data;
  const i = pl.revenue.length - 1;
  const series = pl[itemKey === "gp" ? "gp" : itemKey === "ebitda" ? "ebitda" : itemKey] || pl.revenue;
  const current = series[i];
  const cmp = Math.round(series[cmpIdx] * cmpMult);
  const delta$ = current - cmp;
  const deltaPctV = cmp === 0 ? 0 : (delta$ / Math.abs(cmp)) * 100;
  const isNegLine = itemKey === "cogs" || itemKey === "opex";
  const isGood = isNegLine ? delta$ < 0 : delta$ > 0;
  const color = isGood ? "var(--positive)" : "var(--danger)";

  const titles = {
    revenue: "Revenue", cogs: "Cost of goods sold", gp: "Gross profit", opex: "Operating expenses", ebitda: "EBITDA",
  };
  const accents = {
    revenue: "var(--accent)", cogs: "var(--warning)", gp: "var(--accent-2)", opex: "var(--warning)", ebitda: "var(--positive)",
  };

  const subs = SUB_BREAKDOWNS[itemKey] || [];
  const kpis = LINE_KPIS[itemKey] || [];
  const lineColor = accents[itemKey];

  // 12-month series for chart
  const trendValues = series.slice();
  const trendLabels = pl.labels;

  return (
    <div className="pc-modal-backdrop" onClick={onClose}>
      <div className="pc-modal pc-modal-wide" onClick={(e) => e.stopPropagation()}>
        <div className="pc-modal-hd">
          <div className="pc-breadcrumb">
            <span style={{ cursor: "pointer", color: "var(--text-3)" }} onClick={onClose}>Operating P&L</span>
            <span style={{ opacity: 0.4 }}>›</span>
            <span style={{ fontWeight: 500 }}>{titles[itemKey]}</span>
          </div>
          <div style={{ display: "flex", gap: 8 }}>
            <ExportButton rows={subs.map(s => ({ Account: s.acct, Name: s.name, Current: Math.round(current * s.share), Comparison: Math.round(cmp * s.share) }))} filename={titles[itemKey] + "_drill"} />
            <button className="pc-icon-btn" onClick={onClose} title="Close"><Icon d={icons.x} size={14} /></button>
          </div>
        </div>
        <div className="pc-modal-body">
          {/* Hero header */}
          <div className="pc-drill-hero">
            <div>
              <div style={{ fontSize: 11, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.6 }}>Current period · May 2026</div>
              <h2 style={{ fontSize: 32, fontFamily: "'Instrument Serif', serif", fontWeight: 400, margin: "4px 0 4px", color: lineColor }}>
                {fmtUSD(current, { compact: true })}
              </h2>
              <div style={{ display: "flex", alignItems: "center", gap: 10, fontSize: 12 }}>
                <span style={{ color: "var(--text-3)" }}>vs {cmpOpt.label.toLowerCase()} {fmtUSD(cmp, { compact: true })}</span>
                <span className="pc-delta" style={{ color, background: isGood ? "rgba(110,231,183,0.10)" : "rgba(248,113,113,0.10)" }}>
                  {delta$ >= 0 ? "▲" : "▼"} {fmtUSD(Math.abs(delta$), { compact: true })} · {deltaPctV >= 0 ? "+" : ""}{deltaPctV.toFixed(1)}%
                </span>
              </div>
            </div>
            <div className="pc-drill-mini-kpis">
              <div className="pc-drill-mini-kpi">
                <div className="pc-mk-l">% of revenue</div>
                <div className="pc-mk-v">{itemKey === "revenue" ? "100%" : (current / pl.revenue[i] * 100).toFixed(1) + "%"}</div>
              </div>
              <div className="pc-drill-mini-kpi">
                <div className="pc-mk-l">12-mo avg</div>
                <div className="pc-mk-v">{fmtUSD(trendValues.reduce((s,v)=>s+v,0)/trendValues.length, { compact: true })}</div>
              </div>
              <div className="pc-drill-mini-kpi">
                <div className="pc-mk-l">12-mo high</div>
                <div className="pc-mk-v">{fmtUSD(Math.max(...trendValues), { compact: true })}</div>
              </div>
              <div className="pc-drill-mini-kpi">
                <div className="pc-mk-l">12-mo low</div>
                <div className="pc-mk-v">{fmtUSD(Math.min(...trendValues), { compact: true })}</div>
              </div>
            </div>
          </div>

          {/* Trend chart */}
          <div className="pc-card-inner" style={{ marginBottom: 16 }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
              <div>
                <div className="pc-card-title">12-month trend</div>
                <div className="pc-card-subtitle">With {cmpOpt.label.toLowerCase()} comparison line</div>
              </div>
                <SegSmall opts={["12M", "6M", "Quarterly", "YoY"]} value="12M" onChange={() => {}} />
            </div>
            <AreaChart
              height={220}
              labels={trendLabels}
              series={[
                { name: titles[itemKey], values: trendValues, color: lineColor },
                { name: cmpOpt.label, values: trendValues.map((v) => Math.round(v / (1 + (deltaPctV/100/12)))), color: "var(--text-3)", fill: false, dashed: true },
              ]}
            />
          </div>

          {/* KPIs related to this line */}
          {kpis.length > 0 && (
            <div className="pc-drill-section">
              <div className="pc-drill-section-label">Operating KPIs · linked to {titles[itemKey]}</div>
              <div className="pc-drill-kpi-grid">
                {kpis.map((k, idx) => {
                  const fmt = k.format === "usd" ? fmtUSD(k.base) : k.format === "pct" ? k.base.toFixed(1) + "%" : k.format === "ratio" ? k.base.toFixed(2) + "x" : fmtNum(k.base);
                  return (
                    <div key={idx} className="pc-drill-kpi">
                      <div className="pc-mk-l">{k.label}</div>
                      <div className="pc-mk-v">{fmt}</div>
                      <div className="pc-mk-d" style={{ color: k.delta >= 0 ? "var(--positive)" : "var(--danger)" }}>
                        {k.delta >= 0 ? "▲" : "▼"} {Math.abs(k.delta).toFixed(1)}%
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          )}

          {/* Sub-account breakdown */}
          {subs.length > 0 && (
            <div className="pc-drill-section">
              <div className="pc-drill-section-label">Sub-account composition · {subs.length} accounts</div>
              <table className="pc-table compact">
                <thead>
                  <tr><th>Account</th><th>Name</th><th style={{textAlign:"right"}}>Current</th><th style={{textAlign:"right"}}>% of total</th><th style={{textAlign:"right"}}>{cmpOpt.label}</th><th style={{textAlign:"right"}}>Δ $</th><th>Trend</th></tr>
                </thead>
                <tbody>
                  {subs.map((s, idx) => {
                    const sCur = Math.round(current * s.share);
                    const sCmp = Math.round(cmp * s.share * (0.96 + (idx*0.013))); // synthetic per-row variance
                    const sDelta = sCur - sCmp;
                    return (
                      <tr key={idx}>
                        <td style={{ paddingLeft: 14, fontFamily: "ui-monospace, monospace", fontSize: 11, color: "var(--text-3)" }}>{s.acct}</td>
                        <td style={{ fontWeight: 500 }}>{s.name}</td>
                        <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right" }}>{fmtUSD(sCur, { compact: true })}</td>
                        <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", color: "var(--text-3)" }}>{(s.share * 100).toFixed(1)}%</td>
                        <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", color: "var(--text-3)" }}>{fmtUSD(sCmp, { compact: true })}</td>
                        <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", color: (isNegLine ? sDelta < 0 : sDelta > 0) ? "var(--positive)" : "var(--danger)" }}>
                          {sDelta >= 0 ? "+" : "−"}{fmtUSD(Math.abs(sDelta), { compact: true })}
                        </td>
                        <td><Sparkline values={Array.from({ length: 12 }, (_, k) => Math.round(sCur * (0.85 + Math.random() * 0.3)))} width={70} height={22} color={lineColor} /></td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          )}

          {/* Variance bridge for GP / EBITDA */}
          {(itemKey === "gp" || itemKey === "ebitda") && (
            <div className="pc-drill-section">
              <div className="pc-drill-section-label">Variance bridge · what drove the change</div>
              <VarianceBridge itemKey={itemKey} cmp={cmp} current={current} />
            </div>
          )}

          {/* AI insight */}
          <AIInsight>
            {itemKey === "revenue" && <><b>Revenue</b> moved {deltaPctV >= 0 ? "up" : "down"} {Math.abs(deltaPctV).toFixed(1)}% driven primarily by <b>Polaris Beacon</b> (+24% on accelerated enterprise wins) offset by <b>Meridian Sleeve</b> (−28% as the line ages). Mix shifted toward higher-ASP SKUs, lifting AOV but compressing units sold.</>}
            {itemKey === "cogs" && <><b>COGS</b> grew faster than revenue this period. Decomposition: <b>67% input cost</b> (V-201 lots received post-Apr 18 at +9% material cost), <b>22% mix</b> (heavier Premium-line volume), <b>11% freight</b> (ocean rate increase). Renegotiating V-201 or passing 4% through to wholesale recovers ~1.2 pp of GM.</>}
            {itemKey === "gp" && <><b>Gross profit</b> declined despite revenue growth — a classic margin-compression signal. The walk: −$52K from input cost, +$18K from volume mix, neutral from price. Re-pricing wholesale by 4% (still under DTC by 18%) restores most of the lost dollars without volume risk.</>}
            {itemKey === "opex" && <><b>Opex</b> increased $35.3K. Decomposition: <b>$18K software</b> (auto-renewals to enterprise tiers, 4 tools with usage &lt; 30%), <b>$11K travel</b> (one-time conference), <b>$6K other</b>. Estimated <b>$48K annualized</b> savings available on the software stack alone.</>}
            {itemKey === "ebitda" && <><b>EBITDA margin compressed 3.2 pts</b>: 1.8 pts from gross margin, 1.4 pts from opex deleverage. The good news: <b>92% is identifiable, addressable, and reversible</b> within 1–2 cycles. The bad news: it requires action — without intervention, both effects persist into next quarter.</>}
          </AIInsight>

          {/* Source transactions */}
          <div className="pc-drill-section">
            <div className="pc-drill-section-label">Recent source transactions · top 8 of 1,847</div>
            <table className="pc-table compact">
              <thead><tr><th>Date</th><th>Account</th><th>Reference</th><th>Memo</th><th style={{textAlign:"right"}}>Amount</th></tr></thead>
              <tbody>
                {[
                  { d: "May 12, 2026", a: subs[0]?.acct || "4000", r: "INV-24142", m: "Halcyon Group — Phase 2 milestone", v: 84200 },
                  { d: "May 12, 2026", a: subs[1]?.acct || "4010", r: "INV-24141", m: "Northwind — wholesale order Q2",   v: 62500 },
                  { d: "May 11, 2026", a: subs[0]?.acct || "4000", r: "ORD-9921", m: "Online — bundle pack",             v: 3940 },
                  { d: "May 11, 2026", a: subs[2]?.acct || "4020", r: "MKP-1182", m: "Marketplace — daily payout",       v: 14200 },
                  { d: "May 10, 2026", a: subs[0]?.acct || "4000", r: "ORD-9912", m: "Online — Aurelius Pro Kit",        v: 1495 },
                  { d: "May 10, 2026", a: subs[1]?.acct || "4010", r: "INV-24134", m: "Ironwood — partial ship",         v: 18400 },
                  { d: "May 09, 2026", a: subs[0]?.acct || "4000", r: "ORD-9904", m: "Online — multi-SKU bundle",        v: 2840 },
                  { d: "May 09, 2026", a: subs[3]?.acct || "4050", r: "SUB-2241", m: "Subscription renewal — Q2",        v: 8200 },
                ].map((tx, idx) => (
                  <tr key={idx}>
                    <td style={{ paddingLeft: 14, fontSize: 11.5, color: "var(--text-2)", whiteSpace: "nowrap" }}>{tx.d}</td>
                    <td style={{ fontFamily: "ui-monospace, monospace", fontSize: 11, color: "var(--text-3)" }}>{tx.a}</td>
                    <td style={{ fontFamily: "ui-monospace, monospace", fontSize: 11.5 }}>{tx.r}</td>
                    <td style={{ fontSize: 12 }}>{tx.m}</td>
                    <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", fontWeight: 500 }}>{fmtUSD(tx.v)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── Variance bridge (waterfall) ─────────────────────────────────────
function VarianceBridge({ itemKey, cmp, current }) {
  const drivers = itemKey === "gp"
    ? [
        { label: "Price", value: -8400, color: "var(--danger)" },
        { label: "Volume", value: 22000, color: "var(--positive)" },
        { label: "Mix", value: -4200, color: "var(--danger)" },
        { label: "Input cost", value: -52100, color: "var(--danger)" },
        { label: "Freight", value: 1800, color: "var(--positive)" },
      ]
    : [
        { label: "GP impact", value: -52100, color: "var(--danger)" },
        { label: "Personnel", value: -18000, color: "var(--danger)" },
        { label: "Software", value: -8400, color: "var(--danger)" },
        { label: "Travel & ent.", value: -6200, color: "var(--danger)" },
        { label: "Facilities", value: 2200, color: "var(--positive)" },
      ];
  const total = current - cmp;

  // Build waterfall positions
  const items = [
    { label: cmp > 0 ? "Prior" : "Start", value: cmp, type: "start" },
    ...drivers.map(d => ({ ...d, type: "delta" })),
    { label: "Current", value: current, type: "end" },
  ];

  // Find range for scaling
  const all = [cmp, current, ...drivers.map(d => d.value)];
  let runningHi = cmp, runningLo = cmp;
  let running = cmp;
  for (const d of drivers) {
    running += d.value;
    runningHi = Math.max(runningHi, running);
    runningLo = Math.min(runningLo, running);
  }
  const max = Math.max(cmp, current, runningHi) * 1.05;
  const min = Math.min(0, runningLo) * 1.05;
  const range = max - min || 1;

  const height = 200;
  const padT = 20, padB = 40;
  const innerH = height - padT - padB;
  const yFor = (v) => padT + innerH - ((v - min) / range) * innerH;

  let cursor = cmp;
  return (
    <div className="pc-card-inner" style={{ padding: 0 }}>
      <div style={{ display: "flex", justifyContent: "space-around", alignItems: "stretch", padding: "12px 8px" }}>
        {items.map((it, idx) => {
          let barTop, barBottom, fill, labelTop;
          if (it.type === "start") {
            barTop = yFor(it.value); barBottom = yFor(0);
            fill = "var(--text-3)";
            labelTop = barTop - 16;
          } else if (it.type === "end") {
            barTop = yFor(it.value); barBottom = yFor(0);
            fill = it.value >= cmp ? "var(--positive)" : "var(--danger)";
            labelTop = barTop - 16;
          } else {
            if (it.value >= 0) { barTop = yFor(cursor + it.value); barBottom = yFor(cursor); }
            else { barTop = yFor(cursor); barBottom = yFor(cursor + it.value); }
            fill = it.color;
            labelTop = barTop - 16;
            cursor += it.value;
          }
          const h = Math.max(barBottom - barTop, 2);
          return (
            <div key={idx} style={{ flex: 1, position: "relative", minWidth: 80 }}>
              <svg width="100%" height={height} style={{ display: "block" }}>
                <rect x="20%" y={barTop} width="60%" height={h} fill={fill} rx="2" opacity={it.type === "start" || it.type === "end" ? 1 : 0.85} />
                <text x="50%" y={labelTop} textAnchor="middle" fontSize="11" fill="var(--text)" fontFamily="ui-monospace, monospace" fontWeight={it.type === "start" || it.type === "end" ? 600 : 500}>
                  {it.type === "delta" ? (it.value >= 0 ? "+" : "−") + fmtUSD(Math.abs(it.value), { compact: true }) : fmtUSD(it.value, { compact: true })}
                </text>
                <text x="50%" y={height - 18} textAnchor="middle" fontSize="10.5" fill="var(--text-3)">{it.label}</text>
              </svg>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function LegendItem({ color, label, value, pct }) {
  return (
    <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "8px 2px", fontSize: 12.5, borderBottom: "1px solid var(--hover)" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
        <span style={{ width: 8, height: 8, borderRadius: 1, background: color }} />
        <span style={{ color: "var(--text-2)" }}>{label}</span>
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: 12, fontFamily: "ui-monospace, monospace" }}>
        <span style={{ color: "var(--text-3)", fontSize: 11 }}>{pct.toFixed(1)}%</span>
        <span style={{ color: "var(--text)", minWidth: 60, textAlign: "right" }}>{value}</span>
      </div>
    </div>
  );
}

function SegSmall({ opts, active, value, onChange }) {
  const initial = value !== undefined ? value : (active !== undefined ? active : (opts[0] && (opts[0].value || opts[0])));
  const [internal, setInternal] = useStateF(initial);
  const current = value !== undefined ? value : internal;
  const handleClick = (v) => {
    if (value === undefined) setInternal(v);
    if (onChange) onChange(v);
  };
  return (
    <div className="pc-seg-sm">
      {opts.map(o => {
        const v = typeof o === "object" ? o.value : o;
        const label = typeof o === "object" ? o.label : o;
        return <button key={v} className={current === v ? "active" : ""} onClick={() => handleClick(v)}>{label}</button>;
      })}
    </div>
  );
}

// ─── P&L Detail Card — multi-view P&L with analytics toggle ────────────
function PLDetailCard({ pl, cmpOpt, cmpIdx, cmpMult, onDrill, curIdx: propCurIdx }) {
  const [mode, setMode] = useStateF("monthly");
  const [analytics, setAnalytics] = useStateF("none");
  const [expanded, setExpanded] = useStateF({ revenue: false, cogs: false, opex: false });
  const i = pl.revenue.length - 1;
  // curIdx from parent (period-aware) or fallback to latest month
  const activeCurIdx = propCurIdx && propCurIdx.length > 0 ? propCurIdx : [i];

  const rowDef = (label, key, opts = {}) => ({ label, key, ...opts });
  const allRows = [
    rowDef("Revenue", "revenue", { bold: true, drillable: true, expandable: true }),
    rowDef("Product Sales — Online",   "rev_4000", { indent: true, parent: "revenue", share: 0.42 }),
    rowDef("Wholesale Revenue",        "rev_4010", { indent: true, parent: "revenue", share: 0.32 }),
    rowDef("Marketplace Revenue",      "rev_4020", { indent: true, parent: "revenue", share: 0.17 }),
    rowDef("Subscription / Recurring", "rev_4050", { indent: true, parent: "revenue", share: 0.11 }),
    rowDef("Returns & Allowances",     "rev_4090", { indent: true, parent: "revenue", share: -0.02, neg: true }),
    rowDef("Cost of goods sold", "cogs", { bold: true, neg: true, drillable: true, expandable: true }),
    rowDef("Direct Material",         "cogs_5000", { indent: true, parent: "cogs", share: 0.58, neg: true }),
    rowDef("Direct Labor",            "cogs_5100", { indent: true, parent: "cogs", share: 0.18, neg: true }),
    rowDef("Inbound Freight",         "cogs_5010", { indent: true, parent: "cogs", share: 0.11, neg: true }),
    rowDef("Packaging",               "cogs_5020", { indent: true, parent: "cogs", share: 0.07, neg: true }),
    rowDef("Manufacturing Overhead",  "cogs_5200", { indent: true, parent: "cogs", share: 0.06, neg: true }),
    rowDef("Gross profit", "gp", { bold: true, accent: true, drillable: true }),
    rowDef("Gross margin %", "gp_pct", { indent: true, pct: true, muted: true }),
    rowDef("Operating expenses", "opex", { bold: true, neg: true, drillable: true, expandable: true }),
    rowDef("Personnel — Salaries & Benefits", "opex_6010", { indent: true, parent: "opex", share: 0.51, neg: true }),
    rowDef("Sales & Marketing",              "opex_6200", { indent: true, parent: "opex", share: 0.18, neg: true }),
    rowDef("Software & Subscriptions",        "opex_6900", { indent: true, parent: "opex", share: 0.09, neg: true }),
    rowDef("Facilities & Rent",               "opex_6100", { indent: true, parent: "opex", share: 0.08, neg: true }),
    rowDef("Professional Services",           "opex_6500", { indent: true, parent: "opex", share: 0.07, neg: true }),
    rowDef("G&A — Other",                    "opex_6700", { indent: true, parent: "opex", share: 0.07, neg: true }),
    rowDef("EBITDA", "ebitda", { bold: true, accent: true, drillable: true }),
    rowDef("EBITDA margin %", "ebitda_pct", { indent: true, pct: true, muted: true }),
  ];

  // Filter rows by expanded state
  const baseRows = allRows.filter(r => !r.parent || expanded[r.parent]);

  const valueAt = (key, idx) => {
    if (!key) return 0;
    if (key === "revenue") return pl.revenue[idx] || 0;
    if (key === "cogs") return pl.cogs[idx] || 0;
    if (key === "gp") return pl.gp[idx] || 0;
    if (key === "opex") return pl.opex[idx] || 0;
    if (key === "ebitda") return pl.ebitda[idx] || 0;
    if (key === "gp_pct") { const r = pl.revenue[idx] || 0; return r > 0 ? (pl.gp[idx] / r) * 100 : 0; }
    if (key === "ebitda_pct") { const r = pl.revenue[idx] || 0; return r > 0 ? (pl.ebitda[idx] / r) * 100 : 0; }
    const row = allRows.find(x => x.key === key);
    if (!row) return 0;
    const parentVal = (pl[row.parent] && pl[row.parent][idx]) || 0;
    return Math.round(parentVal * (row.share || 0));
  };
  const sumValue = (key, idxs) => idxs.reduce((s, idx) => s + valueAt(key, idx), 0);
  const ratioValue = (key, idxs) => {
    if (key === "gp_pct")     return sumValue("revenue", idxs) > 0 ? sumValue("gp", idxs) / sumValue("revenue", idxs) * 100 : 0;
    if (key === "ebitda_pct") return sumValue("revenue", idxs) > 0 ? sumValue("ebitda", idxs) / sumValue("revenue", idxs) * 100 : 0;
    return sumValue(key, idxs);
  };

  const cols = (() => {
    if (mode === "variance") {
      return [
        { id: "cur",  label: "Current",   indices: activeCurIdx },
        { id: "cmp",  label: cmpOpt.label, indices: [cmpIdx], mult: cmpMult, isComp: true },
        { id: "dlr",  label: "Δ $",       compute: (k) => ratioValue(k, activeCurIdx) - ratioValue(k, [cmpIdx]) * (cmpMult || 1) },
        { id: "pct",  label: "Δ %",       compute: (k) => {
          const cur = ratioValue(k, activeCurIdx);
          const cmpVal = ratioValue(k, [cmpIdx]) * (cmpMult || 1);
          return cmpVal === 0 ? 0 : ((cur - cmpVal) / Math.abs(cmpVal)) * 100;
        } },
      ];
    }
    if (mode === "monthly") {
      const idxs = []; for (let k = Math.max(0, i - 5); k <= i; k++) idxs.push(k);
      return [...idxs.map(k => ({ id: "m" + k, label: pl.labels[k] + " " + pl.years[k].toString().slice(2), indices: [k] })),
        { id: "tot", label: "Total", indices: idxs, bold: true }];
    }
    if (mode === "ytd") {
      const idxs = []; for (let k = Math.max(0, i - 4); k <= i; k++) idxs.push(k);
      return [...idxs.map(k => ({ id: "m" + k, label: pl.labels[k] + " " + pl.years[k].toString().slice(2), indices: [k] })),
        { id: "tot", label: "YTD", indices: idxs, bold: true }];
    }
    if (mode === "ltm") {
      const idxs = []; for (let k = 0; k <= i; k++) idxs.push(k);
      return [...idxs.map(k => ({ id: "m" + k, label: pl.labels[k], indices: [k] })),
        { id: "tot", label: "LTM", indices: idxs, bold: true }];
    }
    return [];
  })();

  const cellValue = (col, row) => col.compute ? col.compute(row.key) : ratioValue(row.key, col.indices) * (col.mult || 1);
  const compact = mode === "ltm";
  const showTrend = mode !== "variance"; // last column is a sparkline per row

  // Trend series for a row across the visible month columns
  const trendSeries = (row) => {
    const monthCols = cols.filter(c => c.id !== "tot" && c.id !== "dlr" && c.id !== "pct" && c.id !== "cmp");
    return monthCols.map(c => cellValue(c, row));
  };

  const exportRows = baseRows.map(r => {
    const obj = { Line: r.label };
    cols.forEach(c => { obj[c.label] = cellValue(c, r); });
    return obj;
  });

  // ─── AI findings summary ──
  const curRev = sumValue("revenue", activeCurIdx);
  const prevRev = sumValue("revenue", [cmpIdx]) || 1;
  const curGM = ratioValue("gp_pct", activeCurIdx);
  const prevGM = ratioValue("gp_pct", [cmpIdx]);
  const curEBITDA = ratioValue("ebitda_pct", activeCurIdx);
  const prevEBITDA = ratioValue("ebitda_pct", [cmpIdx]);

  return (
    <Card title="Operating P&L"
          subtitle={
            mode === "variance" ? `Current period vs. ${cmpOpt.label.toLowerCase()}` :
            mode === "monthly"  ? "Last 6 months side by side" :
            mode === "ytd"      ? "Year to date · month by month" :
            "Trailing 12 months · month by month"
          }
          action={
            <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}>
              <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                <span style={{ fontSize: 10.5, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.5 }}>View</span>
                <SegSmall opts={[
                  { value: "variance", label: "Variance" },
                  { value: "monthly",  label: "Monthly" },
                  { value: "ytd",      label: "YTD" },
                  { value: "ltm",      label: "LTM" },
                ]} value={mode} onChange={setMode} />
              </div>
              <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                <span style={{ fontSize: 10.5, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.5 }}>Show</span>
                <SegSmall opts={[
                  { value: "none", label: "$" },
                  { value: "pct",  label: "%" },
                  { value: "both", label: "$ + %" },
                ]} value={analytics} onChange={setAnalytics} />
              </div>
              <ExportButton rows={exportRows} filename={"PL_" + mode} />
            </div>
          } padding={0}>
      <div style={{ overflowX: "auto" }}>
        <table className={"pc-table " + (compact ? "compact" : "")} style={{ minWidth: compact ? 1280 : 800 }}>
          <thead>
            <tr>
              <th style={{ minWidth: compact ? 220 : 260, textAlign: "left", position: "sticky", left: 0, background: "var(--bg-card-solid)", zIndex: 2 }}>Line item</th>
              {cols.map(c => (
                <th key={c.id} style={{ textAlign: "right", whiteSpace: "nowrap", minWidth: compact ? 76 : 100, fontWeight: c.bold ? 600 : undefined, color: c.bold ? "var(--text)" : c.isComp ? "var(--text-2)" : undefined }}>
                  {c.label}
                </th>
              ))}
              {showTrend && <th style={{ textAlign: "left", minWidth: 110, paddingLeft: 14 }}>Trend</th>}
            </tr>
          </thead>
          <tbody>
            {baseRows.map((r, ri) => {
              const revForCol = (col) => sumValue("revenue", col.indices) * (col.mult || 1);
              const isExpanded = r.expandable && expanded[r.key];
              const series = showTrend ? trendSeries(r) : null;
              // Trend direction for the bold rows
              const trendDir = series && series.length >= 2 ? (series[series.length - 1] - series[0]) : 0;
              const trendIsGood = r.neg ? trendDir < 0 : trendDir > 0;
              const trendColor = r.accent ? "var(--accent)" : trendDir === 0 ? "var(--text-3)" : (trendIsGood ? "var(--positive)" : "var(--danger)");

              return (
                <tr key={ri} className={(r.bold ? "bold " : "") + (r.drillable ? "pc-clickable" : "")}>
                  <td
                    style={{
                      paddingLeft: r.indent ? 32 : 14,
                      color: r.indent ? "var(--text)" : "var(--text)",
                      fontSize: compact ? 11.5 : (r.indent ? 12.5 : 13.5),
                      fontWeight: r.bold ? 700 : 500,
                      position: "sticky",
                      left: 0,
                      background: "var(--bg-card-solid)",
                      zIndex: 2,
                    }}
                    onClick={() => r.expandable ? setExpanded(s => ({ ...s, [r.key]: !s[r.key] })) : (r.drillable && onDrill && onDrill(r.key))}
                  >
                    <span style={{ display: "inline-flex", alignItems: "center", gap: 6, cursor: r.expandable || r.drillable ? "pointer" : "default" }}>
                      {r.expandable && (
                        <Icon d={icons.chevron} size={11} stroke="var(--text-2)" style={{ transform: isExpanded ? "rotate(90deg)" : "none", transition: "transform 0.12s" }} />
                      )}
                      {r.label}
                      {r.drillable && !r.expandable && <Icon d={icons.chevron} size={10} stroke="var(--text-3)" />}
                    </span>
                  </td>
                  {cols.map(c => {
                    const v = cellValue(c, r);
                    const isDeltaDlr = c.id === "dlr";
                    const isDeltaPct = c.id === "pct";

                    if (isDeltaPct) {
                      const sign = v >= 0 ? "+" : "";
                      const isGood = r.neg ? v < 0 : v > 0;
                      const dColor = isGood ? "var(--positive)" : v === 0 ? "var(--text-3)" : "var(--danger)";
                      return <td key={c.id} style={{ fontFamily: "'Geist Mono', ui-monospace, monospace", textAlign: "right", color: dColor, fontVariantNumeric: "tabular-nums", fontSize: compact ? 11.5 : 12.5, fontWeight: r.bold ? 600 : 500 }}>{r.pct ? sign + v.toFixed(1) + " pp" : sign + v.toFixed(1) + "%"}</td>;
                    }
                    if (isDeltaDlr) {
                      const sign = v >= 0 ? "+" : "−";
                      const isGood = r.neg ? v < 0 : v > 0;
                      const dColor = isGood ? "var(--positive)" : v === 0 ? "var(--text-3)" : "var(--danger)";
                      return <td key={c.id} style={{ fontFamily: "'Geist Mono', ui-monospace, monospace", textAlign: "right", color: dColor, fontVariantNumeric: "tabular-nums", fontSize: compact ? 11.5 : 12.5, fontWeight: r.bold ? 600 : 500 }}>{r.pct ? "—" : sign + fmtUSD(Math.abs(v), { compact: true })}</td>;
                    }

                    // Determine cell color — darker for primary, accent for GP/EBITDA, muted only for margin % rows
                    const valColor = r.accent ? "var(--accent)" : r.muted ? "var(--text-2)" : "var(--text)";
                    const display = r.pct
                      ? v.toFixed(1) + "%"
                      : ((r.neg && v > 0 ? "(" : "") + fmtUSD(v, { compact: true }) + (r.neg && v > 0 ? ")" : ""));
                    const rev = revForCol(c);
                    const pctOfSales = rev > 0 ? (v / rev) * 100 : 0;
                    const showDollars = analytics === "none" || analytics === "both";
                    const showPct = (analytics === "pct" || analytics === "both") && !r.pct;

                    return (
                      <td key={c.id} style={{
                        fontFamily: "'Geist Mono', ui-monospace, monospace",
                        textAlign: "right",
                        color: valColor,
                        fontVariantNumeric: "tabular-nums",
                        fontSize: compact ? 11.5 : 12.5,
                        fontWeight: r.bold ? 700 : r.indent ? 500 : 600,
                        padding: compact ? "7px 9px" : undefined,
                      }}>
                        {(showDollars || r.pct) && <div>{display}</div>}
                        {showPct && (
                          <div style={{ fontSize: compact ? 9.5 : 10.5, color: "var(--text-3)", marginTop: showDollars ? 2 : 0, fontWeight: 400 }}>
                            {pctOfSales.toFixed(1)}%
                          </div>
                        )}
                      </td>
                    );
                  })}
                  {showTrend && (
                    <td style={{ paddingLeft: 14, paddingRight: 14, minWidth: 110 }}>
                      {series && (
                        <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                          <Sparkline values={series} color={trendColor} width={70} height={22} fill={false} strokeWidth={1.8} />
                          <span style={{
                            fontSize: 10,
                            color: trendColor,
                            fontFamily: "ui-monospace, monospace",
                          }}>
                            {trendDir === 0 ? "—" : trendDir > 0 ? "▲" : "▼"}
                          </span>
                        </div>
                      )}
                    </td>
                  )}
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      {/* AI findings summary */}
      <div style={{ padding: "16px 18px", borderTop: "1px solid var(--border)", background: "var(--bg-elev-1)" }}>
        <div style={{ display: "flex", alignItems: "flex-start", gap: 12, marginBottom: 10 }}>
          <div style={{ width: 24, height: 24, borderRadius: 6, background: "radial-gradient(circle at 30% 30%, var(--accent), var(--accent-2))", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
            <Icon d={icons.ai} size={12} stroke="var(--on-accent)" strokeWidth={2.4} />
          </div>
          <div style={{ fontSize: 11, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.6, fontWeight: 500, paddingTop: 5 }}>
            Findings on this period
          </div>
        </div>
        <ul style={{ margin: 0, paddingLeft: 18, fontSize: 12.5, color: "var(--text)", lineHeight: 1.65 }}>
          <li><b>Revenue {curRev >= prevRev ? "grew" : "declined"} {Math.abs((curRev - prevRev) / prevRev * 100).toFixed(1)}%</b> vs last month, driven by Product Sales Online and Wholesale.</li>
          <li><b style={{ color: curGM < prevGM ? "var(--danger)" : "var(--positive)" }}>Gross margin {curGM < prevGM ? "compressed" : "expanded"} {Math.abs(curGM - prevGM).toFixed(1)} pp</b> ({prevGM.toFixed(1)}% → {curGM.toFixed(1)}%). Material cost is the dominant driver — V-201 input prices stepped up on April lots and haven't been passed through to wholesale.</li>
          <li><b>Software & Subscriptions runs hot</b> at ~2.2% of sales — auto-renewals on enterprise tiers; an audit identified $48K annualized savings.</li>
          <li><b style={{ color: curEBITDA < prevEBITDA ? "var(--danger)" : "var(--positive)" }}>EBITDA margin {curEBITDA < prevEBITDA ? "compressed" : "expanded"} {Math.abs(curEBITDA - prevEBITDA).toFixed(1)} pp</b>, fully attributable to the GM step plus modest opex deleverage. Both are reversible in 1–2 cycles.</li>
          <li>Click any bold line (Revenue, COGS, Gross profit, Opex, EBITDA) to drill into transactions or expand the chevron to see sub-accounts in place.</li>
        </ul>
      </div>
    </Card>
  );
}

function PLTable({ pl }) {
  const tail = 6;
  const months = pl.labels.slice(-tail);
  const years = pl.years.slice(-tail);
  const rows = [
    { label: "Revenue",       values: pl.revenue.slice(-tail), bold: true },
    { label: "  Cost of goods sold", values: pl.cogs.slice(-tail), neg: true, indent: true },
    { label: "Gross profit",  values: pl.gp.slice(-tail), bold: true, accent: true },
    { label: "  Gross margin %",  values: pl.gp.slice(-tail).map((g, i) => g / pl.revenue.slice(-tail)[i] * 100), indent: true, pct: true },
    { label: "  Operating expenses", values: pl.opex.slice(-tail), neg: true, indent: true },
    { label: "EBITDA",       values: pl.ebitda.slice(-tail), bold: true, accent: true },
    { label: "  EBITDA margin %", values: pl.ebitda.slice(-tail).map((e, i) => e / pl.revenue.slice(-tail)[i] * 100), indent: true, pct: true },
  ];

  return (
    <div style={{ overflowX: "auto" }}>
      <table className="pc-table">
        <thead>
          <tr>
            <th style={{ minWidth: 220, textAlign: "left" }}>Line item</th>
            {months.map((m, i) => <th key={i} style={{ textAlign: "right" }}>{m} {years[i].toString().slice(2)}</th>)}
            <th style={{ textAlign: "right" }} title="Compared to the prior month">vs last month</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((r, ri) => {
            const last = r.values[r.values.length - 1];
            const prev = r.values[r.values.length - 2];
            const delta = r.pct ? (last - prev) : deltaPct(last, prev);
            return (
              <tr key={ri} className={r.bold ? "bold" : ""}>
                <td style={{ paddingLeft: r.indent ? 24 : 14, color: r.indent ? "var(--text-2)" : "var(--text)" }}>{r.label.trim()}</td>
                {r.values.map((v, i) => (
                  <td key={i} style={{
                    fontFamily: "ui-monospace, 'Geist Mono', monospace",
                    color: r.accent ? "var(--accent)" : r.bold ? "var(--text)" : "var(--text-2)",
                    fontVariantNumeric: "tabular-nums",
                  }}>
                    {r.pct ? v.toFixed(1) + "%" : (r.neg ? "(" : "") + fmtUSD(v, { compact: true }).replace("$", "$") + (r.neg ? ")" : "")}
                  </td>
                ))}
                <td style={{ fontFamily: "ui-monospace, monospace", color: (r.bold && delta >= 0) ? "var(--positive)" : (r.bold && delta < 0) ? "var(--danger)" : "var(--text-2)" }}>
                  {r.pct ? (delta >= 0 ? "+" : "") + delta.toFixed(1) + " pp" : fmtPct(delta)}
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────────────
// CASH FLOW
// ────────────────────────────────────────────────────────────────────────
function CashFlowPage({ data, period: globalPeriod, setPeriod: setGlobalPeriod }) {
  const { cash, aging, pl } = data;
  const { curIdx, cmpIdx, sumAt, cmpMult, compareDeltaSub, PeriodComparerEl } = window.usePeriod(globalPeriod, setGlobalPeriod);
  const [horizon, setHorizon] = useStateF("90d");
  const horizonDays = { "30d": 30, "60d": 60, "90d": 90, "180d": 90 }[horizon] || 90; // synthesize 180 from 90

  const opex = sumAt(pl.opex, curIdx);
  const rev  = sumAt(pl.revenue, curIdx);
  const opexPrev = sumAt(pl.opex, cmpIdx) * cmpMult;

  return (
    <div className="pc-page">
      {PeriodComparerEl}
      <div className="pc-kpi-grid pc-kpi-grid-4">
        <KPICard label="Cash on hand"    value={fmtUSD(cash.startCash, { compact: true })} delta={2.4} sub={compareDeltaSub || "vs. start of month"} accent="var(--accent)" spark={[1.7e6,1.74e6,1.78e6,1.81e6,1.79e6,1.82e6]} />
        <KPICard label="Projected runway" value={cash.runwayDays > 365 ? "12+ months" : cash.runwayDays + "d"} hint="Based on trailing 90-day burn" accent="var(--positive)" />
        <KPICard label="Net burn / day"   value={fmtUSD(Math.abs(cash.burnPerDay))} hint={cash.burnPerDay > 0 ? "Cash declining" : "Cash building"} accent={cash.burnPerDay > 0 ? "var(--warning)" : "var(--positive)"} />
        <KPICard label="Opex (period)"    value={fmtUSD(opex, { compact: true })} delta={opexPrev > 0 ? deltaPct(opex, opexPrev) : null} sub={compareDeltaSub} accent="var(--warning)" spark={pl.opex} />
      </div>

      <ThirteenWeekCash data={data} />

      <Card title="13-week cash projection" subtitle="Direct method · daily granularity"
            action={
              <div style={{ display: "flex", gap: 8 }}>
                <SegSmall opts={["30d", "60d", "90d", "180d"]} value={horizon} onChange={setHorizon} />
                <button className="pc-btn-mini ghost" onClick={() => alert("Custom scenario builder — coming soon")}>Add scenario</button>
              </div>
            }>
        <AreaChart
          height={280}
          labels={Array.from({length: horizonDays}, (_, k) => k % 10 === 0 ? "+" + k + "d" : "")}
          series={[
            { name: "Base", values: cash.proj.slice(0, horizonDays), color: "var(--accent)" },
            { name: "Downside (AR delay)", values: cash.proj.slice(0, horizonDays).map((v, idx) => v - idx * 850), color: "var(--danger)", fill: false, dashed: true },
            { name: "Upside (collections push)", values: cash.proj.slice(0, horizonDays).map((v, idx) => v + idx * 620), color: "var(--positive)", fill: false, dashed: true },
          ]}
        />
        <AIInsight>
          Without action, baseline cash drifts <b>$108K</b> down over 90 days. Two levers swing the outcome by <b>$160K</b>: collecting Atlas Logistics ($48K) and renegotiating two enterprise software auto-renewals ($112K annual).
        </AIInsight>
      </Card>

      <div className="pc-grid-2">
        <Card title="Cash inflows · next 30 days" subtitle="Receivables expected">
          <table className="pc-table compact">
            <thead><tr><th>Source</th><th style={{textAlign:"right"}}>Amount</th><th>Confidence</th></tr></thead>
            <tbody>
              {[
                { src: "Halcyon Group — INV-24130", amt: 84200, conf: 98 },
                { src: "Ironwood Partners — INV-24128", amt: 62500, conf: 96 },
                { src: "Northwind Holdings — INV-24134", amt: 121400, conf: 92 },
                { src: "Atlas Logistics — INV-24091 (overdue)", amt: 48200, conf: 64 },
                { src: "Brightside Co. — INV-24142", amt: 18400, conf: 88 },
                { src: "Subscription auto-renewals", amt: 38700, conf: 99 },
              ].map((r, i) => (
                <tr key={i}>
                  <td style={{ paddingLeft: 14 }}>{r.src}</td>
                  <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right" }}>{fmtUSD(r.amt)}</td>
                  <td><ConfBar v={r.conf} /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>

        <Card title="Cash outflows · next 30 days" subtitle="Payables + recurring">
          <table className="pc-table compact">
            <thead><tr><th>Item</th><th style={{textAlign:"right"}}>Amount</th><th>Due</th></tr></thead>
            <tbody>
              {[
                { src: "Payroll (2 cycles)", amt: 184000, due: "Jun 1, 15" },
                { src: "Tessera Materials — BILL-9921", amt: 48400, due: "Jun 8" },
                { src: "Rent (Q2 prepayment)", amt: 38500, due: "Jun 1" },
                { src: "Kanto Industrial — BILL-9912", amt: 28200, due: "Jun 12" },
                { src: "Cloud + software", amt: 18900, due: "Recurring" },
                { src: "Tax estimate (Q2)", amt: 42000, due: "Jun 15" },
              ].map((r, i) => (
                <tr key={i}>
                  <td style={{ paddingLeft: 14 }}>{r.src}</td>
                  <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right" }}>{fmtUSD(r.amt)}</td>
                  <td style={{ fontSize: 11, color: "var(--text-3)" }}>{r.due}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>
      </div>

      <Card title="Working capital cycle" subtitle="Cash conversion at a glance">
        <div className="pc-wcc">
          <WccBox label="DSO" value="42d" delta="+4d" deltaColor="var(--warning)" hint="Days sales outstanding" />
          <WccArrow />
          <WccBox label="DIO" value="68d" delta="−3d" deltaColor="var(--positive)" hint="Days inventory" />
          <WccArrow />
          <WccBox label="DPO" value="38d" delta="+2d" deltaColor="var(--positive)" hint="Days payable" />
          <WccArrow op="=" />
          <WccBox label="CCC" value="72d" delta="−1d" deltaColor="var(--positive)" hint="Cash conversion cycle" big />
        </div>
      </Card>
    </div>
  );
}

function ConfBar({ v }) {
  const c = v >= 90 ? "var(--positive)" : v >= 75 ? "var(--warning)" : "var(--danger)";
  return (
    <div style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
      <div style={{ width: 60, height: 4, background: "var(--border-strong)", borderRadius: 1 }}>
        <div style={{ width: v + "%", height: "100%", background: c, borderRadius: 1 }} />
      </div>
      <span style={{ fontSize: 11, fontFamily: "ui-monospace, monospace", color: c }}>{v}%</span>
    </div>
  );
}

function WccBox({ label, value, delta, deltaColor, hint, big }) {
  return (
    <div className={"pc-wcc-box " + (big ? "big" : "")}>
      <div style={{ fontSize: 10.5, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.5 }}>{label}</div>
      <div style={{ fontSize: big ? 28 : 22, fontWeight: 600, fontFamily: "ui-monospace, monospace", marginTop: 4 }}>{value}</div>
      <div style={{ fontSize: 11, color: deltaColor, marginTop: 2 }}>{delta} vs. last month</div>
      <div style={{ fontSize: 10.5, color: "var(--text-3)", marginTop: 6 }}>{hint}</div>
    </div>
  );
}

function WccArrow({ op = "+" }) {
  return <div className="pc-wcc-arrow">{op === "=" ? "=" : "−"}</div>;
}

// ────────────────────────────────────────────────────────────────────────
// AR / AP
// ────────────────────────────────────────────────────────────────────────
function ARAPPage({ data, onDrill, period: globalPeriod, setPeriod: setGlobalPeriod }) {
  const { aging } = data;
  const { PeriodComparerEl, compareDeltaSub } = window.usePeriod(globalPeriod, setGlobalPeriod);
  const arTotal = aging.ar.buckets.reduce((s, b) => s + b.value, 0);
  const apTotal = aging.ap.buckets.reduce((s, b) => s + b.value, 0);
  const overdue = aging.ar.buckets.slice(1).reduce((s, b) => s + b.value, 0);

  return (
    <div className="pc-page">
      {PeriodComparerEl}
      <div className="pc-kpi-grid pc-kpi-grid-4">
        <KPICard label="Total AR"        value={fmtUSD(arTotal, { compact: true })} sub={aging.ar.buckets.reduce((s,b)=>s+b.count,0) + " invoices"} accent="var(--accent)" />
        <KPICard label="Overdue AR"      value={fmtUSD(overdue, { compact: true })} sub={`${(overdue/arTotal*100).toFixed(0)}% of total`} delta={12.4} accent="var(--warning)" />
        <KPICard label="Total AP"        value={fmtUSD(apTotal, { compact: true })} sub={aging.ap.buckets.reduce((s,b)=>s+b.count,0) + " bills"} accent="var(--accent-2)" />
        <KPICard label="Net working AR-AP" value={fmtUSD(arTotal - apTotal, { compact: true })} sub="Receivables less payables" accent="var(--positive)" />
      </div>

      <div className="pc-grid-2">
        <Card title="AR aging" subtitle="By bucket"
              action={<button className="pc-btn-mini ghost" onClick={() => onDrill("ar")}>Drill into invoices</button>}>
          <BarChart
            data={aging.ar.buckets.map((b, i) => ({
              ...b,
              color: i === 0 ? "var(--positive)" : i === 1 ? "var(--accent)" : i === 2 ? "var(--warning)" : "var(--danger)",
            }))}
            colorFn={(d) => d.color}
            yFmt={(v) => fmtUSD(v, { compact: true })}
            height={180}
          />
          <AIInsight action={<button className="pc-btn-mini">Draft collections plan</button>}>
            Overdue concentration is unusual — <b>$62.4K of 60+ day balance</b> sits with 3 customers, vs. trailing average of 1.4 customers. Cascade Foods is a 2-σ payment anomaly worth manual escalation.
          </AIInsight>
        </Card>

        <Card title="AP aging" subtitle="By bucket">
          <BarChart
            data={aging.ap.buckets.map((b, i) => ({
              ...b,
              color: i === 0 ? "rgba(148,163,184,0.6)" : i === 1 ? "var(--accent-2)" : i === 2 ? "var(--warning)" : "var(--danger)",
            }))}
            colorFn={(d) => d.color}
            yFmt={(v) => fmtUSD(v, { compact: true })}
            height={180}
          />
          <AIInsight>
            <b>$84K of bills</b> qualify for early-payment discount (1.5–2%). Available cash supports taking all of them with no impact on runway — captures <b>$1.4K</b> margin in one cycle.
          </AIInsight>
        </Card>
      </div>

      <Card title="Top overdue receivables" subtitle="Sorted by days past due"
            action={
              <div style={{ display: "flex", gap: 8 }}>
                <button className="pc-btn-mini ghost"><Icon d={icons.filter} size={12} /> Filter</button>
                <ExportButton rows={aging.ar.topOverdue} filename="AR_overdue" />
                <button className="pc-btn-mini">Bulk-send reminders</button>
              </div>
            } padding={0}>
        <table className="pc-table">
          <thead>
            <tr>
              <th>Customer</th>
              <th>Segment</th>
              <th>Invoice</th>
              <th style={{ textAlign: "right" }}>Amount</th>
              <th>Days overdue</th>
              <th>Risk</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {aging.ar.topOverdue.map((r, i) => {
              const risk = r.days > 90 ? "high" : r.days > 60 ? "medium" : "low";
              return (
                <tr key={i} className="pc-clickable" onClick={() => onDrill("ar", r)}>
                  <td style={{ paddingLeft: 14, fontWeight: 500 }}>{r.customer}</td>
                  <td><span className="pc-chip">{r.segment}</span></td>
                  <td style={{ fontFamily: "ui-monospace, monospace", fontSize: 11.5, color: "var(--text-2)" }}>{r.invoice}</td>
                  <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", fontWeight: 500 }}>{fmtUSD(r.amount)}</td>
                  <td style={{ fontFamily: "ui-monospace, monospace", color: r.days > 60 ? "var(--danger)" : "var(--warning)" }}>{r.days}d</td>
                  <td><SevPill sev={risk} /></td>
                  <td><Icon d={icons.chevron} size={12} stroke="var(--text-3)" /></td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </Card>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────────────
// FORECAST
// ────────────────────────────────────────────────────────────────────────
function ForecastPage({ data }) {
  const { forecast, pl } = data;
  const [scenario, setScenario] = useStateF("base");
  const series = scenario === "base" ? forecast.base : scenario === "upside" ? forecast.upside : forecast.downside;
  const ttmRev = pl.revenue.reduce((s, v) => s + v, 0);
  const fwd12 = series.reduce((s, v) => s + v, 0);

  return (
    <div className="pc-page">
      <div className="pc-kpi-grid pc-kpi-grid-4">
        <KPICard label="TTM revenue"      value={fmtUSD(ttmRev, { compact: true })} accent="var(--accent)" />
        <KPICard label="Forward 12mo · base"     value={fmtUSD(forecast.base.reduce((s,v)=>s+v,0), { compact: true })} delta={deltaPct(forecast.base.reduce((s,v)=>s+v,0), ttmRev)} sub="vs. TTM" accent="var(--accent)" />
        <KPICard label="Forward 12mo · upside"   value={fmtUSD(forecast.upside.reduce((s,v)=>s+v,0), { compact: true })} delta={deltaPct(forecast.upside.reduce((s,v)=>s+v,0), ttmRev)} sub="vs. TTM" accent="var(--positive)" />
        <KPICard label="Forward 12mo · downside" value={fmtUSD(forecast.downside.reduce((s,v)=>s+v,0), { compact: true })} delta={deltaPct(forecast.downside.reduce((s,v)=>s+v,0), ttmRev)} sub="vs. TTM" accent="var(--danger)" />
      </div>

      <Card title="Revenue forecast" subtitle="Trailing 12mo + forward 12mo · with scenarios"
            action={
              <div className="pc-seg-sm">
                {["downside","base","upside"].map(s =>
                  <button key={s} className={scenario === s ? "active" : ""} onClick={() => setScenario(s)}>{s[0].toUpperCase() + s.slice(1)}</button>
                )}
              </div>
            }>
        <AreaChart
          height={300}
          labels={[...pl.labels, ...forecast.labels]}
          series={[
            { name: "Actual", values: [...pl.revenue, ...Array(12).fill(null)].slice(0, 24).map(v => v === null ? pl.revenue[pl.revenue.length-1] : v).map((v, i) => i < 12 ? v : null).filter(v => v !== null), color: "var(--text-3)", fill: false },
            { name: "Downside",  values: [...pl.revenue, ...forecast.downside], color: "var(--danger)", fill: scenario === "downside", dashed: scenario !== "downside" },
            { name: "Base",      values: [...pl.revenue, ...forecast.base],     color: "var(--accent)", fill: scenario === "base", dashed: scenario !== "base" },
            { name: "Upside",    values: [...pl.revenue, ...forecast.upside],   color: "var(--positive)", fill: scenario === "upside", dashed: scenario !== "upside" },
          ]}
        />
        <AIInsight>
          Forecast learns from your 24 months of seasonality + booked pipeline + AR collections behavior. Base case assumes <b>1.5% MoM</b> revenue growth with stable margin. To unlock upside, the model points to <b>2 leverage points</b>: re-activating the South region pipeline ({"<"}1.2x coverage) and converting the 7 stalled deals tagged "Q2 close".
        </AIInsight>
      </Card>

      <div className="pc-grid-2">
        <Card title="Driver assumptions" subtitle="Edit any field to see impact live">
          <table className="pc-table compact">
            <thead>
              <tr>
                <th>Driver</th>
                <th style={{ textAlign: "right" }}>Downside</th>
                <th style={{ textAlign: "right" }}>Base</th>
                <th style={{ textAlign: "right" }}>Upside</th>
              </tr>
            </thead>
            <tbody>
              {forecast.assumptions.map((a, i) => (
                <tr key={i}>
                  <td style={{ paddingLeft: 14 }}>{a.name}</td>
                  <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", color: "var(--danger)" }}>{typeof a.downside === "number" && a.downside > 1000 ? fmtUSD(a.downside) : a.downside}</td>
                  <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right" }}>{typeof a.base === "number" && a.base > 1000 ? fmtUSD(a.base) : a.base}</td>
                  <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", color: "var(--positive)" }}>{typeof a.upside === "number" && a.upside > 1000 ? fmtUSD(a.upside) : a.upside}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>

        <Card title="Sensitivity analysis" subtitle="What moves the most">
          <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
            {[
              { d: "Churn %",            impact: "−$340K", pct: 88, dir: "neg" },
              { d: "New customer adds",  impact: "+$280K", pct: 72, dir: "pos" },
              { d: "Gross margin %",     impact: "±$240K", pct: 62, dir: "neutral" },
              { d: "Avg deal size",      impact: "+$180K", pct: 46, dir: "pos" },
              { d: "Headcount growth",   impact: "−$110K", pct: 28, dir: "neg" },
            ].map((s, i) => (
              <div key={i}>
                <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12, marginBottom: 4 }}>
                  <span>{s.d}</span>
                  <span style={{ fontFamily: "ui-monospace, monospace", color: s.dir === "pos" ? "var(--positive)" : s.dir === "neg" ? "var(--danger)" : "var(--text-2)" }}>{s.impact}</span>
                </div>
                <div style={{ height: 4, background: "var(--grid)", borderRadius: 1 }}>
                  <div style={{ width: s.pct + "%", height: "100%", background: s.dir === "pos" ? "var(--positive)" : s.dir === "neg" ? "var(--danger)" : "var(--accent-2)", borderRadius: 1 }} />
                </div>
              </div>
            ))}
          </div>
        </Card>
      </div>

      <Card title="Forecast accuracy" subtitle="How well past forecasts predicted what actually happened · trust calibration"
            action={<ExportButton rows={[{Line:"Revenue",MAPE:"4.2%",Bias:"-1.1%"},{Line:"COGS",MAPE:"6.8%",Bias:"+2.4%"},{Line:"Opex",MAPE:"3.4%",Bias:"-0.6%"},{Line:"EBITDA",MAPE:"11.2%",Bias:"-4.2%"}]} filename="Forecast_accuracy" />} padding={0}>
        <table className="pc-table">
          <thead><tr><th>Line</th><th style={{textAlign:"right"}}>Forecast (6mo ago)</th><th style={{textAlign:"right"}}>Actual</th><th style={{textAlign:"right"}}>Error $</th><th style={{textAlign:"right"}}>Error %</th><th>MAPE (12mo)</th><th style={{textAlign:"right"}}>Bias</th><th>Trust</th></tr></thead>
          <tbody>
            {[
              { line: "Revenue", fcast: 1428000, actual: 1480000, mape: 4.2, bias: -1.1 },
              { line: "COGS",    fcast: 728000,  actual: 752000,  mape: 6.8, bias: 2.4 },
              { line: "Gross profit", fcast: 700000, actual: 728000, mape: 5.2, bias: -1.8 },
              { line: "Opex",    fcast: 358000,  actual: 362000,  mape: 3.4, bias: -0.6 },
              { line: "EBITDA",  fcast: 342000,  actual: 366000,  mape: 11.2, bias: -4.2 },
            ].map((r, i) => {
              const err = r.actual - r.fcast;
              const errPct = (err / r.fcast) * 100;
              return (
                <tr key={i}>
                  <td style={{ paddingLeft: 14, fontWeight: 500 }}>{r.line}</td>
                  <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", color: "var(--text-3)" }}>{fmtUSD(r.fcast, { compact: true })}</td>
                  <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", fontWeight: 500 }}>{fmtUSD(r.actual, { compact: true })}</td>
                  <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", color: err > 0 ? "var(--positive)" : "var(--danger)" }}>{err >= 0 ? "+" : "−"}{fmtUSD(Math.abs(err), { compact: true })}</td>
                  <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", color: errPct > 0 ? "var(--positive)" : "var(--danger)" }}>{errPct >= 0 ? "+" : ""}{errPct.toFixed(1)}%</td>
                  <td><Bullet value={r.mape} target={5} max={15} accent={r.mape < 5 ? "var(--positive)" : r.mape < 10 ? "var(--warning)" : "var(--danger)"} /></td>
                  <td style={{ fontFamily: "ui-monospace, monospace", textAlign: "right", color: Math.abs(r.bias) < 2 ? "var(--positive)" : "var(--warning)" }}>{r.bias >= 0 ? "+" : ""}{r.bias.toFixed(1)}%</td>
                  <td><span className="pc-statpill" style={{ background: r.mape < 5 ? "rgba(110,231,183,0.10)" : r.mape < 10 ? "rgba(251,191,36,0.10)" : "rgba(248,113,113,0.10)", color: r.mape < 5 ? "var(--positive)" : r.mape < 10 ? "var(--warning)" : "var(--danger)" }}>{r.mape < 5 ? "High" : r.mape < 10 ? "Medium" : "Calibrating"}</span></td>
                </tr>
              );
            })}
          </tbody>
        </table>
        <div style={{ padding: "14px 18px", borderTop: "1px solid var(--border)" }}>
          <AIInsight>
            Forecast quality is <b>high on Revenue and Opex</b> (MAPE under 5%) — trust those numbers. <b>EBITDA forecasts run pessimistic</b> (−4.2% bias) primarily because GM forecasts haven't reflected the V-201 cost step. <b>The model is calibrating</b> — next month's forecast should self-correct.
          </AIInsight>
        </div>
      </Card>
    </div>
  );
}

Object.assign(window, { OverviewPage, CashFlowPage, ARAPPage, ForecastPage, Card, AIInsight, SegSmall, PLTable, ConfBar });
