// §3.10 Volume Tracker — Upload, MVC Commitment, Analytics

function VolumeTracker({ user, perms }) {
  const [tab, setTab] = useState("overview");
  const [showUpload, setShowUpload] = useState(false);

  const tabs = [
    { id: "overview", label: "Overview" },
    { id: "commitment", label: "MVC Commitment", count: Object.keys(MVC).length },
    { id: "rebatepace", label: "Rebate Pace" },
    { id: "data", label: "Volume Records" },
  ];

  return (
    <div>
      <PageHeader
        title="Volume Tracker"
        sub="Actual throughput per terminal · feeds rebate accrual + TCO + MVC monitoring"
        right={
          <>
            <button className="btn"><Icon name="download" size={14} /> Template</button>
            {(perms.edit || perms.admin || user.role === "procurement") && (
              <button className="btn primary" onClick={() => setShowUpload(true)}>
                <Icon name="upload" size={14} />
                Upload monthly volume
              </button>
            )}
          </>
        }
      />
      <VolumeKPIs />
      <Tabs tabs={tabs} current={tab} onChange={setTab} />
      {tab === "overview" && <VolumeOverview />}
      {tab === "commitment" && <CommitmentTracker />}
      {tab === "rebatepace" && <RebatePaceView />}
      {tab === "data" && <VolumeRecords />}

      {showUpload && <VolumeUploadWizard onClose={() => setShowUpload(false)} />}
    </div>
  );
}

function VolumeKPIs() {
  const ytdAPA = Object.values(YTD_VOLUME).reduce((a, b) => a + b, 0);
  const monthlyAvg = ytdAPA / 5;
  const atRiskMVC = Object.entries(MVC).filter(([code, m]) => {
    const ytd = YTD_VOLUME[code];
    const pace = (ytd / 5) * 12;
    return pace < m.annual * 0.95;
  }).length;
  return (
    <div className="grid-4" style={{ marginBottom: 18 }}>
      <KPI label="APA YTD Volume" value={fmt.num(ytdAPA / 1000, 0) + "k"} sub="TEU · Jan–May 2025" delta="↑ 8.2% YoY" deltaDir="up" />
      <KPI label="Monthly Avg" value={fmt.num(monthlyAvg / 1000, 0) + "k"} sub="TEU · trailing 5 months" />
      <KPI label="MVC Terminals" value={Object.keys(MVC).length} sub={`${atRiskMVC} at-risk`} deltaDir={atRiskMVC > 0 ? "down" : "up"} />
      <KPI label="Last Upload" value="May 8" sub="Daniel Park · 7 terminals" />
    </div>
  );
}

// ============== OVERVIEW ==============
function VolumeOverview() {
  // Top 8 terminals by YTD volume
  const top = Object.entries(YTD_VOLUME)
    .map(([code, ytd]) => ({ code, ytd, name: TERMINAL_BY_CODE[code]?.name, region: TERMINAL_BY_CODE[code]?.region }))
    .sort((a, b) => b.ytd - a.ytd).slice(0, 10);
  const maxYtd = top[0].ytd;

  return (
    <div>
      {/* Monthly trend by region */}
      <Card title="Monthly Volume Trend" sub="Rolling 12-month · TEU · stacked by region"
        right={
          <div className="row gap-8">
            <select className="select" style={{ width: 140, height: 28, fontSize: 12 }}><option>All terminals</option></select>
            <select className="select" style={{ width: 120, height: 28, fontSize: 12 }}><option>By region</option><option>By equipment</option><option>By cargo</option></select>
          </div>
        }
        style={{ marginBottom: 16 }}
      >
        <div style={{ padding: 18 }}>
          <MonthlyTrendChart />
        </div>
      </Card>

      <div style={{ display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 16 }}>
        <Card title="Top 10 terminals · YTD" sub="Volume share + YoY delta">
          <div style={{ padding: 12 }}>
            {top.map((t, i) => (
              <div key={t.code} style={{ display: "grid", gridTemplateColumns: "16px 200px 1fr 80px 60px", gap: 10, alignItems: "center", padding: "8px 0", borderTop: i > 0 ? "1px solid var(--line)" : 0, fontSize: 12 }}>
                <div className="mono tiny muted" style={{ textAlign: "right" }}>#{i + 1}</div>
                <div>
                  <div className="bold tiny">{t.name}</div>
                  <div className="tiny muted">{t.region}</div>
                </div>
                <div style={{ height: 12, background: "var(--paper-2)", borderRadius: 2, overflow: "hidden" }}>
                  <div style={{ width: `${(t.ytd / maxYtd) * 100}%`, height: "100%", background: "var(--teal)" }} />
                </div>
                <div className="num mono tiny">{fmt.num(t.ytd / 1000, 1)}k</div>
                <div className="num mono tiny" style={{ color: i % 3 === 0 ? "var(--red)" : "var(--green)" }}>{i % 3 === 0 ? "↓" : "↑"} {(2 + i * 0.7).toFixed(1)}%</div>
              </div>
            ))}
          </div>
        </Card>

        <Card title="Seasonal Heatmap" sub="Month × terminal · index vs 12-mo avg">
          <SeasonalHeatmap />
        </Card>
      </div>
    </div>
  );
}

function MonthlyTrendChart() {
  // Aggregate volume by month & region
  const months = VOLUME.months;
  const regionTotals = REGIONS.map(reg => ({
    region: reg,
    monthly: months.map(m => VOLUME.rows.filter(v => v.region === reg && v.period === m).reduce((s, v) => s + v.teu, 0))
  }));
  const totalByMonth = months.map((m, i) => regionTotals.reduce((s, r) => s + r.monthly[i], 0));
  const maxTotal = Math.max(...totalByMonth);

  const regionColors = {
    "North Asia": "#0e7f95",
    "Southeast Asia": "#14a3bd",
    "South Asia Sub-Continent": "#8a4d2e",
    "Oceania": "#1f6f5c",
  };

  const W = 720, H = 200;
  return (
    <div>
      <svg width="100%" height={H + 30} viewBox={`0 0 ${W} ${H + 30}`}>
        {/* gridlines */}
        {[0, 0.25, 0.5, 0.75, 1].map(p => (
          <line key={p} x1="40" y1={H - p * H} x2={W} y2={H - p * H} stroke="#e7ebef" strokeWidth="1" />
        ))}
        {/* y axis */}
        {[0, 0.25, 0.5, 0.75, 1].map(p => (
          <text key={p} x="34" y={H - p * H + 4} textAnchor="end" fontSize="9" fill="#5a6a7c" fontFamily="IBM Plex Mono">{fmt.num((maxTotal * p) / 1000, 0)}k</text>
        ))}
        {/* stacked bars */}
        {months.map((m, mi) => {
          const x = 40 + (mi * (W - 50) / months.length);
          const bw = (W - 50) / months.length - 4;
          let yOff = 0;
          return (
            <g key={m}>
              {regionTotals.map((r, ri) => {
                const h = (r.monthly[mi] / maxTotal) * H;
                const y = H - h - yOff;
                yOff += h;
                return <rect key={ri} x={x} y={y} width={bw} height={h} fill={regionColors[r.region]} opacity={mi === months.length - 1 ? 1 : 0.85} />;
              })}
              <text x={x + bw / 2} y={H + 14} textAnchor="middle" fontSize="9" fill="#5a6a7c" fontFamily="IBM Plex Mono">
                {m.slice(5)}
              </text>
              {mi === 0 && <text x={x + bw / 2} y={H + 24} textAnchor="middle" fontSize="9" fill="#5a6a7c" fontFamily="IBM Plex Mono">{m.slice(0, 4)}</text>}
              {mi === 11 && <text x={x + bw / 2} y={H + 24} textAnchor="middle" fontSize="9" fill="#5a6a7c" fontFamily="IBM Plex Mono">{m.slice(0, 4)}</text>}
            </g>
          );
        })}
      </svg>
      <div className="row gap-12" style={{ marginTop: 6, justifyContent: "center" }}>
        {Object.entries(regionColors).map(([r, c]) => (
          <div key={r} className="row gap-4 tiny">
            <span style={{ width: 12, height: 8, background: c, borderRadius: 2 }} />
            {r}
          </div>
        ))}
      </div>
    </div>
  );
}

function SeasonalHeatmap() {
  const terminals = ["CNSHA", "CNNGB", "CNTAO", "SGSIN", "MYPKG", "INNSA", "AUSYD"];
  const months = VOLUME.months;
  // Compute index (vs each terminal's 12-mo avg)
  return (
    <div style={{ padding: 12 }}>
      <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 10 }}>
        <thead>
          <tr>
            <th style={{ textAlign: "left", padding: 2, fontWeight: 500, color: "var(--ink-mute)" }}>Terminal</th>
            {months.map(m => <th key={m} style={{ padding: 2, fontFamily: "IBM Plex Mono", fontWeight: 500, color: "var(--ink-mute)" }}>{m.slice(5)}</th>)}
          </tr>
        </thead>
        <tbody>
          {terminals.map(tc => {
            const tRows = VOLUME.rows.filter(v => v.terminal === tc);
            const avg = tRows.reduce((s, r) => s + r.teu, 0) / tRows.length;
            return (
              <tr key={tc}>
                <td className="tiny mono" style={{ padding: "3px 4px", color: "var(--ink)" }}>{tc}</td>
                {months.map(m => {
                  const row = tRows.find(r => r.period === m);
                  const idx = row ? row.teu / avg : 1;
                  // Color: <1 cool, >1 warm
                  let bg;
                  if (idx < 0.9) bg = `oklch(70% 0.05 230 / ${0.4 + (0.9 - idx) * 4})`;
                  else if (idx > 1.05) bg = `oklch(70% 0.13 35 / ${0.3 + (idx - 1) * 3})`;
                  else bg = "var(--paper-2)";
                  return (
                    <td key={m} style={{ padding: 1 }}>
                      <div style={{ background: bg, height: 18, borderRadius: 2, display: "grid", placeItems: "center", color: "var(--ink)", fontSize: 9, fontFamily: "IBM Plex Mono" }}>
                        {idx > 0.85 && idx < 1.15 ? "" : Math.round(idx * 100)}
                      </div>
                    </td>
                  );
                })}
              </tr>
            );
          })}
        </tbody>
      </table>
      <div className="row gap-12 tiny muted" style={{ marginTop: 8, justifyContent: "center" }}>
        <span>Index (100 = 12-mo avg)</span>
        <div className="row gap-2">
          <div style={{ width: 16, height: 8, background: "oklch(70% 0.05 230 / 0.7)" }} />
          <div style={{ width: 16, height: 8, background: "oklch(70% 0.05 230 / 0.4)" }} />
          <div style={{ width: 16, height: 8, background: "var(--paper-2)" }} />
          <div style={{ width: 16, height: 8, background: "oklch(70% 0.13 35 / 0.5)" }} />
          <div style={{ width: 16, height: 8, background: "oklch(70% 0.13 35 / 0.8)" }} />
        </div>
        <span>low ← → high</span>
      </div>
    </div>
  );
}

// ============== MVC COMMITMENT TRACKER ==============
function CommitmentTracker() {
  const rows = Object.entries(MVC).map(([code, m]) => {
    const ytd = YTD_VOLUME[code] || 0;
    const pace = (ytd / 5) * 12;
    const gap = pace - m.annual;
    const risk = pace < m.annual * 0.95 ? (pace < m.annual * 0.85 ? "Below Pace" : "At Risk") : "On Track";
    const shortfall = gap < 0 ? Math.abs(gap) * m.penaltyRate : 0;
    return { code, name: TERMINAL_BY_CODE[code]?.name, region: TERMINAL_BY_CODE[code]?.region, mvc: m.annual, ytd, pace, gap, risk, shortfall, focal: m.focal };
  });

  const atRisk = rows.filter(r => r.risk !== "On Track");

  return (
    <div>
      {atRisk.length > 0 && (
        <div style={{ marginBottom: 14, padding: 12, background: "#fdf6e7", border: "1px solid #f0d8a8", borderRadius: 6, display: "flex", gap: 10, alignItems: "flex-start" }}>
          <Icon name="bell" size={16} stroke="var(--amber)" />
          <div className="tiny">
            <b style={{ color: "var(--amber)" }}>{atRisk.length} terminal(s) below 95% of commitment pace.</b> Alert sent to FBP + Procurement on
            <span className="mono"> 2025-05-12 via Power Automate</span>. Estimated shortfall exposure: <b>{fmt.usd(atRisk.reduce((s, r) => s + r.shortfall, 0))}</b> if pace continues.
          </div>
        </div>
      )}

      <Card title="Minimum Volume Commitment · Actual vs Target" sub={`${rows.length} terminals with MVC clauses · annualised pace from YTD`}>
        <div className="table-wrap">
          <table className="table">
            <thead>
              <tr>
                <th>Terminal</th>
                <th className="num">Contract MVC</th>
                <th className="num">YTD Actual</th>
                <th>Pace vs MVC</th>
                <th className="num">YTD Pace (Annualised)</th>
                <th className="num">Gap to MVC</th>
                <th>Risk</th>
                <th className="num">Shortfall Cost</th>
                <th>Focal</th>
              </tr>
            </thead>
            <tbody>
              {rows.map(r => (
                <tr key={r.code}>
                  <td>
                    <div className="bold tiny">{r.name}</div>
                    <div className="tiny muted">{r.region}</div>
                  </td>
                  <td className="num mono">{fmt.num(r.mvc, 0)}</td>
                  <td className="num mono">{fmt.num(r.ytd, 0)}</td>
                  <td><PaceGauge value={r.pace} target={r.mvc} width={140} /></td>
                  <td className="num mono">{fmt.num(r.pace, 0)}</td>
                  <td className="num mono" style={{ color: r.gap < 0 ? "var(--red)" : "var(--green)" }}>
                    {r.gap > 0 ? "+" : ""}{fmt.num(r.gap, 0)}
                  </td>
                  <td>
                    {r.risk === "On Track" && <Pill status="Active">On Track</Pill>}
                    {r.risk === "At Risk" && <Pill status="Pending">⚠ At Risk</Pill>}
                    {r.risk === "Below Pace" && <Pill className="rejected">Below Pace</Pill>}
                  </td>
                  <td className="num mono" style={{ color: r.shortfall > 0 ? "var(--red)" : null }}>
                    {r.shortfall > 0 ? fmt.usd(r.shortfall) : "—"}
                  </td>
                  <td className="tiny">{r.focal}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </Card>
    </div>
  );
}

// ============== REBATE PACE VIEW ==============
function RebatePaceView() {
  return (
    <Card title="Rebate Pace · Volume overlaid with tier thresholds" sub="How close each terminal is to next rebate tier">
      <div style={{ padding: 18 }}>
        {REBATES.filter(r => r.currentTier >= 0 && r.tiers.length > 1).map((r, i) => {
          const ytd = YTD_VOLUME[r.terminal] || 18000;
          const lastTier = r.tiers[r.tiers.length - 1];
          // Scale the chart so YTD always fits with headroom — never clip the marker
          const lastTierBound = lastTier.max || lastTier.min * 1.5;
          const max = Math.max(lastTierBound * 1.05, ytd * 1.08);
          const ytdPct = (ytd / max) * 100;
          return (
            <div key={r.id} style={{ padding: "14px 0 18px", borderTop: i > 0 ? "1px solid var(--line)" : 0 }}>
              <div className="row gap-8" style={{ marginBottom: 8 }}>
                <div className="bold tiny">{TERMINAL_BY_CODE[r.terminal]?.name}</div>
                <div className="tiny muted mono">{r.id}</div>
                <div className="grow" />
                <div className="tiny muted">YTD: <b className="mono" style={{ color: "var(--ink)" }}>{fmt.num(ytd, 0)} TEU</b></div>
              </div>

              {/* Wrapper allows marker label to overflow above the bar */}
              <div style={{ position: "relative", paddingTop: 18 }}>
                {/* Tier band bar (clipped) */}
                <div style={{ position: "relative", height: 22, background: "var(--paper-2)", borderRadius: 3, overflow: "hidden" }}>
                  {r.tiers.map((t, ti) => {
                    const start = (t.min / max) * 100;
                    const end = ((t.max || max) / max) * 100;
                    const colors = ["#e7f3f6", "#cae8ee", "#9ad4de", "#5fbac9"];
                    return (
                      <div key={ti} style={{ position: "absolute", left: `${start}%`, width: `${end - start}%`, top: 0, bottom: 0, background: colors[Math.min(ti, 3)], borderRight: ti < r.tiers.length - 1 ? "1px solid #fff" : null }}>
                        <span className="mono" style={{ position: "absolute", top: 4, left: 4, color: "var(--ink)", fontSize: 9, fontWeight: 600 }}>{t.rate}%</span>
                      </div>
                    );
                  })}
                </div>

                {/* YTD marker lives on the OUTER wrapper so the label can overflow */}
                <div style={{ position: "absolute", left: `${ytdPct}%`, top: 14, height: 32, width: 2, background: "var(--ink)" }} />
                <div style={{
                  position: "absolute",
                  left: `${ytdPct}%`,
                  top: 0,
                  transform: ytdPct > 92 ? "translateX(-100%)" : ytdPct < 8 ? "translateX(0)" : "translateX(-50%)",
                  background: "var(--ink)", color: "#fff",
                  padding: "2px 6px", borderRadius: 3, fontSize: 9, fontFamily: "IBM Plex Mono",
                  whiteSpace: "nowrap", lineHeight: 1.2, fontWeight: 600,
                }}>
                  YTD · {fmt.num(ytd, 0)}
                </div>
              </div>

              <div className="row" style={{ marginTop: 6, justifyContent: "space-between" }}>
                {r.tiers.map((t, ti) => (
                  <div key={ti} className="tiny mono muted" style={{ flex: 1, textAlign: ti === 0 ? "left" : ti === r.tiers.length - 1 ? "right" : "center" }}>
                    {fmt.num(t.min, 0)}
                  </div>
                ))}
              </div>
            </div>
          );
        })}
      </div>
    </Card>
  );
}

// ============== VOLUME RECORDS ==============
function VolumeRecords() {
  const [page, setPage] = useState(1);
  const pageSize = 14;
  const sample = VOLUME.rows.filter(r => r.period >= "2024-12").slice((page - 1) * pageSize, page * pageSize);
  const total = VOLUME.rows.length;

  return (
    <div>
      <div className="filterbar">
        <FilterChip keyLabel="Terminal" value="" />
        <FilterChip keyLabel="Period" value="May 2025" set />
        <FilterChip keyLabel="Equipment" value="" />
        <FilterChip keyLabel="Cargo" value="" />
        <div className="grow" />
        <button className="btn"><Icon name="download" size={14} /> Export</button>
      </div>
      <Card>
        <div className="table-wrap">
          <table className="table">
            <thead>
              <tr>
                <th>Period</th>
                <th>Terminal</th>
                <th>Equipment</th>
                <th>Cargo</th>
                <th>Move Type</th>
                <th className="num">Actual TEU</th>
                <th className="num">Actual Moves</th>
                <th>Source</th>
                <th>Uploaded</th>
              </tr>
            </thead>
            <tbody>
              {sample.map((v, i) => (
                <tr key={i}>
                  <td className="mono tiny">{v.period}</td>
                  <td>
                    <div className="bold tiny">{v.terminalName}</div>
                    <div className="tiny muted mono">{v.terminal}</div>
                  </td>
                  <td className="mono tiny">{EQUIPMENT[i % EQUIPMENT.length]}</td>
                  <td className="tiny">{CARGO_TYPES[i % CARGO_TYPES.length]}</td>
                  <td className="tiny">{MOVE_TYPES[i % MOVE_TYPES.length]}</td>
                  <td className="num mono">{fmt.num(v.teu, 0)}</td>
                  <td className="num mono">{fmt.num(v.moves, 0)}</td>
                  <td><Pill className="plain">Manual Upload</Pill></td>
                  <td className="tiny muted mono">2025-05-08 · D. Park</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
        <div className="card-head" style={{ borderTop: "1px solid var(--line)", borderBottom: 0, background: "#fafbfc" }}>
          <div className="muted tiny">Showing {(page - 1) * pageSize + 1}–{page * pageSize} of {total.toLocaleString()} records</div>
          <div className="row gap-4" style={{ marginLeft: "auto" }}>
            <button className="btn ghost" onClick={() => setPage(p => Math.max(1, p - 1))}>Previous</button>
            <button className="btn ghost" onClick={() => setPage(p => p + 1)}>Next</button>
          </div>
        </div>
      </Card>
    </div>
  );
}

// ============== UPLOAD WIZARD ==============
function VolumeUploadWizard({ onClose }) {
  const [step, setStep] = useState(0);
  const sample = [
    { terminal: "CNSHA", period: "2025-05", eq: "40HC", cargo: "Dry", move: "Export", teu: 5240, moves: 2620, status: "ok" },
    { terminal: "CNSHA", period: "2025-05", eq: "20GP", cargo: "Dry", move: "Import", teu: 3120, moves: 3120, status: "ok" },
    { terminal: "CNSHA", period: "2025-05", eq: "40RF", cargo: "Reefer", move: "Export", teu: 480, moves: 240, status: "ok" },
    { terminal: "CNSHA", period: "2025-05", eq: "45HC", cargo: "Dry", move: "Transship", teu: 980, moves: 490, status: "ok" },
    { terminal: "CNNGB", period: "2025-05", eq: "40HC", cargo: "Dry", move: "Export", teu: 4180, moves: 2090, status: "ok" },
    { terminal: "CNNGB", period: "2025-05", eq: "40HC", cargo: "Dry", move: "Export", teu: 4180, moves: 2090, status: "dup" },
    { terminal: "CNTAO", period: "2025-06", eq: "20GP", cargo: "Dry", move: "Import", teu: 2840, moves: 2840, status: "future" },
  ];
  return (
    <SlideOver
      open={true}
      onClose={onClose}
      wide
      title="Upload monthly volume"
      sub="CSV / Excel · validated row-by-row · triggers rebate re-accrual on commit"
      foot={
        <>
          <button className="btn ghost" onClick={onClose}>Cancel</button>
          {step > 0 && <button className="btn" onClick={() => setStep(s => s - 1)}>Back</button>}
          <div className="grow" />
          {step < 2 && <button className="btn primary" onClick={() => setStep(s => s + 1)}>Continue <Icon name="arrowRight" size={12} /></button>}
          {step === 2 && <button className="btn primary" onClick={onClose}><Icon name="check" size={14} /> Commit · trigger re-accrual</button>}
        </>
      }
    >
      <div style={{ marginBottom: 20 }}><Stepper steps={["Upload", "Validate & Preview", "Confirm"]} current={step} /></div>

      {step === 0 && (
        <div>
          <div className="dropzone">
            <Icon name="upload" size={28} stroke="var(--ink-mute)" />
            <div style={{ marginTop: 10, fontWeight: 500, color: "var(--ink)" }}>Drop volume CSV / .xlsx file here</div>
            <div className="tiny" style={{ marginTop: 4 }}>or <a style={{ color: "var(--teal)", cursor: "pointer" }}>browse</a> — max 25MB</div>
          </div>
          <div className="card" style={{ marginTop: 14, padding: 12, display: "flex", alignItems: "center", gap: 10 }}>
            <div style={{ width: 36, height: 36, borderRadius: 6, background: "var(--paper-2)", display: "grid", placeItems: "center" }}>
              <Icon name="table" size={18} stroke="var(--ink-mute)" />
            </div>
            <div style={{ flex: 1 }}>
              <div className="bold">volume_2025-05_NA.xlsx</div>
              <div className="tiny muted mono">68 KB · 184 rows · 7 terminals</div>
            </div>
            <button className="icon-btn"><Icon name="close" size={12} /></button>
          </div>
          <div className="tiny muted" style={{ marginTop: 14 }}>
            Template includes dropdown validation for Equipment Type, Cargo Type, Move Type. Upload scope restricted to your assigned Region/Area.
          </div>
        </div>
      )}

      {step === 1 && (
        <div>
          <div className="row gap-8" style={{ marginBottom: 12 }}>
            <Pill status="Active">{sample.filter(s => s.status === "ok").length} valid</Pill>
            <Pill status="Rejected">{sample.filter(s => s.status !== "ok").length} errors</Pill>
            <div className="grow" />
            <span className="tiny muted">Total file: 184 rows · 178 valid · 6 errors</span>
          </div>
          <Card>
            <div className="table-wrap">
              <table className="table">
                <thead><tr><th>Terminal</th><th>Period</th><th>Equipment</th><th>Cargo</th><th>Move</th><th className="num">TEU</th><th className="num">Moves</th><th>Result</th></tr></thead>
                <tbody>
                  {sample.map((s, i) => (
                    <tr key={i} style={s.status !== "ok" ? { background: "#fef4f4" } : null}>
                      <td className="mono tiny">{s.terminal}</td>
                      <td className="mono tiny">{s.period}</td>
                      <td className="mono tiny">{s.eq}</td>
                      <td className="tiny">{s.cargo}</td>
                      <td className="tiny">{s.move}</td>
                      <td className="num mono">{fmt.num(s.teu, 0)}</td>
                      <td className="num mono">{fmt.num(s.moves, 0)}</td>
                      <td>
                        {s.status === "ok" && <span className="tiny" style={{ color: "var(--green)" }}>✓ Valid</span>}
                        {s.status === "dup" && <span className="tiny" style={{ color: "var(--red)" }}>✕ Duplicate combination</span>}
                        {s.status === "future" && <span className="tiny" style={{ color: "var(--red)" }}>✕ Future period not allowed</span>}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </Card>
        </div>
      )}

      {step === 2 && (
        <div>
          <div className="card" style={{ padding: 20, marginBottom: 16 }}>
            <div className="serif" style={{ fontSize: 20, fontWeight: 500, marginBottom: 12 }}>Ready to commit 178 records</div>
            <table style={{ width: "100%", fontSize: 13 }}>
              <tbody>
                <DRow k="Period" v={<span className="mono">May 2025</span>} />
                <DRow k="Terminals affected" v="7" />
                <DRow k="Total TEU" v={<span className="mono bold">29,640</span>} />
                <DRow k="Total Moves" v={<span className="mono">18,260</span>} />
              </tbody>
            </table>
          </div>
          <div style={{ padding: 12, background: "var(--teal-soft)", border: "1px solid #c8e3ea", borderRadius: 6, display: "flex", gap: 10 }}>
            <Icon name="bolt" size={16} stroke="var(--teal)" />
            <div className="tiny">
              <b style={{ color: "var(--teal)" }}>On commit:</b> System will automatically recalculate accruals for 4 active rebate contracts linked to these terminals.
              Affected contracts: <span className="mono">RB-2025-001, RB-2025-002, RB-2025-003, RB-2025-005</span>. MVC pace and TCO will refresh in real-time.
            </div>
          </div>
        </div>
      )}
    </SlideOver>
  );
}

Object.assign(window, { VolumeTracker });
