// Screens 7: Line Mode + Traveler Mode + Auditor view

const { useState: uS7, useMemo: uM7 } = React;

// ─────────────────────────────── helpers ──────────────────────────────────
function HeaderStrip({ uri, right }) {
  return (
    <div style={{
      height: 40, padding: "0 14px", display: "flex", alignItems: "center", justifyContent: "space-between",
      borderBottom: "1px solid var(--line-soft)", background: "var(--bg-1)"
    }}>
      <div className="mono" style={{ fontSize: 12, color: "var(--accent)", letterSpacing: "0.02em" }}>{uri}</div>
      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>{right}</div>
    </div>
  );
}

function AgentCallout({ label, body, children }) {
  return (
    <div style={{
      background: "var(--bg-2)", border: "1px solid var(--line-soft)",
      boxShadow: "inset 3px 0 0 var(--accent)",
      padding: 12, borderRadius: 4
    }}>
      <div className="label" style={{ marginBottom: 6, color: "var(--accent)" }}>{label}</div>
      <div style={{ fontSize: 12, color: "var(--ink-2)", lineHeight: 1.5, marginBottom: 10 }}>{body}</div>
      <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>{children}</div>
    </div>
  );
}

function _dotColor(tone) {
  return tone === "ok" ? "var(--ok)" : tone === "warn" ? "var(--warn)" : tone === "err" ? "var(--err)" : "var(--ink-3)";
}

function Cell({ label, info }) {
  return (
    <div style={{
      border: "1px solid var(--line-soft)", borderRadius: 4, padding: "10px 12px",
      background: "var(--bg-1)", minHeight: 64
    }}>
      <div style={{ display: "flex", alignItems: "center", gap: 6, marginBottom: 4 }}>
        <span style={{ width: 8, height: 8, borderRadius: 8, background: _dotColor(info.tone), display: "inline-block" }} />
        <span className="label">{label}</span>
      </div>
      <div className="mono" style={{ fontSize: 12, color: "var(--ink-2)", lineHeight: 1.4 }}>{info.body}</div>
    </div>
  );
}

function Chip({ active, onClick, children }) {
  const _chipBtnStyle = {
    padding: "3px 10px", borderRadius: 3, cursor: "pointer", fontSize: 12,
    textTransform: "uppercase", letterSpacing: "0.04em",
    border: `1px solid ${active ? "color-mix(in oklch, var(--accent) 60%, var(--line))" : "var(--line)"}`,
    background: active ? "color-mix(in oklch, var(--accent) 18%, var(--bg-2))" : "var(--bg-2)",
    color: active ? "var(--accent)" : "var(--ink-3)",
  };
  return (
    <button onClick={onClick} className="mono" style={_chipBtnStyle}>{children}</button>
  );
}

// ─────────────────────────────── LINE MODE ────────────────────────────────
function ScreenLine() {
  const tenant = useActiveTenant();
  const isTritan = !!(tenant && tenant.tenant && tenant.tenant.id === "tritan");
  const tenantWos = (tenant && tenant.work_orders && tenant.work_orders.length)
    ? tenant.work_orders.map(function(w) {
        var tone = w.status === "in-progress" ? "warn" : w.status === "scheduled" ? "info" : w.status === "pilot" ? "info" : "ok";
        var label = w.status === "in-progress" ? "in progress" : w.status;
        var firstStation = (tenant.routing && tenant.routing[0]) || { name: "—" };
        return {
          id: w.id,
          part: w.sku + " · " + w.customer + " · qty " + w.qty,
          window: (w.scheduled_start || "") + " → " + (w.scheduled_end || ""),
          readiness: w.status, tone: tone, readinessLabel: label,
          cells: {
            material: { tone: "ok",   body: "kits staged at " + firstStation.name },
            tooling:  { tone: "ok",   body: "fixtures set per station spec" },
            operator: { tone: "ok",   body: "crew assigned per routing owners" },
            ncr:      { tone: "ok",   body: "none open" },
          },
        };
      })
    : null;
  const _fallbackWoId = (tenant && tenant.work_orders && tenant.work_orders[0] && tenant.work_orders[0].id) || "WO-—";
  const wos = tenantWos || [
    {
      id: _fallbackWoId, part: "HTU-220.10.02 · Composite blade · qty 80",
      window: "06:00–14:00", readiness: "flagged", tone: "err",
      readinessLabel: "flagged",
      cells: {
        material: { tone: "err", body: "SUB-A12 short 12u · ETA tomorrow 18h" },
        tooling:  { tone: "ok",  body: "JIG-114-C · TRQ-44 set" },
        operator: { tone: "warn", body: "STA-014 backup needed" },
        ncr:      { tone: "ok",  body: "none" },
      },
    },
    {
      id: "WO-44220", part: "HTU-220.10.04 · Mounting bracket · qty 24",
      window: "14:00–22:00", readiness: "ready", tone: "ok",
      readinessLabel: "ready",
      cells: {
        material: { tone: "ok", body: "all staged" },
        tooling:  { tone: "ok", body: "JIG-118-A set" },
        operator: { tone: "ok", body: "OP-211 qualified" },
        ncr:      { tone: "ok", body: "none" },
      },
    },
    {
      id: "WO-44221", part: "HTU-220.10.07 · Strut sub-assy · qty 60",
      window: "22:00–06:00", readiness: "ready", tone: "ok",
      readinessLabel: "ready",
      cells: {
        material: { tone: "ok", body: "all staged" },
        tooling:  { tone: "ok", body: "JIG-122 set" },
        operator: { tone: "ok", body: "OP-204 qualified" },
        ncr:      { tone: "ok", body: "1 minor closed" },
      },
    },
  ];
  const [selWo, setSelWo] = uS7(wos[0].id);

  const wo = wos.find(w => w.id === selWo) || wos[0];
  const otdTrend = [94, 93, 92, 92, 90, 88, 87];

  return (
    <div style={{ display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }}>
      <HeaderStrip
        uri="line://schedules/2027-W22 · Wed 2027-06-02"
        right={<>
          <span className="pill info pulse"><span className="dot"/>readiness · live</span>
          <div className="mono" style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 12, color: "var(--ink-3)" }}>
            {I("Clock", { size: 14 })}<span>shift starts in 4h 12m</span>
          </div>
        </>}
      />

      <div style={{ flex: 1, padding: 14, display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 14, minHeight: 0 }}>
        {/* ── LEFT: schedule ── */}
        <Panel title="line schedule" right={<>
          <Tag>2027-W22</Tag>
          <Btn size="sm" icon="Filter" onClick={() => window.forgeToast && window.forgeToast("filter queued — wired in v2")}>filter</Btn>
        </>}>
          <div>
            {wos.map(w => {
              const sel = w.id === selWo;
              const _woRowStyle = {
                display: "grid", gridTemplateColumns: "100px 1fr 110px 120px 40px",
                gap: 8, alignItems: "center", padding: "8px 10px",
                borderBottom: "1px solid var(--line-soft)", cursor: "pointer",
                background: sel ? "color-mix(in oklch, var(--accent) 12%, transparent)" : "transparent",
              };
              return (
                <div key={w.id} role="button" tabIndex={0} onClick={() => setSelWo(w.id)} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setSelWo(w.id); } }} style={_woRowStyle}>
                  <span className="mono" style={{ fontSize: 12, color: "var(--accent)" }}>{w.id}</span>
                  <span style={{ fontSize: 12, color: "var(--ink)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{w.part}</span>
                  <span className="mono tnum" style={{ fontSize: 12, color: "var(--ink-3)" }}>{w.window}</span>
                  <Pill tone={w.tone}>{w.readinessLabel}</Pill>
                  <span style={{ textAlign: "right", color: sel ? "var(--accent)" : "var(--ink-3)", fontFamily: "var(--font-mono)", fontSize: 14 }}>→</span>
                </div>
              );
            })}
          </div>
          <div style={{ padding: 12, borderTop: "1px solid var(--line-soft)" }}>
            <div className="label" style={{ marginBottom: 6 }}>OTD · 7 day trend</div>
            <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
              <Spark data={otdTrend} height={36} stroke="var(--info)"/>
              <div className="mono" style={{ fontSize: 12, color: "var(--ink-3)" }}>
                OTD 7d · <span style={{ color: "var(--ink-2)" }}>91% → 87%</span> <span style={{ color: "var(--info)" }}>(down 4)</span>
              </div>
            </div>
          </div>
        </Panel>

        {/* ── RIGHT: readiness ── */}
        <div style={{ display: "flex", flexDirection: "column", gap: 14, minHeight: 0 }}>
          <Panel title={"readiness · " + wo.id} right={<Pill tone={wo.tone}>{wo.readinessLabel}</Pill>}>
            <div style={{ padding: 12, display: "flex", flexDirection: "column", gap: 12 }}>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
                <Cell label="Material"  info={wo.cells.material} />
                <Cell label="Tooling"   info={wo.cells.tooling} />
                <Cell label="Operator"  info={wo.cells.operator} />
                <Cell label="NCR carry" info={wo.cells.ncr} />
              </div>

              <div style={{ border: "1px solid var(--line-soft)", borderRadius: 4, padding: "10px 12px", background: "var(--bg-1)" }}>
                <div className="label" style={{ marginBottom: 6 }}>cost rollup</div>
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "4px 16px" }}>
                  {(function() {
                    const i18n = (typeof window !== "undefined") ? window.forgeI18n : null;
                    function fmt(minor, ccy, fallback) {
                      if (i18n && i18n.formatMoneyMinor) {
                        const out = i18n.formatMoneyMinor(minor, ccy);
                        if (out) return out;
                      }
                      return fallback;
                    }
                    return isTritan ? [
                      ["Total cost", fmt("42100000", "INR", "₹4,21,000")],
                      ["Material",   fmt("29000000", "INR", "₹2,90,000")],
                      ["Labor",      fmt("9000000",  "INR", "₹90,000")],
                      ["Overhead",   fmt("4000000",  "INR", "₹40,000")],
                    ] : [
                      ["Total cost", fmt("18240000", "USD", "$182,400")],
                      ["Material",   fmt("9420000",  "USD", "$94,200")],
                      ["Labor",      fmt("6180000",  "USD", "$61,800")],
                      ["Overhead",   fmt("2640000",  "USD", "$26,400")],
                    ];
                  })().map(([k, v]) => (
                    <div key={k} className="mono" style={{ fontSize: 12, display: "flex", justifyContent: "space-between", color: "var(--ink-3)" }}>
                      <span>{k}</span>
                      <span className="tnum" style={{ color: "var(--ink-2)" }}>{v}</span>
                    </div>
                  ))}
                </div>
              </div>

              <AgentCallout
                label="Forge agent · suggestion"
                body={isTritan
                  ? "NRV bodies short by 24 units for WO-44219 stage A; expedite available from Spire Foundry at +₹220/u with 5-day ETA. Backup operator Aryan M. meets receiving QA gates."
                  : ("Material short flagged on " + _fallbackWoId + " · expedite quote on file with primary supplier · backup operator qualified for affected station.")
                }
              >
                <Btn size="sm" icon="Eye" onClick={() => window.forgeToast && window.forgeToast("Plan preview queued — wired in v2")}>Plan</Btn>
                <Btn size="sm" variant="primary" icon="Zap" disabled title="coming in v2">Strike · cut + expedite</Btn>
              </AgentCallout>
            </div>
          </Panel>
        </div>
      </div>
    </div>
  );
}

// ────────────────────────────── TRAVELER MODE ─────────────────────────────
function ScreenTraveler() {
  const tenant = useActiveTenant();
  const isTritan = !!(tenant && tenant.tenant && tenant.tenant.id === "tritan");
  const trav = (tenant && tenant.travelers && tenant.travelers.length) ? tenant.travelers[0] : null;
  const tenantRouting = (tenant && tenant.routing && tenant.routing.length) ? tenant.routing : null;
  const _fallbackWoId = (tenant && tenant.work_orders && tenant.work_orders[0] && tenant.work_orders[0].id) || "WO-—";
  const stationKey = function(s, idx) {
    return String((s && (s.id || s.station || s.station_id || s.code)) || ("sta-" + (idx + 1)));
  };

  const stations = uM7(() => {
    if (trav && tenantRouting) {
      return tenantRouting.map(function(s, idx) {
        const sid = stationKey(s, idx);
        const done = (trav.completed_stations || []).indexOf(sid) !== -1;
        const active = trav.current_station === sid;
        return { id: sid.toUpperCase(), kind: done ? "done" : active ? "active" : "pending", name: s.name || sid };
      });
    }
    const arr = [];
    for (let i = 1; i <= 22; i++) {
      const id = String(i).padStart(3, "0");
      let kind = "pending";
      if (i < 14) kind = "done";
      else if (i === 14) kind = "active";
      arr.push({ id, kind });
    }
    return arr;
  }, [trav, tenantRouting]);

  const tileStyle = (kind) => {
    if (kind === "done") return {
      border: "1px solid var(--line-strong)", background: "var(--bg-2)", color: "var(--ink-3)"
    };
    if (kind === "active") return {
      border: "1px solid var(--accent)", background: "color-mix(in oklch, var(--accent) 14%, var(--bg-1))",
      color: "var(--accent)", fontWeight: 600
    };
    return {
      border: "1px dashed var(--line)", background: "var(--bg-1)", color: "var(--ink-3)"
    };
  };

  const measurementCells = [
    ["Hole ⌀", "mm"],
    ["Position true", "mm"],
    ["Surface Ra", "μm"],
    ["Torque", "Nm"],
  ];

  const bomLines = trav
    ? [].concat(
        (trav.completed_stations || []).map(function(sid) {
          const safeSid = String(sid || "");
          const stn = (tenantRouting || []).find(function(s, idx) { return stationKey(s, idx) === safeSid; });
          return [(safeSid.toUpperCase()) + " · " + (stn ? stn.name : "") + " · " + (trav.serial || "") + " ✓", "var(--ink-3)"];
        }),
        [[((trav.current_station || "").toUpperCase()) + " · in-process · " + (trav.status === "hold" ? (trav.hold_reason || "hold") : "ok"), trav.status === "hold" ? "var(--err)" : "var(--accent)"]],
        [["pending downstream", "var(--ink-3)"]]
      )
    : [
        ["STA-001 · base plate · S/N 44219-001 · op-001 ✓", "var(--ink-3)"],
        ["STA-007 · CFRP layup · 8-ply 0/45/-45/90 ✓",      "var(--ink-3)"],
        ["STA-009 · cure cycle · 180°C / 4hr ✓",            "var(--ink-3)"],
        ["STA-013 · trim + edge prep · 27 min ✓",           "var(--ink-3)"],
        ["STA-014 · in-process · ⌀ pending",                "var(--accent)"],
        ["STA-015..022 · pending",                          "var(--ink-3)"],
      ];
  const headerUri = trav
    ? ("traveler://workorders/" + trav.wo + "/units/" + trav.serial + "/stations/" + (trav.current_station || "").toUpperCase())
    : ("traveler://workorders/" + _fallbackWoId + "/stations/STA-014");
  const stationCount = stations.length;
  const currentStationIdx = stations.findIndex(function(s) { return s.kind === "active"; });
  const currentStationLabel = currentStationIdx >= 0 ? ("station " + (currentStationIdx+1) + " of " + stationCount) : ("station " + stationCount + " of " + stationCount);
  const dimsLines = trav && trav.dimensions
    ? Object.entries(trav.dimensions).filter(function(kv) { return kv[1] != null; })
    : null;

  const cycleTrend = [21,20,19,22,18,19,20,19,18,17,19,20,18,19,21,20,19,18,19,20,19,17,18,19,20,21,19,18,19,19];

  return (
    <div style={{ display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }}>
      <HeaderStrip
        uri={headerUri}
        right={<>
          <span className="mono" style={{ fontSize: 12, color: "var(--ink-3)" }}>{currentStationLabel}</span>
          <span className={"pill " + (trav && trav.status === "hold" ? "err" : "info") + " pulse"}><span className="dot"/>{trav && trav.status === "hold" ? "hold" : "in-process"}</span>
        </>}
      />

      <div style={{ flex: 1, padding: 14, display: "flex", flexDirection: "column", gap: 14, minHeight: 0, overflow: "auto" }}>
        {/* Section 1: station timeline */}
        <Panel title={(trav ? trav.wo : _fallbackWoId) + " · station timeline"} right={<>
          <Tag>{stationCount} stations</Tag>
          <Pill tone="accent">{trav ? "at " + (trav.current_station || "").toUpperCase() : "at STA-014"}</Pill>
        </>}>
          <div style={{ padding: 12, display: "flex", flexWrap: "wrap", gap: 4 }}>
            {stations.map(s => (
              <div key={s.id} className="mono" style={{
                minWidth: 56, padding: "6px 8px", textAlign: "center", fontSize: 12,
                borderRadius: 3, ...tileStyle(s.kind)
              }}>{s.id}</div>
            ))}
          </div>
        </Panel>

        {/* Section 2: console + bom */}
        <div style={{ display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 14 }}>
          <Panel title="STA-014 · operator console" right={<Pill tone="accent">active</Pill>}>
            <div style={{ padding: 12, display: "flex", flexDirection: "column", gap: 12 }}>
              <div style={{ fontSize: 13, color: "var(--ink)", lineHeight: 1.5 }}>
                {isTritan
                  ? "Stage casing 25A · check Ø86 +0/-0.05 · stack three impellers w/ M8×40 bolts · torque 22 Nm · final HV test at QG-30."
                  : "Mounting hole · drill ⌀22.0 ± 0.2 mm · ream to ⌀22.2 H7 · torque gate at STA-022."}
              </div>
              <div className="mono" style={{ fontSize: 12, color: "var(--ink-3)" }}>
                {isTritan
                  ? "Drawing ref: DRG-M27418-PMP-rev-B · Op time est: 9 min"
                  : "Drawing ref: DRG-220.10.02-rev-C · Op time est: 22 min"}
              </div>

              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
                {measurementCells.map(([label, unit]) => {
                  const _measurementInputStyle = {
                    width: "100%", background: "var(--bg-2)", border: "1px solid var(--line-soft)",
                    borderRadius: 3, padding: "4px 8px", color: "var(--ink)",
                    fontFamily: "var(--font-mono)", fontSize: 12, outline: 0,
                  };
                  const slug = label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
                  const fieldId = "traveler-meas-" + slug;
                  return (
                  <div key={label} style={{
                    border: "1px solid var(--line-soft)", borderRadius: 4, padding: "8px 10px", background: "var(--bg-1)"
                  }}>
                    <div className="label" style={{ marginBottom: 4 }}>{label} ({unit})</div>
                    <input id={fieldId} name={fieldId} aria-label={label + " measurement (" + unit + ")"} placeholder="—" style={_measurementInputStyle}/>
                  </div>
                  );
                })}
              </div>

              <div style={{ display: "flex", gap: 8 }}>
                <Btn size="sm" icon="Plus" onClick={() => window.forgeToast && window.forgeToast("Measurement capture queued — wired in v2")}>Capture measurement</Btn>
                <Btn size="sm" variant="primary" icon="Check" onClick={() => window.forgeToast && window.forgeToast("Sign-off draft queued — wired in v2")}>Sign off · STA-014</Btn>
                <Btn size="sm" variant="ghost" icon="X" onClick={() => window.forgeToast && window.forgeToast("NCR draft queued — wired in v2")}>Raise NCR</Btn>
              </div>
            </div>
          </Panel>

          <Panel title="as-built BOM accreting" right={<Tag>live</Tag>}>
            <div style={{ padding: 12, display: "flex", flexDirection: "column", gap: 4 }}>
              {bomLines.map(([line, color]) => (
                <div key={line} className="mono" style={{ fontSize: 12, color, lineHeight: 1.55 }}>{line}</div>
              ))}
              <div style={{ marginTop: 10, paddingTop: 10, borderTop: "1px solid var(--line-soft)" }}>
                <div className="label" style={{ marginBottom: 6 }}>STA-014 · cycle trend</div>
                <Spark data={cycleTrend} height={36} stroke="var(--cool)"/>
                <div className="mono" style={{ fontSize: 12, color: "var(--ink-3)", marginTop: 4 }}>
                  STA-014 cycle · 19 min avg · 22 min est this run
                </div>
              </div>
            </div>
          </Panel>
        </div>

        {/* Section 3: agent footer */}
        <AgentCallout
          label="Forge agent · context"
          body={isTritan
            ? "Stage stack avg 8 min; first-run estimates 11 min. Bowl seal failures last week correlated to ECO-0051 NRV upgrade pending — verify torque sequence A→B→C."
            : "STA-014 cycle estimate 22 min; closest historical batch averaged 19 min. Out-of-spec at STA-019 last week auto-correlated to ECO-2451 — watch the CFRP datum scheme."
          }
        >
          <Btn size="sm" icon="Eye" onClick={() => window.forgeToast && window.forgeToast("Plan preview queued — wired in v2")}>Plan</Btn>
        </AgentCallout>
      </div>
    </div>
  );
}

// ─────────────────────────────── AUDITOR ──────────────────────────────────
function ScreenAuditor() {
  const tenant = useActiveTenant();
  const _fallbackWoId = (tenant && tenant.work_orders && tenant.work_orders[0] && tenant.work_orders[0].id) || "WO-—";
  const _fallbackStationId = (tenant && tenant.routing && tenant.routing[0] && (tenant.routing[0].station || tenant.routing[0].id)) || "STA-01";
  const _fallbackStationCode = String(_fallbackStationId).toUpperCase();
  const allModes = ["forge://", "plan://", "build://", "line://", "traveler://"];
  const [modeSel, setModeSel] = uS7(new Set(["all"]));
  const [reg, setReg] = uS7("none");
  const [search, setSearch] = uS7("");

  const tenantEvents = (tenant && tenant.ledger && tenant.ledger.length)
    ? tenant.ledger.slice().reverse().map(function(e, i) {
        var hashSlice = (e.event_id || "").replace(/[^0-9a-f]/gi, "").toLowerCase();
        var before = hashSlice ? (hashSlice + "0000000").slice(0, 8) : "00000000";
        var after  = hashSlice ? (hashSlice + "00000ff").slice(0, 8) : "ffffffff";
        return {
          id: i + 1, ts: e.ts || "—", actor: e.actor || "—",
          mode: ((e.mode || "forge") + "://"),
          action: e.type || "—",
          object: e.summary || e.ref || "—",
          status: "complete",
          reg: "none",
          before: before, after: after,
          ver: "fcp://verify/" + (e.event_id || "ev"),
          sig: "ed25519:0x" + (hashSlice + "0000").slice(0, 4) + "…" + (hashSlice + "0000").slice(-4),
        };
      })
    : null;

  const events = tenantEvents || [
    { id: 1, ts: "2m ago",  actor: "external · supplier", mode: "forge://", action: "supplier.delegate_quote",        object: "Hexcel/SUB-A12",          status: "pending",     reg: "ISO 13485", before: "a3f29c1b", after: "—",        ver: "fcp://verify/ev-1f8e2a", sig: "ed25519:0xa3f2…1c4d" },
    { id: 2, ts: "8m ago",  actor: "T. Nasser",           mode: "traveler://", action: "traveler.capture_measurement", object: (_fallbackWoId + "/" + _fallbackStationCode),       status: "in-process",  reg: "none",      before: "44219ab0", after: "44219ab1", ver: "fcp://verify/ev-7c4a9b", sig: "ed25519:0x7c4a…9b2d" },
    { id: 3, ts: "15m ago", actor: "system · forge",      mode: "forge://", action: "forge.audit_export",             object: "AS9100-2027-Q2",          status: "complete",    reg: "AS9100",    before: "00000000", after: "9d2f1a3c", ver: "fcp://verify/ev-9d2f1a", sig: "ed25519:0x9d2f…1a3c" },
    { id: 4, ts: "3h ago",  actor: "M. Haddad",           mode: "forge://", action: "forge.transform_ebom_to_mbom",   object: "HTU-220.10.02@C",         status: "complete",    reg: "AS9100",    before: "5e1a44b9", after: "6f2c5710", ver: "fcp://verify/ev-6f2c57", sig: "ed25519:0x6f2c…5710" },
    { id: 5, ts: "4h ago",  actor: "P. Kumar",            mode: "forge://", action: "supplier.find_alternates",        object: "SUB-A12",                 status: "complete",    reg: "AS9100",    before: "8b3d22ee", after: "8b3d22ef", ver: "fcp://verify/ev-8b3d22", sig: "ed25519:0x8b3d…22ef" },
    { id: 6, ts: "8h ago",  actor: "line-agent",          mode: "line://", action: "line.run_readiness_check",          object: "2027-W22",                status: "complete",    reg: "ISO 26262", before: "21cc7740", after: "21cc7741", ver: "fcp://verify/ev-21cc77", sig: "ed25519:0x21cc…7741" },
    { id: 7, ts: "12h ago", actor: "K. Chen",             mode: "build://", action: "build.release_routing",            object: "HTU-220.10.04@D",         status: "complete",    reg: "ISO 26262", before: "47aa1d09", after: "58bb2e1a", ver: "fcp://verify/ev-58bb2e", sig: "ed25519:0x58bb…2e1a" },
    { id: 8, ts: "18h ago", actor: "S. Okafor",           mode: "plan://", action: "plan.replan_program",               object: "CDR-shift +14d",          status: "complete",    reg: "ISO 13485", before: "c91e7702", after: "d02f8813", ver: "fcp://verify/ev-d02f88", sig: "ed25519:0xd02f…8813" },
    { id: 9, ts: "1d ago",  actor: "plan-agent",          mode: "plan://", action: "plan.monte_carlo_forecast",         object: "OAM-program",             status: "complete",    reg: "AS9100",    before: "11334455", after: "22445566", ver: "fcp://verify/ev-224455", sig: "ed25519:0x2244…5566" },
    { id:10, ts: "1d ago",  actor: "T. Nasser",           mode: "traveler://", action: "traveler.sign_off",             object: "WO-44218/STA-022",        status: "complete",    reg: "none",      before: "33aabbcc", after: "44ccddee", ver: "fcp://verify/ev-44ccdd", sig: "ed25519:0x44cc…ddee" },
    { id:11, ts: "2d ago",  actor: "J. Park",             mode: "forge://", action: "forge.run_dfm_lints",              object: "HTU-220.10.02@C",         status: "complete",    reg: "AS9100",    before: "55ff6677", after: "66001188", ver: "fcp://verify/ev-660011", sig: "ed25519:0x6600…1188" },
    { id:12, ts: "2d ago",  actor: "M. Haddad",           mode: "forge://", action: "forge.create_eco",                 object: "ECO-2451",                status: "complete",    reg: "AS9100",    before: "77889900", after: "8899aabb", ver: "fcp://verify/ev-8899aa", sig: "ed25519:0x8899…aabb" },
  ];

  const [expanded, setExpanded] = uS7(() => new Set([1, 3, 4, 8])); // events 1/2/4/8 in temporal order — id 1 is most recent (2m), id 3 is 15m, id 4 is 3h, id 8 is 18h. Per spec #1,#2,#4,#8 expanded.
  // Note: spec calls events #1,#2,#4,#8 by *temporal order* (most recent first). That maps to ids 1, 3, 5, 9 here? Let's recompute strictly by spec ordering:
  // Spec ordered list (most recent FIRST): 1) 2m ago supplier.delegate_quote · 2) 15m ago forge.audit_export · 3) 8m ago traveler.capture_measurement · 4) 3h ago transform · ...
  // The spec writes them slightly out of strict ts order but says "in this temporal order — most recent FIRST". Use the spec's numbering directly.

  // Re-key expand state to use spec ordinal positions:
  // pos 1 = id 1, pos 2 = id 3, pos 3 = id 2, pos 4 = id 4, pos 5 = id 5, pos 6 = id 6, pos 7 = id 7, pos 8 = id 8, pos 9 = id 9, pos 10 = id 10, pos 11 = id 11, pos 12 = id 12.
  // Default expanded positions: 1, 2, 4, 8 → ids 1, 3, 4, 8.

  const toggle = (id) => {
    const next = new Set(expanded);
    if (next.has(id)) next.delete(id); else next.add(id);
    setExpanded(next);
  };

  const toggleMode = (m) => {
    const next = new Set(modeSel);
    if (m === "all") {
      setModeSel(new Set(["all"]));
      return;
    }
    next.delete("all");
    if (next.has(m)) next.delete(m); else next.add(m);
    if (next.size === 0) next.add("all");
    setModeSel(next);
  };

  const filtered = events.filter(e => {
    if (!modeSel.has("all") && !modeSel.has(e.mode)) return false;
    if (reg !== "none" && e.reg !== reg) return false;
    if (search) {
      const q = search.toLowerCase();
      if (!(e.actor.toLowerCase().includes(q) || e.action.toLowerCase().includes(q) || e.object.toLowerCase().includes(q))) return false;
    }
    return true;
  });

  const statusTone = (s) =>
    s === "complete" ? "ok" : s === "in-process" ? "info" : s === "pending" ? "warn" : s === "failed" ? "err" : "";

  return (
    <div style={{ display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }}>
      {/* filter strip */}
      <div style={{
        padding: "10px 14px", borderBottom: "1px solid var(--line-soft)", background: "var(--bg-1)",
        display: "flex", flexDirection: "column", gap: 8
      }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
          <span className="label" style={{ width: 80 }}>mode:</span>
          <Chip active={modeSel.has("all")} onClick={() => toggleMode("all")}>all</Chip>
          {allModes.map(m => (
            <Chip key={m} active={modeSel.has(m)} onClick={() => toggleMode(m)}>{m}</Chip>
          ))}
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
          <span className="label" style={{ width: 80 }}>regulation:</span>
          {["none", "AS9100", "ISO 13485", "ISO 26262"].map(r => (
            <Chip key={r} active={reg === r} onClick={() => setReg(r)}>{r}</Chip>
          ))}
          <div style={{ flex: 1 }}/>
          <div style={{ position: "relative" }}>
            <span style={{ position: "absolute", left: 7, top: "50%", transform: "translateY(-50%)", color: "var(--ink-4)" }}>
              {I("Search", { size: 12 })}
            </span>
            {(() => {
              const _auditSearchStyle = {
                background: "var(--bg-2)", border: "1px solid var(--line)", borderRadius: 4,
                padding: "4px 8px 4px 24px", color: "var(--ink)",
                fontFamily: "var(--font-mono)", fontSize: 12, width: 240, outline: 0,
              };
              return (
                <input
                  id="ledger-search" name="ledger-search" aria-label="Filter ledger events by actor, action, or object"
                  value={search} onChange={e => setSearch(e.target.value)}
                  placeholder="filter by actor, action, object…"
                  style={_auditSearchStyle}
                />
              );
            })()}
          </div>
        </div>
      </div>

      {/* event list */}
      <div style={{ flex: 1, overflow: "auto", padding: 14 }}>
        <Panel title={`signed event ledger · ${filtered.length} of ${events.length}`} right={<>
          <Pill tone="ok" dot={true}>ed25519 verified</Pill>
          <Btn size="sm" icon="ArrowD" onClick={function() {
            if (window.forgeApi && typeof window.forgeApi.exportAuditUrl === "function") {
              window.location.href = window.forgeApi.exportAuditUrl("pdf");
              if (window.forgeToast) window.forgeToast("Audit PDF download started");
            } else {
              if (window.forgeToast) window.forgeToast({ msg: "PDF export queued — v2", kind: "info" });
            }
          }}>Export PDF</Btn>
        </>}>
          <div>
            {filtered.map(e => {
              const open = expanded.has(e.id);
              const _eventRowStyle = {
                display: "grid", gridTemplateColumns: "120px 80px 1fr 1fr 100px 28px",
                gap: 8, alignItems: "center", padding: "8px 10px",
                borderBottom: "1px solid var(--line-soft)", cursor: "pointer",
                background: open ? "var(--bg-2)" : "transparent",
              };
              return (
                <div key={e.id}>
                  <div role="button" tabIndex={0} onClick={() => toggle(e.id)} onKeyDown={(ev) => { if (ev.key === "Enter" || ev.key === " ") { ev.preventDefault(); toggle(e.id); } }} style={_eventRowStyle}
                  onMouseEnter={ev => { if (!open) ev.currentTarget.style.background = "var(--bg-2)"; }}
                  onMouseLeave={ev => { if (!open) ev.currentTarget.style.background = "transparent"; }}
                  >
                    <span className="mono" style={{ fontSize: 12, color: "var(--ink-3)" }}>{e.ts}</span>
                    <Pill tone="accent">{e.mode}</Pill>
                    <span style={{ fontSize: 12, color: "var(--ink-2)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{e.actor}</span>
                    <span className="mono" style={{ fontSize: 12, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
                      <span style={{ color: "var(--accent)" }}>{e.action}</span>{" "}
                      <span style={{ color: "var(--ink-3)" }}>{e.object}</span>
                    </span>
                    <Pill tone={statusTone(e.status)}>{e.status}</Pill>
                    <span style={{ textAlign: "right", color: "var(--ink-3)", fontFamily: "var(--font-mono)", fontSize: 12 }}>
                      {open ? "▾" : "▸"}
                    </span>
                  </div>

                  {open && (() => {
                    const _eventDetailStyle = {
                      margin: "0 10px 8px 10px",
                      background: "var(--bg-2)", border: "1px solid var(--line-soft)",
                      boxShadow: "inset 3px 0 0 var(--accent)",
                      padding: 12, borderRadius: 4,
                      display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14,
                    };
                    return (
                    <div style={_eventDetailStyle}>
                      <div>
                        {[
                          ["actor",  e.actor],
                          ["mode",   e.mode],
                          ["action", e.action],
                          ["object", e.object],
                          ["etag",   `${e.before} → ${e.after}`],
                          ["ts",     e.ts],
                        ].map(([k, v]) => (
                          <div key={k} style={{ display: "grid", gridTemplateColumns: "70px 1fr", gap: 8, padding: "2px 0" }}>
                            <span className="label">{k}</span>
                            <span className="mono" style={{ fontSize: 12, color: "var(--ink-2)" }}>{v}</span>
                          </div>
                        ))}
                      </div>
                      <div style={{
                        background: "var(--bg-1)", border: "1px solid var(--line-soft)",
                        borderRadius: 4, padding: 10
                      }}>
                        <div className="label" style={{ marginBottom: 4 }}>verification</div>
                        <div className="mono" style={{ fontSize: 12, color: "var(--ink-2)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
                          {e.ver}
                        </div>
                        <div className="mono" style={{ fontSize: 12, color: "var(--accent)", marginTop: 4 }}>
                          verify ↗
                        </div>
                        <div className="hr"/>
                        <div className="label" style={{ marginBottom: 4 }}>signature</div>
                        <div className="mono" style={{ fontSize: 12, color: "var(--ink-3)" }}>{e.sig}</div>
                        {e.reg !== "none" && (
                          <>
                            <div className="hr"/>
                            <div className="label" style={{ marginBottom: 4 }}>regulation</div>
                            <Pill tone="info">{e.reg}</Pill>
                          </>
                        )}
                      </div>
                    </div>
                    );
                  })()}
                </div>
              );
            })}
            {filtered.length === 0 && (
              <div style={{ padding: 24, textAlign: "center", color: "var(--ink-3)", fontSize: 12 }}>
                no events match current filters
              </div>
            )}
          </div>
        </Panel>

        <div className="mono" style={{
          marginTop: 10, fontSize: 12, color: "var(--ink-3)", textAlign: "center"
        }}>
          All Strike events are ed25519-signed. before_etag / after_etag pairs are queryable via fcp://verify/&lt;event_id&gt;.
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { ScreenLine, ScreenTraveler, ScreenAuditor });
