// Screens 5/5 — Analytics, People & HR, Documents, Maintenance, Integrations

const { useState: uS5, useMemo: uM5, useRef: uR5 } = React;

function BarGroup({ data, maxV, colorFn, height = 80 }) {
  return (
    <svg width="100%" height={height} viewBox={`0 0 ${data.length * 28} ${height}`} preserveAspectRatio="none">
      {data.map((d, i) => {
        const bh = (d.v / maxV) * (height - 16);
        return (
          <g key={d.lbl}>
            <rect x={i * 28 + 4} y={height - 16 - bh} width={20} height={bh} rx="2" fill={colorFn(d)} opacity="0.85"/>
            <text x={i * 28 + 14} y={height - 2} textAnchor="middle" fontSize="10" fontFamily="var(--font-mono)" fill="var(--ink-3)">{d.lbl}</text>
          </g>
        );
      })}
    </svg>
  );
}

function DonutRing({ segments, size = 80 }) {
  const cx = size / 2, cy = size / 2, r = size * 0.36, sw = size * 0.12;
  let angle = -Math.PI / 2;
  const total = segments.reduce((a, s) => a + s.v, 0);
  return (
    <svg width={size} height={size}>
      {segments.map((s) => {
        const span = (s.v / total) * Math.PI * 2;
        const x1 = cx + r * Math.cos(angle), y1 = cy + r * Math.sin(angle);
        angle += span;
        const x2 = cx + r * Math.cos(angle), y2 = cy + r * Math.sin(angle);
        const large = span > Math.PI ? 1 : 0;
        return (
          <path key={s.color}
            d={`M ${x1} ${y1} A ${r} ${r} 0 ${large} 1 ${x2} ${y2}`}
            fill="none" stroke={s.color} strokeWidth={sw} opacity="0.85"/>
        );
      })}
      <text x={cx} y={cy + 4} textAnchor="middle" fontSize="13" fontFamily="var(--font-mono)" fill="var(--ink)">{total}</text>
    </svg>
  );
}

// ─────────────────────────────── ANALYTICS ────────────────────────────────
function ScreenAnalytics() {
  const tenant = useActiveTenant();
  const tenantName = (tenant && tenant.tenant && tenant.tenant.name) || "OAM";
  const tenantHasOps = !!(tenant && tenant.work_orders && tenant.work_orders.length && tenant.cost_cascade && tenant.cost_cascade.length);
  const [range, setRange] = uS5("30d");

  // Tenant-derived KPI tiles for header (deep tenants only).
  // ALL values derived from primary fixtures (boms, ledger, work_orders, eco) — never hand-typed.
  const kpiCells = tenantHasOps
    ? (function() {
        var boms       = tenant.boms || [];
        var ledger     = tenant.ledger || [];
        var workOrders = tenant.work_orders || [];
        var eco        = tenant.eco || [];

        // Active SKUs — distinct boms.sku.
        var activeSkus = new Set(boms.map(function(b) { return b.sku; })).size;

        // Open RFQs — rfq_received minus po_received (approximation, ledger lacks rfq_id linkage).
        var rfqCount = ledger.filter(function(e) { return e.type === "rfq_received"; }).length;
        var poCount  = ledger.filter(function(e) { return e.type === "po_received"; }).length;
        var openRfqs = Math.max(0, rfqCount - poCount);

        // WOs scheduled — anything active in the pipeline.
        var woStatuses = ["scheduled", "released", "in-progress", "pilot"];
        var wosScheduled = workOrders.filter(function(w) { return woStatuses.indexOf(w.status) !== -1; }).length;

        // Open ECOs — not yet applied.
        var openEcos = eco.filter(function(e) { return e.status !== "applied"; }).length;

        // Audits due 30d — vendor_audit_started without a later completion (approximation).
        var auditStart = ledger.filter(function(e) { return e.type === "vendor_audit_started"; }).length;
        var auditDone  = ledger.filter(function(e) { return e.type === "vendor_audit_completed"; }).length;
        var auditsDue  = Math.max(0, auditStart - auditDone);

        // Line-readiness % — avg of per-WO station_progress means for in-progress WOs.
        var inProgress = workOrders.filter(function(w) { return w.status === "in-progress"; });
        var lineReadiness = 0;
        if (inProgress.length > 0) {
          var perWo = inProgress.map(function(w) {
            var sp = w.station_progress || {};
            var vals = Object.keys(sp).map(function(k) { return Number(sp[k]) || 0; });
            return vals.length ? vals.reduce(function(a, b) { return a + b; }, 0) / vals.length : 0;
          });
          lineReadiness = perWo.reduce(function(a, b) { return a + b; }, 0) / perWo.length;
        }

        // Locale-aware number formatter. Tritan reads en-IN (2-2-3 grouping
        // → "1,23,456"), aetherion en-US, mittelstand de-DE. Falls back to
        // plain stringification when forgeI18n hasn't bootstrapped yet.
        var _fmtN = function (n) {
          return (window.forgeI18n && window.forgeI18n.formatNumber)
            ? window.forgeI18n.formatNumber(n)
            : String(n);
        };

        return [
          ["Active SKUs",      _fmtN(activeSkus),                      "from BOMs",        "info"],
          ["Open RFQs",        _fmtN(openRfqs),                        "awaiting PO",      openRfqs > 0 ? "warn" : "ok"],
          ["WOs scheduled",    _fmtN(wosScheduled),                    "in pipeline",      "accent"],
          ["Open ECOs",        _fmtN(openEcos),                        openEcos ? "needs approval" : "—", openEcos > 0 ? "warn" : "ok"],
          ["Audits due 30d",   _fmtN(auditsDue),                       "follow-ups",       auditsDue > 0 ? "warn" : "ok"],
          ["Line-readiness %", Math.round(lineReadiness * 100) + "%",  inProgress.length + " in-progress", lineReadiness > 0.5 ? "ok" : "warn"],
        ];
      })()
    : null;

  const isTritan = !!(tenant && tenant.tenant && tenant.tenant.id === "tritan");
  const designCoverage = isTritan
    ? [
        {lbl:"Motor",v:78},{lbl:"Pump",v:62},{lbl:"Cable",v:55},
        {lbl:"Pkg",v:48},{lbl:"Test",v:88},{lbl:"FAT",v:72},{lbl:"QA",v:90},
      ]
    : [
        {lbl:"Prop",v:47},{lbl:"Tie",v:29},{lbl:"OxTk",v:0},{lbl:"Fltr",v:29},
        {lbl:"Rmn",v:14},{lbl:"CGas",v:60},{lbl:"Engn",v:86},{lbl:"Plmb",v:60},
      ];
  const mfgCoverage = isTritan
    ? [
        {lbl:"Motor",v:55},{lbl:"Pump",v:42},{lbl:"Cable",v:60},
        {lbl:"Pkg",v:30},{lbl:"Test",v:65},{lbl:"FAT",v:50},{lbl:"QA",v:80},
      ]
    : [
        {lbl:"Prop",v:64},{lbl:"Tie",v:56},{lbl:"OxTk",v:20},{lbl:"Fltr",v:20},
        {lbl:"Rmn",v:63},{lbl:"CGas",v:70},{lbl:"Engn",v:60},{lbl:"Plmb",v:30},
      ];
  const weeklyTrend = [12,18,22,19,28,31,24,33,38,36,41,44,40,48];
  const burnSparkD   = [85,82,78,74,70,67,64,60,57,54,51,49,46,44];

  const _analyticsRootStyle = { padding:14, display:"grid", gridTemplateColumns:"1fr 1fr 1fr", gridTemplateRows:"auto auto auto", gap:14, minHeight:0, height:"100%", overflowY:"auto" };

  return (
    <div style={_analyticsRootStyle}>

      {/* KPI row */}
      <Panel title={tenantName + " · Program Health"} style={{ gridColumn:"1/-1" }}>
        <div style={{ display:"grid", gridTemplateColumns:`repeat(${(kpiCells || new Array(7)).length},1fr)` }}>
          {(kpiCells || [
            ["Total Parts","122","—","info"],["Design Avg","41%","+3.2 wk","info"],
            ["Mfg Avg","52%","+5.4 wk","accent"],["Test Avg","0%","On track","ok"],
            ["Open Actions","18","2 critical","err"],["On-Time Del.","74%","-2 pt","warn"],
            ["Supplier Score","88","B+","ok"],
          ]).map(([k,v,d,t]) => (
            <div key={k} style={{ padding:"10px 12px", borderRight:"1px solid var(--line-soft)" }}>
              <div className="label" style={{ whiteSpace: "normal", overflow: "visible", textOverflow: "clip", lineHeight: 1.3 }}>{k}</div>
              <div className="mono tnum" style={{ fontSize:20, color:`var(--${t})` }}>{v}</div>
              <div className="mono" style={{ fontSize: 12, color:"var(--ink-3)", marginTop:2 }}>{d}</div>
            </div>
          ))}
        </div>
      </Panel>

      {/* Design coverage */}
      <Panel title="Design Completion · by Sub-System">
        <div style={{ padding:"10px 12px" }}>
          <BarGroup data={designCoverage} maxV={100} colorFn={d => d.v >= 70 ? "var(--ok)" : d.v >= 40 ? "var(--info)" : "var(--err)"} height={90}/>
          <div style={{ display:"flex", justifyContent:"space-between", marginTop:8 }}>
            <div><div className="label">Leading</div><div className="mono tnum" style={{ fontSize:16 }}>{isTritan ? "QA 90%" : "Engine 86%"}</div></div>
            <div><div className="label">Lagging</div><div className="mono tnum" style={{ fontSize:16, color:"var(--err)" }}>{isTritan ? "Pkg 48%" : "OxTank 0%"}</div></div>
          </div>
        </div>
      </Panel>

      {/* Mfg coverage */}
      <Panel title="Manufacturing Completion · by Sub-System">
        <div style={{ padding:"10px 12px" }}>
          <BarGroup data={mfgCoverage} maxV={100} colorFn={d => d.v >= 70 ? "var(--ok)" : d.v >= 40 ? "var(--accent)" : "var(--err)"} height={90}/>
          <div style={{ display:"flex", justifyContent:"space-between", marginTop:8 }}>
            <div><div className="label">Leading</div><div className="mono tnum" style={{ fontSize:16 }}>{isTritan ? "QA 80%" : "Prop 64%"}</div></div>
            <div><div className="label">Lagging</div><div className="mono tnum" style={{ fontSize:16, color:"var(--err)" }}>{isTritan ? "Pkg 30%" : "OxTank 20%"}</div></div>
          </div>
        </div>
      </Panel>

      {/* Status breakdown */}
      <Panel title="Parts · Status Breakdown">
        <div style={{ padding:12, display:"flex", gap:16, alignItems:"center" }}>
          <DonutRing size={100} segments={[
            { v:28, color:"var(--ok)"   },
            { v:61, color:"var(--info)" },
            { v:19, color:"var(--warn)" },
            { v:14, color:"var(--err)"  },
          ]}/>
          <div style={{ flex:1 }}>
            {[["On Track","28","ok"],["In Progress","61","info"],["At Risk","19","warn"],["Blocked","14","err"]].map(([l,v,t]) => (
              <div key={l} style={{ display:"flex", justifyContent:"space-between", padding:"4px 0", borderBottom:"1px solid var(--line-soft)" }}>
                <div style={{ display:"flex", alignItems:"center", gap:6 }}>
                  <span style={{ width:8, height:8, borderRadius:8, background:`var(--${t})`, display:"inline-block" }}/>
                  <span style={{ fontSize:12 }}>{l}</span>
                </div>
                <span className="mono tnum" style={{ color:`var(--${t})` }}>{v}</span>
              </div>
            ))}
          </div>
        </div>
      </Panel>

      {/* Weekly velocity */}
      <Panel title="Design Closure · Weekly Velocity" right={
        <>{["7d","30d","90d"].map(r=><Btn key={r} size="sm" variant={r===range?"primary":"ghost"} onClick={()=>setRange(r)}>{r}</Btn>)}</>
      }>
        <div style={{ padding:12 }}>
          <Spark data={weeklyTrend} height={56} stroke="var(--info)"/>
          <div style={{ display:"flex", justifyContent:"space-between", marginTop:8 }}>
            <div><div className="label">Items closed/wk</div><div className="mono tnum" style={{ fontSize:18 }}>48</div></div>
            <div><div className="label">Peak</div><div className="mono tnum" style={{ fontSize:18 }}>48</div></div>
            <div><div className="label">Forecast close</div><div className="mono tnum" style={{ fontSize:18 }}>Sep 26</div></div>
          </div>
        </div>
      </Panel>

      {/* Procurement health */}
      <Panel title="Procurement · Lead Time Risk">
        <div style={{ padding:12 }}>
          {(isTritan && tenant && tenant.parts && tenant.parts.length
            ? tenant.parts.slice().sort(function(a,b){return (b.lead_time_days||0)-(a.lead_time_days||0);}).slice(0,6).map(function(p) {
                var d = p.lead_time_days || 0;
                var t = d >= 60 ? "err" : d >= 30 ? "warn" : "ok";
                return [p.name, d, t];
              })
            : [
                ["Engine Assembly",90,"err"],["Fuel Tank",60,"warn"],["Oxidiser Tank",80,"err"],
                ["Swagelok Fittings",30,"ok"],["Cold Gas Assy",55,"warn"],
              ]
          ).map(([n,risk,t]) => (
            <div key={n} style={{ display:"grid", gridTemplateColumns:"140px 1fr 40px", gap:8, alignItems:"center", padding:"4px 0" }}>
              <span style={{ fontSize: 12, color:"var(--ink-2)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{n}</span>
              <div style={{ height:6, background:"var(--bg-3)", borderRadius:3, overflow:"hidden" }}>
                <div style={{ width:`${risk}%`, height:"100%", background:`var(--${t})`, borderRadius:3 }}/>
              </div>
              <span className="mono tnum" style={{ fontSize: 12, color:`var(--${t})`, textAlign:"right" }}>{risk}d</span>
            </div>
          ))}
          <div className="hr"/>
          <div className="muted mono" style={{ fontSize: 12 }}>Lead time risk index, avg critical path</div>
        </div>
      </Panel>

      {/* Burndown */}
      <Panel title="Open Actions · Burndown">
        <div style={{ padding:12 }}>
          <Spark data={burnSparkD} height={56} stroke="var(--accent)"/>
          <div style={{ display:"flex", justifyContent:"space-between", marginTop:8 }}>
            <div><div className="label">Open</div><div className="mono tnum" style={{ fontSize:18 }}>44</div></div>
            <div><div className="label">Slope</div><div className="mono tnum" style={{ fontSize:18 }}>−3.4/wk</div></div>
            <div><div className="label">Forecast</div><div className="mono tnum" style={{ fontSize:18 }}>Aug 12</div></div>
          </div>
        </div>
      </Panel>

      {/* Team capacity */}
      <Panel title="Team Capacity · vs Load">
        <div style={{ padding:12 }}>
          {[
            ["Engineering","var(--info)",0.82],["Procurement","var(--accent)",0.71],
            ["Manufacturing","var(--ok)",0.54],["Quality","var(--warn)",0.93],
          ].map(([t,c,v]) => (
            <div key={t} style={{ marginBottom:10 }}>
              <div style={{ display:"flex", justifyContent:"space-between", marginBottom:3 }}>
                <span style={{ fontSize: 12 }}>{t}</span>
                <span className="mono tnum" style={{ fontSize: 12, color: v > 0.9 ? "var(--err)" : c }}>{Math.round(v*100)}% loaded</span>
              </div>
              <div style={{ height:8, background:"var(--bg-3)", borderRadius:4, overflow:"hidden" }}>
                <div style={{ width:`${v*100}%`, height:"100%", background:c, borderRadius:4 }}/>
              </div>
            </div>
          ))}
        </div>
      </Panel>

      {/* Recent activity */}
      <Panel title="Activity · last 48h" style={{ gridColumn:"3" }}>
        <div style={{ padding:8 }}>
          {(isTritan ? [
            ["ECO raised","NRV body CI → S.G.-400 (ECO-0051)","warn","2h"],
            ["PO raised","Spire Foundry — NRV S.G.-400 expedite","warn","5h"],
            ["Doc approved","DRG-M27418-PMP rev B — Devansh A.","ok","8h"],
            ["WO update","WO-44219 stage A · 24 units short","warn","12h"],
            ["Qual passed","TPX-H-0008 Q-H pass — Neha G.","ok","18h"],
            ["Audit signed","Helios audit · 87% conditional","ok","24h"],
          ] : [
            ["ECO raised","Oxidiser tank — no CDR sign-off","err","2h"],
            ["PO raised","Engine Assembly — 90d lead","warn","5h"],
            ["Doc approved","MFG-001 Rev B — Suresh Kumar","ok","8h"],
            ["BOM update","Items 17–26 design % updated","info","12h"],
            ["Qual passed","Cold Gas Assy — TVAC-sim","ok","18h"],
            ["Risk flagged","TVAC chamber — overdue service","err","24h"],
          ]).map(([a,b,t,time]) => (
            <div key={b} style={{ display:"grid", gridTemplateColumns:"1fr auto", gap:8, padding:"6px 6px", borderBottom:"1px solid var(--line-soft)" }}>
              <div>
                <div style={{ fontSize: 12, color:"var(--ink)" }}>{a}</div>
                <div className="muted" style={{ fontSize: 12 }}>{b}</div>
              </div>
              <div style={{ textAlign:"right" }}>
                <Pill tone={t} dot={false}>{t.toUpperCase()}</Pill>
                <div className="mono" style={{ fontSize: 12, color:"var(--ink-3)", marginTop:2 }}>{time} ago</div>
              </div>
            </div>
          ))}
        </div>
      </Panel>
    </div>
  );
}

// ──────────────────────────────── PEOPLE & HR ─────────────────────────────
function ScreenPeople() {
  const tenant = useActiveTenant();
  const [tab, setTab]   = uS5("roster");
  const [selPerson, setSelPerson] = uS5(null);
  const tenantPeople = (tenant && tenant.people && tenant.people.length) ? tenant.people : null;
  const isStubTenant = tenant && tenant.depth && tenant.depth !== "deep" && !tenantPeople;

  const teams = [
    { id:"engineering",   label:"Engineering",    color:"var(--info)",   lead:"Sana Raza",   count:5 },
    { id:"procurement",   label:"Procurement",    color:"var(--accent)", lead:"Aditi Singh",  count:3 },
    { id:"manufacturing", label:"Manufacturing",  color:"var(--ok)",     lead:"Suresh Kumar", count:3 },
    { id:"management",    label:"Management",     color:"var(--warn)",   lead:"Arjun Mehta",  count:1 },
  ];

  if (isStubTenant) {
    return (
      <div style={{ padding: 28, height: "100%", display: "flex", alignItems: "center", justifyContent: "center" }}>
        <div style={{ maxWidth: 460, textAlign: "center" }}>
          <div className="serif" style={{ fontSize: 26, lineHeight: 1.15, marginBottom: 8 }}>Crew coming online</div>
          <div className="muted" style={{ fontSize: 14 }}>
            People & HR is fully populated on the Tritan pump tenant. Switch tenants to explore.
          </div>
        </div>
      </div>
    );
  }

  // For tenant with .people, project into the same shape ScreenPeople expects:
  // { id, name, role, dept, team, loc, joined }
  const projectedPeople = tenantPeople
    ? tenantPeople.map(function(p) {
        var role = (p.role || "").toLowerCase();
        var team = role.indexOf("design") >= 0 ? "engineering"
                  : role.indexOf("plant") >= 0 ? "management"
                  : role.indexOf("sales") >= 0 || role.indexOf("compliance") >= 0 ? "procurement"
                  : "manufacturing";
        return {
          id: p.id, name: p.name, role: p.role,
          dept: team.charAt(0).toUpperCase() + team.slice(1),
          team: team,
          loc: (tenant && tenant.tenant && tenant.tenant.site) || "—",
          joined: "2024-01-01",
        };
      })
    : null;
  const peopleList = projectedPeople || PEOPLE;
  const person = selPerson ? peopleList.find(p => p.id === selPerson) : null;

  // Wave 4D.3: real Add member + Export handlers. Lightweight prompt UX
  // for now — the roster reads from tenant.people in the cached state, so
  // a successful POST emits a person_added event that the SSE pool fans
  // out, and the next state refetch picks up the new row.
  async function handleAddMember() {
    const name = prompt("Name:", "");
    if (!name) return;
    const role = prompt("Role:", "");
    if (!role) return;
    try {
      await window.forgeApi.people.add({ name, role });
      alert("Added ✓");
    } catch (e) {
      alert("Failed: " + (e.message || e));
    }
  }
  function handleExportPeople() {
    window.location.href = window.forgeApi.people.exportUrl();
  }

  return (
    <div style={{ padding:14, display:"grid", gridTemplateColumns:"1fr 280px", gap:14, height:"100%", minHeight:0 }}>
      <div style={{ display:"flex", flexDirection:"column", gap:14, minHeight:0 }}>

        {/* org chart */}
        <Panel title={"Organisation · " + ((tenant && tenant.tenant && tenant.tenant.name) || "OAM Program")}>
          <div style={{ padding:14, overflow:"auto" }}>
            <svg width="700" height="220" viewBox="0 0 700 220">
              {/* lines */}
              {[220,340,460,580].map((x, i) => (
                <g key={x}>
                  <line x1="350" y1="62" x2="350" y2="90" stroke="var(--line-strong)" strokeWidth="1"/>
                  <line x1="220" y1="90" x2="580" y2="90" stroke="var(--line-strong)" strokeWidth="1"/>
                  <line x1={x} y1="90" x2={x} y2="118" stroke="var(--line-strong)" strokeWidth="1"/>
                </g>
              ))}
              {/* root */}
              {(function() {
                var rootPerson = tenantPeople ? (tenantPeople.find(function(p){ return /director/i.test(p.role || ""); }) || tenantPeople[0]) : null;
                var rootName = rootPerson ? rootPerson.name : "Arjun Mehta";
                var rootRole = rootPerson ? rootPerson.role : "Program Director";
                return (
                  <>
                    <rect x="270" y="16" width="160" height="46" rx="5" fill="var(--bg-2)" stroke="var(--warn)" strokeWidth="1.5"/>
                    <text x="350" y="38" textAnchor="middle" fontSize="12" fontFamily="var(--font-ui)" fill="var(--ink)">{rootName}</text>
                    <text x="350" y="54" textAnchor="middle" fontSize="10" fontFamily="var(--font-mono)" fill="var(--ink-3)">{rootRole}</text>
                  </>
                );
              })()}
              {/* teams */}
              {teams.map((t, i) => {
                const x = [170, 290, 410, 530][i];
                const teamPeople = peopleList.filter(p => p.team === t.id);
                return (
                  <g key={t.id}>
                    <rect x={x - 60} y="118" width="120" height="40" rx="4" fill="var(--bg-2)" stroke={t.color} strokeWidth="1.5"/>
                    <text x={x} y="136" textAnchor="middle" fontSize="11" fontFamily="var(--font-ui)" fill={t.color}>{t.label}</text>
                    <text x={x} y="150" textAnchor="middle" fontSize="10" fontFamily="var(--font-mono)" fill="var(--ink-3)">{t.count} members</text>
                    {/* avatars */}
                    {teamPeople.slice(0,3).map((p, j) => (
                      <g key={p.id} transform={`translate(${x - 24 + j * 20}, 170)`}>
                        <circle cx="10" cy="10" r="10" fill="var(--bg-3)" stroke={t.color} strokeWidth="1"/>
                        <text x="10" y="14" textAnchor="middle" fontSize="8" fontFamily="var(--font-mono)" fill="var(--ink-2)">
                          {p.name.split(" ").map(s=>s[0]).join("")}
                        </text>
                      </g>
                    ))}
                  </g>
                );
              })}
            </svg>
          </div>
        </Panel>

        {/* roster table */}
        <Panel title="Team Roster" right={
          <><Btn size="sm" icon="Plus" onClick={handleAddMember}>Add member</Btn><Btn size="sm" icon="ArrowD" onClick={handleExportPeople}>Export</Btn></>
        }>
          <table className="dtable">
            <thead><tr><th>Name</th><th>Role</th><th>Team</th><th>Location</th><th>Since</th><th>Status</th></tr></thead>
            <tbody>
              {peopleList.map(p => {
                const team = teams.find(t => t.id === p.team);
                const _personAvatarStyle = { width:24, height:24, borderRadius:24, background:"var(--bg-3)",
                  border:`1px solid ${team?.color || "var(--line)"}`,
                  display:"grid", placeItems:"center", fontFamily:"var(--font-mono)", fontSize: 12, flexShrink:0 };
                return (
                  <tr key={p.id} onClick={() => setSelPerson(p.id)} className={selPerson === p.id ? "selected" : ""} style={{ cursor:"pointer" }}>
                    <td>
                      <div style={{ display:"flex", alignItems:"center", gap:8 }}>
                        <div style={_personAvatarStyle}>
                          {p.name.split(" ").map(s=>s[0]).join("")}
                        </div>
                        <span style={{ color:"var(--ink)" }}>{p.name}</span>
                      </div>
                    </td>
                    <td>{p.role}</td>
                    <td><Pill tone="" dot={false} style={{ color:team?.color }}>{p.dept}</Pill></td>
                    <td>{p.loc}</td>
                    <td className="tnum">{p.joined.slice(0,7)}</td>
                    <td><Pill tone="ok" dot={false}>Active</Pill></td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </Panel>
      </div>

      {/* side detail */}
      <div style={{ display:"flex", flexDirection:"column", gap:14, minHeight:0 }}>
        {person ? (
          <>
            <Panel title="Member Detail">
              {(() => {
                const _personDetailAvatarStyle = { width:48, height:48, borderRadius:48, background:"var(--bg-3)",
                  border:"2px solid var(--accent)", display:"grid", placeItems:"center",
                  fontFamily:"var(--font-mono)", fontSize:16, marginBottom:10 };
                return (
              <div style={{ padding:14 }}>
                <div style={_personDetailAvatarStyle}>
                  {person.name.split(" ").map(s=>s[0]).join("")}
                </div>
                <div className="serif" style={{ fontSize:20 }}>{person.name}</div>
                <div className="muted" style={{ fontSize:12 }}>{person.role}</div>
                <div className="hr"/>
                {[["Team",person.team],["Dept",person.dept],["Location",person.loc],["Joined",person.joined]].map(([k,v]) => (
                  <div key={k} style={{ display:"grid", gridTemplateColumns:"80px 1fr", gap:8, padding:"3px 0" }}>
                    <span className="label">{k}</span>
                    <span className="mono" style={{ fontSize: 12, color:"var(--ink-2)" }}>{v}</span>
                  </div>
                ))}
              </div>
                );
              })()}
            </Panel>
            <Panel title="Workload">
              <div style={{ padding:12 }}>
                {[["Design Tasks","3 open","info"],["ECOs","1 pending","warn"],["Doc Reviews","2 pending","info"]].map(([k,v,t])=>(
                  <div key={k} style={{ display:"flex", justifyContent:"space-between", padding:"6px 0", borderBottom:"1px solid var(--line-soft)" }}>
                    <span style={{ fontSize:12 }}>{k}</span>
                    <Pill tone={t} dot={false}>{v}</Pill>
                  </div>
                ))}
              </div>
            </Panel>
          </>
        ) : (
          <Panel title="Team Breakdown">
            <div style={{ padding:12 }}>
              {teams.map(t => (
                <div key={t.id} style={{ marginBottom:12 }}>
                  <div style={{ display:"flex", justifyContent:"space-between", marginBottom:4 }}>
                    <span style={{ fontSize:12, color:t.color }}>{t.label}</span>
                    <span className="mono tnum" style={{ fontSize: 12 }}>{t.count} members</span>
                  </div>
                  <div style={{ height:6, background:"var(--bg-3)", borderRadius:3, overflow:"hidden" }}>
                    <div style={{ width:`${(t.count/12)*100}%`, height:"100%", background:t.color }}/>
                  </div>
                  <div className="muted" style={{ fontSize: 12, marginTop:2 }}>Lead · {t.lead}</div>
                </div>
              ))}
            </div>
          </Panel>
        )}
        <Panel title="Capacity Heatmap · this week">
          <div style={{ padding:10 }}>
            {peopleList.slice(0,6).map(p => {
              const load = [0.7,0.9,0.5,0.8,0.6,1.0,0.4,0.75,0.85,0.6,0.7,0.5][peopleList.indexOf(p) % 12];
              return (
                <div key={p.id} style={{ display:"grid", gridTemplateColumns:"90px 1fr 30px", gap:8, alignItems:"center", padding:"4px 0" }}>
                  <span style={{ fontSize: 12, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{p.name.split(" ")[0]}</span>
                  <div style={{ height:8, background:"var(--bg-3)", borderRadius:4, overflow:"hidden" }}>
                    <div style={{ width:`${load*100}%`, height:"100%", background: load > 0.9 ? "var(--err)" : load > 0.75 ? "var(--warn)" : "var(--ok)" }}/>
                  </div>
                  <span className="mono tnum" style={{ fontSize: 12 }}>{Math.round(load*100)}%</span>
                </div>
              );
            })}
          </div>
        </Panel>
      </div>
    </div>
  );
}

// Normalize a tenant.documents row to the shape ScreenDocuments expects
// (id, name, rev, type, status, owner, updated). Aetherion uses title/date/itar.
function normalizeTenantDoc(d) {
  if (!d) return null;
  return {
    id:      d.id || "",
    name:    d.name || d.title || "—",
    rev:     d.rev || "A",
    type:    d.type || d.classification || (d.itar ? "ITAR" : "DOC"),
    status:  d.status || "approved",
    owner:   d.owner || d.author || (d.itar ? "ITAR controlled" : "—"),
    updated: d.updated || d.date || "—",
    itar:           !!d.itar,
    classification: d.classification || null,
  };
}

// Mittelstand has no documents array in fixtures-mittelstand.jsx — provide a
// representative CE / IATF 16949 / PPAP / VDA set for the demo so the screen
// doesn't fall back to the generic OAM/space DOCS array.
const MITTELSTAND_DOCS = [
  { id:"DOC-MS-001", name:"MTL-220 Konstruktionsmappe (Rev D)",  rev:"D",    type:"DRAWING",    classification:"CE",          status:"approved", owner:"K. Becker",   updated:"2025-11-28" },
  { id:"DOC-MS-014", name:"CE Conformity Declaration · 2006/42/EC", rev:"r2", type:"CE",         classification:"CE",          status:"approved", owner:"S. Vogel",    updated:"2026-01-12" },
  { id:"DOC-MS-021", name:"IATF 16949 Audit Report · MAHLE Q1",  rev:"r1",    type:"IATF",       classification:"IATF 16949", status:"approved", owner:"M. Schulz",   updated:"2026-02-09" },
  { id:"DOC-MS-027", name:"PPAP Level 3 · MTL-220 batch-1",      rev:"r1",    type:"PPAP",       classification:"PPAP-3",      status:"review",   owner:"H. Müller",   updated:"2026-04-22" },
  { id:"DOC-MS-033", name:"ISO 230-1/2/4 acceptance certificate", rev:"r1",   type:"ISO",        classification:"ISO 230",     status:"approved", owner:"J. Hoffmann", updated:"2026-03-18" },
  { id:"DOC-MS-040", name:"ECO-MS-0017 · Granite-cell tolerance bump", rev:"B", type:"ECO",      classification:"CE",          status:"approved", owner:"K. Becker",   updated:"2025-11-30" },
  { id:"DOC-MS-046", name:"FMEA · MTL-220 Rev D",                rev:"r3",    type:"FMEA",       classification:"IATF 16949", status:"approved", owner:"M. Schulz",   updated:"2026-03-04" },
  { id:"DOC-MS-051", name:"VDA Band 6.3 · supplier process audit", rev:"r2",  type:"VDA",        classification:"VDA 6.3",    status:"review",   owner:"S. Vogel",    updated:"2026-04-08" },
];

// Resolve the document list for a non-Tritan tenant. Order:
//   1. tenant.documents on the resolved tenant object (rare today; reserved for future)
//   2. window.<TENANT>_TENANT.documents (fixtures-space.jsx wires this for Aetherion)
//   3. tenant-specific hardcoded set (MITTELSTAND_DOCS)
//   4. empty array — never the generic OAM DOCS leak
function resolveDocsForTenant(tenant) {
  if (!tenant || !tenant.tenant) return [];
  const tid = tenant.tenant.id;
  // 1. Direct
  if (Array.isArray(tenant.documents) && tenant.documents.length) {
    return tenant.documents.map(normalizeTenantDoc).filter(Boolean);
  }
  // 2. Window fixture global (active-tenant.jsx doesn't currently pick documents)
  if (typeof window !== "undefined") {
    if (tid === "aetherion" && window.AETHERION_TENANT && Array.isArray(window.AETHERION_TENANT.documents)) {
      return window.AETHERION_TENANT.documents.map(normalizeTenantDoc).filter(Boolean);
    }
    if (tid === "mittelstand" && window.MITTELSTAND_TENANT && Array.isArray(window.MITTELSTAND_TENANT.documents)) {
      return window.MITTELSTAND_TENANT.documents.map(normalizeTenantDoc).filter(Boolean);
    }
  }
  // 3. Tenant-specific hardcoded set
  if (tid === "mittelstand") return MITTELSTAND_DOCS.map(normalizeTenantDoc).filter(Boolean);
  // 4. Empty — explicit, no OAM leak
  return [];
}

// ────────────────────────────── DOCUMENTS ─────────────────────────────────
function ScreenDocuments() {
  const tenant = useActiveTenant();
  const isTritan = !!(tenant && tenant.tenant && tenant.tenant.id === "tritan");
  if (isTritan) {
    return <ScreenDocumentsTritan tenant={tenant}/>;
  }
  const sourceDocs = resolveDocsForTenant(tenant);
  // Guard: if no docs resolved (e.g. unknown tenant), render a small empty panel
  // rather than crash the cell renderers below or fall back to generic DOCS.
  if (!sourceDocs.length) {
    const tenantName = (tenant && tenant.tenant && tenant.tenant.name) || "this tenant";
    return (
      <div style={{ padding: 14, height: "100%", display: "grid", placeItems: "center" }}>
        <Panel title="Documents" style={{ minWidth: 360, maxWidth: 520 }}>
          <div style={{ padding: 28, textAlign: "center" }}>
            <div className="serif" style={{ fontSize: 18, lineHeight: 1.2, marginBottom: 8 }}>
              No documents loaded for {tenantName}
            </div>
            <div className="muted" style={{ fontSize: 12 }}>
              Upload approved drawings, certs and procedures to seed the registry.
            </div>
          </div>
        </Panel>
      </div>
    );
  }
  const [sel, setSel] = uS5(sourceDocs[0] ? sourceDocs[0].id : "DOC-001");
  const [search, setSearch] = uS5("");

  const doc = sourceDocs.find(d => d.id === sel) || sourceDocs[0];
  const toneForStatus = s => s === "approved" ? "ok" : s === "review" ? "warn" : s === "draft" ? "info" : "accent";

  const filtered = sourceDocs.filter(d =>
    !search || (d.name || "").toLowerCase().includes(search.toLowerCase()) || (d.type || "").includes(search.toUpperCase())
  );

  return (
    <div style={{ padding:14, display:"grid", gridTemplateColumns:"1fr 300px", gap:14, height:"100%", minHeight:0 }}>
      <Panel title="Document Registry" right={
        <>
          <div style={{ position:"relative" }}>
            {(() => {
              const _docSearchStyle = { background:"var(--bg-2)", border:"1px solid var(--line)", borderRadius:4, padding:"3px 8px 3px 24px",
                color:"var(--ink)", fontFamily:"var(--font-mono)", fontSize: 12, width:160 };
              return (
                <input id="docs-search" name="docs-search" aria-label="Search documents" value={search} onChange={e=>setSearch(e.target.value)} placeholder="Search docs…" style={_docSearchStyle}/>
              );
            })()}
            <span style={{ position:"absolute", left:7, top:"50%", transform:"translateY(-50%)", color:"var(--ink-4)" }}>{I("Search",{size:12})}</span>
          </div>
          <Btn size="sm" icon="Plus" onClick={() => window.forgeToast && window.forgeToast({ msg: "Document upload queued — v2", kind: "info" })}>Upload</Btn>
        </>
      }>
        <table className="dtable">
          <thead><tr><th>ID</th><th>Document</th><th>Type</th><th>Rev</th><th>Owner</th><th>Updated</th><th>Status</th></tr></thead>
          <tbody>
            {filtered.map(d => (
              <tr key={d.id} onClick={()=>setSel(d.id)} className={sel===d.id?"selected":""} style={{ cursor:"pointer" }}>
                <td className="mono">{d.id}</td>
                <td style={{ color:"var(--ink)" }}>
                  <span>{d.name}</span>
                  {d.itar ? (
                    <span className="pill err" style={{ marginLeft: 6, fontSize: 10, padding: "1px 5px" }}>ITAR</span>
                  ) : null}
                  {(!d.itar && d.classification && d.classification !== d.type) ? (
                    <span className="pill" style={{ marginLeft: 6, fontSize: 10, padding: "1px 5px", color: "var(--ink-3)" }}>{d.classification}</span>
                  ) : null}
                </td>
                <td><Tag>{d.type}</Tag></td>
                <td>{d.rev}</td>
                <td>{(d.owner || "—").split(" ")[0]}</td>
                <td className="tnum">{(window.forgeI18n && window.forgeI18n.formatDate && /^\d{4}-\d{2}-\d{2}$/.test(d.updated) && window.forgeI18n.formatDate(d.updated)) || d.updated}</td>
                <td><Pill tone={toneForStatus(d.status)} dot={false}>{d.status}</Pill></td>
              </tr>
            ))}
          </tbody>
        </table>
      </Panel>

      <div style={{ display:"flex", flexDirection:"column", gap:14, minHeight:0 }}>
        {doc && (
          <>
            <Panel title={`${doc.id} · Detail`}>
              <div style={{ padding:12 }}>
                <div className="serif" style={{ fontSize:17, lineHeight:1.2 }}>{doc.name}</div>
                <div className="muted mono" style={{ fontSize: 12, marginTop:2 }}>Rev {doc.rev} · {doc.type}</div>
                <div className="hr"/>
                {[["Owner",doc.owner],["Status",doc.status],["Updated",(window.forgeI18n && window.forgeI18n.formatDate && /^\d{4}-\d{2}-\d{2}$/.test(doc.updated) && window.forgeI18n.formatDate(doc.updated)) || doc.updated]].map(([k,v])=>(
                  <div key={k} style={{ display:"grid", gridTemplateColumns:"80px 1fr", gap:8, padding:"3px 0" }}>
                    <span className="label">{k}</span>
                    <span className="mono" style={{ fontSize: 12, color:"var(--ink-2)" }}>{v}</span>
                  </div>
                ))}
                <div className="hr"/>
                <div className="label" style={{ marginBottom:6 }}>Actions</div>
                <div style={{ display:"flex", gap:6 }}>
                  <Btn size="sm" variant="primary" icon="Eye" onClick={() => window.forgeToast && window.forgeToast({ msg: "Document viewer queued — v2 · " + doc.id, kind: "info" })}>View</Btn>
                  <Btn size="sm" icon="ArrowD" onClick={() => window.forgeToast && window.forgeToast({ msg: "Download queued — v2 · " + doc.id, kind: "info" })}>Download</Btn>
                  <Btn size="sm" icon="Check" onClick={() => {
                    var _q = function (err) { return err && (err.status === 404 || err.status === 400); };
                    if (window.forgeApi && typeof window.forgeApi.mutate === "function") {
                      window.forgeApi.mutate("documents", { op: "replace", path: "/" + encodeURIComponent(doc.id) + "/status", value: "approved" })
                        .then(function () { window.forgeToast && window.forgeToast("Document approved · " + doc.id); })
                        .catch(function (err) { window.forgeToast && window.forgeToast(_q(err) ? "Approval queued · " + doc.id : "Approve failed · " + (err && err.message || "unknown")); });
                    } else {
                      window.forgeToast && window.forgeToast("Approval queued · " + doc.id);
                    }
                  }}>Approve</Btn>
                </div>
              </div>
            </Panel>

            <Panel title="Revision History">
              <table className="dtable">
                <thead><tr><th>Rev</th><th>Author</th><th>Date</th><th>Note</th></tr></thead>
                <tbody>
                  {"ABCDEF".split("").slice(0, doc.rev.charCodeAt(0) - 64).reverse().map((r, i) => (
                    <tr key={r}>
                      <td>{r}</td>
                      <td>{doc.owner.split(" ")[0]}</td>
                      <td className="tnum">2026-0{4-i}-{String(10+i*5).padStart(2,"0")}</td>
                      <td>{i===0?"Current release":i===1?"Minor corrections":"Initial draft"}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </Panel>

            <Panel title="Approval Workflow">
              <div style={{ padding:10 }}>
                {["Author","Reviewer","Approver","Release"].map((stage, i) => {
                  const done = doc.status === "approved" || i < (doc.status === "review" ? 2 : 1);
                  const active = (!done && i === (doc.status === "review" ? 2 : 1));
                  return (
                    <div key={stage} style={{ display:"grid", gridTemplateColumns:"20px 1fr auto", gap:8, padding:"6px 0",
                      borderBottom:"1px solid var(--line-soft)", alignItems:"center" }}>
                      <div style={{ width:10, height:10, borderRadius:10,
                        background: done?"var(--ok)":active?"var(--accent)":"var(--line-strong)" }}/>
                      <span style={{ fontSize:12 }}>{stage}</span>
                      <Pill tone={done?"ok":active?"accent":""} dot={false}>{done?"Done":active?"Active":"Waiting"}</Pill>
                    </div>
                  );
                })}
              </div>
            </Panel>
          </>
        )}
      </div>
    </div>
  );
}

// ─────────────────────────────── MAINTENANCE ──────────────────────────────
function ScreenMaintenance() {
  const tenant = useActiveTenant();
  const tenantName = (tenant && tenant.tenant && tenant.tenant.name) || "this tenant";
  const isTritan = !!(tenant && tenant.tenant && tenant.tenant.id === "tritan");
  if (isTritan) {
    return <ScreenMaintenanceTritan tenant={tenant}/>;
  }
  // For non-Tritan tenants: read tenant.maintenance if present, else show empty state.
  const tenantMaint = (tenant && tenant.maintenance && tenant.maintenance.length) ? tenant.maintenance : null;
  if (!tenantMaint) {
    return (
      <div style={{ padding: 14, height: "100%", display: "grid", placeItems: "center" }}>
        <Panel title="Maintenance" style={{ minWidth: 360, maxWidth: 520 }}>
          <div style={{ padding: 28, textAlign: "center" }}>
            <div className="serif" style={{ fontSize: 18, lineHeight: 1.2, marginBottom: 8 }}>
              No maintenance schedule loaded for {tenantName}
            </div>
            <div className="muted" style={{ fontSize: 12, marginBottom: 16 }}>
              Load a preset to seed equipment, services, and PM cadence for this program.
            </div>
            <Btn size="sm" variant="primary" icon="ArrowD" onClick={() => window.forgeToast && window.forgeToast("Load preset queued — wired in v2")}>Load preset</Btn>
          </div>
        </Panel>
      </div>
    );
  }
  const dataset = tenantMaint;
  const [sel, setSel] = uS5(dataset[0] ? dataset[0].id : "EQ-01");
  const eq = dataset.find(e => e.id === sel) || dataset[0];

  const daysUntil = (dateStr) => {
    const d = new Date(dateStr);
    const now = new Date("2026-04-25");
    return Math.round((d - now) / 86400000);
  };

  // Wave 4D.2: real Log Service handler — POSTs to /maintenance/log-service
  // and writes an event row. Lightweight prompt-based UX; future waves can
  // promote to a proper modal with date picker + work-order linkage.
  async function handleLogService(eqId) {
    const tech = prompt("Technician name:", "");
    if (!tech) return;
    const notes = prompt("Service notes:", "") || "";
    try {
      await window.forgeApi.maintenance.logService({
        equipment_id: eqId,
        service_date: new Date().toISOString().slice(0, 10),
        technician: tech,
        notes,
      });
      alert("Service logged ✓");
    } catch (e) {
      alert("Failed: " + (e.message || e));
    }
  }

  return (
    <div style={{ padding:14, display:"grid", gridTemplateColumns:"1fr 280px", gap:14, height:"100%", minHeight:0 }}>
      <div style={{ display:"flex", flexDirection:"column", gap:14, minHeight:0 }}>
        <Panel title="Equipment Overview">
          <div style={{ display:"grid", gridTemplateColumns:"repeat(4,1fr)", gap:0 }}>
            {[
              ["Total Equipment","8","info"],
              ["Service Due <30d","2","warn"],
              ["Overdue / Critical","1","err"],
              ["All Calibrated","5","ok"],
            ].map(([k,v,t])=>(
              <div key={k} style={{ padding:"10px 12px", borderRight:"1px solid var(--line-soft)" }}>
                <div className="label" style={{ whiteSpace: "normal", overflow: "visible", textOverflow: "clip", lineHeight: 1.3 }}>{k}</div>
                <div className="mono tnum" style={{ fontSize:20, color:`var(--${t})` }}>{v}</div>
              </div>
            ))}
          </div>
        </Panel>

        <Panel title="Equipment Registry" right={<Btn size="sm" icon="Plus" onClick={() => window.forgeToast && window.forgeToast("Add Equipment queued — wired in v2")}>Add Equipment</Btn>}>
          <table className="dtable">
            <thead><tr><th>ID</th><th>Equipment</th><th>Location</th><th>Last Service</th><th>Next Service</th><th>Days</th><th>Status</th></tr></thead>
            <tbody>
              {dataset.map(e => {
                const days = daysUntil(e.nextService);
                return (
                  <tr key={e.id} onClick={()=>setSel(e.id)} className={sel===e.id?"selected":""} style={{ cursor:"pointer" }}>
                    <td className="mono">{e.id}</td>
                    <td style={{ color:"var(--ink)" }}>{e.name}</td>
                    <td>{e.location}</td>
                    <td className="tnum">{(window.forgeI18n && window.forgeI18n.formatDate && /^\d{4}-\d{2}-\d{2}$/.test(e.lastService) && window.forgeI18n.formatDate(e.lastService)) || e.lastService}</td>
                    <td className="tnum">{(window.forgeI18n && window.forgeI18n.formatDate && /^\d{4}-\d{2}-\d{2}$/.test(e.nextService) && window.forgeI18n.formatDate(e.nextService)) || e.nextService}</td>
                    <td className="tnum" style={{ color: days < 0 ? "var(--err)" : days < 30 ? "var(--warn)" : "var(--ok)" }}>
                      {days < 0 ? `${Math.abs(days)}d overdue` : `${days}d`}
                    </td>
                    <td><Pill tone={e.status} dot={false}>{e.status==="ok"?"NOMINAL":e.status==="warn"?"DUE SOON":"OVERDUE"}</Pill></td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </Panel>
      </div>

      <div style={{ display:"flex", flexDirection:"column", gap:14, minHeight:0 }}>
        {eq && (
          <>
            <Panel title={`${eq.id} · Detail`}>
              <div style={{ padding:12 }}>
                <div className="serif" style={{ fontSize:16, lineHeight:1.2 }}>{eq.name}</div>
                <div className="muted mono" style={{ fontSize: 12, marginTop:2 }}>{eq.location}</div>
                <div className="hr"/>
                {[["Owner",eq.owner],["Last Svc",(window.forgeI18n && window.forgeI18n.formatDate && /^\d{4}-\d{2}-\d{2}$/.test(eq.lastService) && window.forgeI18n.formatDate(eq.lastService)) || eq.lastService],["Next Svc",(window.forgeI18n && window.forgeI18n.formatDate && /^\d{4}-\d{2}-\d{2}$/.test(eq.nextService) && window.forgeI18n.formatDate(eq.nextService)) || eq.nextService]].map(([k,v])=>(
                  <div key={k} style={{ display:"grid", gridTemplateColumns:"80px 1fr", gap:8, padding:"3px 0" }}>
                    <span className="label">{k}</span>
                    <span className="mono" style={{ fontSize: 12, color:"var(--ink-2)" }}>{v}</span>
                  </div>
                ))}
                <div className="hr"/>
                <div style={{ display:"flex", gap:6, flexWrap:"wrap" }}>
                  <Btn size="sm" variant="primary" icon="Check" onClick={() => handleLogService(eq.id)}>Log Service</Btn>
                  <Btn size="sm" icon="Calendar" onClick={() => window.forgeToast && window.forgeToast("Schedule queued — wired in v2")}>Schedule</Btn>
                  <Btn size="sm" icon="File" onClick={() => window.forgeToast && window.forgeToast("Work Order queued — wired in v2")}>Work Order</Btn>
                </div>
              </div>
            </Panel>
            <Panel title="Service History">
              <div style={{ padding:10 }}>
                {[["2026","Calibration — passed","ok"],["2025-09","Preventive — oil change","ok"],["2025-03","Corrective — sensor replaced","warn"]].map(([d,n,t])=>(
                  <div key={d} style={{ display:"grid", gridTemplateColumns:"60px 1fr auto", gap:8, padding:"6px 0", borderBottom:"1px solid var(--line-soft)", alignItems:"center" }}>
                    <span className="mono tnum" style={{ fontSize: 12, color:"var(--ink-3)" }}>{d}</span>
                    <span style={{ fontSize:12 }}>{n}</span>
                    <Pill tone={t} dot={false}>{t}</Pill>
                  </div>
                ))}
              </div>
            </Panel>
          </>
        )}
        <Panel title="Upcoming Services">
          <div style={{ padding:10 }}>
            {dataset.filter(e => e.status !== "ok" || daysUntil(e.nextService) < 60)
              .sort((a,b) => Date.parse(a.nextService) - Date.parse(b.nextService))
              .slice(0,5)
              .map(e => {
                const days = daysUntil(e.nextService);
                return (
                  <div key={e.id} style={{ display:"grid", gridTemplateColumns:"1fr auto", gap:8, padding:"6px 0", borderBottom:"1px solid var(--line-soft)" }}>
                    <div>
                      <div style={{ fontSize:12, color:"var(--ink)" }}>{e.name}</div>
                      <div className="muted mono" style={{ fontSize: 12 }}>{(window.forgeI18n && window.forgeI18n.formatDate && /^\d{4}-\d{2}-\d{2}$/.test(e.nextService) && window.forgeI18n.formatDate(e.nextService)) || e.nextService}</div>
                    </div>
                    <Pill tone={days < 0 ? "err" : days < 30 ? "warn" : "ok"} dot={false}>
                      {days < 0 ? "OVERDUE" : `${days}d`}
                    </Pill>
                  </div>
                );
              })}
          </div>
        </Panel>
      </div>
    </div>
  );
}

// ─────────────────────────────── INTEGRATIONS ─────────────────────────────
function ScreenIntegrations() {
  const tenant = useActiveTenant();
  const tenantId = (tenant && tenant.tenant && tenant.tenant.id) || "tritan";
  // Per-tenant integration stack — see data.jsx#getIntegrationsFor.
  const integrations = (typeof getIntegrationsFor === "function")
    ? getIntegrationsFor(tenantId)
    : INTEGRATIONS;
  const [sel, setSel] = uS5(integrations[0] ? integrations[0].id : "INT-SAP");
  const integ = integrations.find(x => x.id === sel) || integrations[0];

  const typeColor = t => {
    if (t === "ERP" || t === "SCM") return "var(--accent)";
    if (t === "CAE" || t === "CAD") return "var(--cool)";
    if (t === "TASKS" || t === "DOCS") return "var(--info)";
    return "var(--ok)";
  };

  // ── Sync / Configure / Logs wiring (W12B · optimistic UI, no backend) ──
  // Toast with a single shared timer so back-to-back flashes don't clobber.
  const [toast, setToast] = uS5("");
  const toastTimer = uR5(null);
  const flash = (msg) => {
    setToast(msg);
    if (toastTimer.current) clearTimeout(toastTimer.current);
    toastTimer.current = setTimeout(() => setToast(""), 1800);
  };
  // syncing[id] === true → button shows spinner state.
  // lastSyncOverride[id] = "just now" → table + detail panel render this in
  // place of the seed value.
  const [syncing, setSyncing]                 = uS5({});
  const [lastSyncOverride, setLastSyncOverride] = uS5({});
  // Modal: { kind: "config" | "logs", connector }. null = hidden.
  const [modal, setModal] = uS5(null);

  // Field mappings shared by the right-pane panel and the Configure modal.
  const FIELD_MAPPINGS = [
    ["part_number","item_number","ok"],
    ["description","description","ok"],
    ["revision","eng_rev","ok"],
    ["uom","unit_of_measure","warn"],
    ["cost_center","cost_element","warn"],
  ];

  // Synthesize ~10 plausible log lines for the Logs modal.
  const buildLogs = (c) => {
    if (!c) return [];
    const now = new Date();
    const pad = (n) => String(n).padStart(2, "0");
    const stamp = (m) => {
      const d = new Date(now.getTime() - m * 60000);
      return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
    };
    return [
      [stamp(2),   "info", `sync ok · ${c.records || "—"} records pulled`],
      [stamp(6),   "info", `heartbeat · latency ${c.latency || "—"}`],
      [stamp(14),  "info", `field-map applied · 5 mappings, 0 conflicts`],
      [stamp(23),  "warn", `uom mapping fallback · "EA" → "each" (1 row)`],
      [stamp(31),  "info", `auth refreshed · token rotated`],
      [stamp(47),  "info", `sync ok · 47 records pulled`],
      [stamp(62),  "info", `${c.id || c.name} connector reachable · TLS 1.3`],
      [stamp(118), "warn", `cost_center mapping fallback · 2 rows`],
      [stamp(214), "info", `sync ok · 12 records pulled`],
      [stamp(340), "info", `scheduled cron tick · pulled delta`],
    ];
  };

  const onSync = (c) => {
    if (!c || syncing[c.id]) return;
    setSyncing(s => ({ ...s, [c.id]: true }));
    setLastSyncOverride(o => ({ ...o, [c.id]: "just now" }));
    flash(`Syncing ${c.name}…`);
    setTimeout(() => {
      setSyncing(s => ({ ...s, [c.id]: false }));
      flash(`✓ Synced ${c.records || "—"} · ${c.latency || "—"}`);
    }, 1500);
  };
  const onConfigure = (c) => { if (c) setModal({ kind: "config", connector: c }); };
  const onLogs      = (c) => { if (c) setModal({ kind: "logs",   connector: c }); };

  const isSyncing = integ ? !!syncing[integ.id] : false;

  return (
    <div style={{ padding:14, display:"grid", gridTemplateColumns:"1fr 300px", gap:14, height:"100%", minHeight:0 }}>
      <div style={{ display:"flex", flexDirection:"column", gap:14, minHeight:0 }}>
        {/* flow diagram */}
        <Panel title="Forge · Integration Hub">
          <div style={{ padding:10, overflow:"auto" }}>
            <svg width="700" height="160" viewBox="0 0 700 160">
              {/* center hub */}
              <rect x="280" y="56" width="140" height="48" rx="6" fill="var(--bg-2)" stroke="var(--accent)" strokeWidth="2"/>
              <text x="350" y="78" textAnchor="middle" fontSize="13" fontFamily="var(--font-ui)" fontWeight="600" fill="var(--ink)">FORGE</text>
              <text x="350" y="96" textAnchor="middle" fontSize="10" fontFamily="var(--font-mono)" fill="var(--ink-3)">lattice · 5 modes · FCP</text>
              <circle cx="282" cy="66" r="4" fill="var(--accent)" className="pulse"/>
              {/* spokes */}
              {(function() {
                // Derive spoke labels from the active tenant's integration stack.
                const slots = [
                  [80,  30,  "var(--accent)"],
                  [180, 140, "var(--accent)"],
                  [280, 148, "var(--cool)"  ],
                  [420, 148, "var(--cool)"  ],
                  [520, 140, "var(--info)"  ],
                  [620, 30,  "var(--ok)"    ],
                ];
                const labels = integrations.slice(0, slots.length).map(function(it) {
                  const parts = (it.name || "").split(" ");
                  return parts.length > 1 ? parts.slice(0, 2).join("\n") : (it.name || "—");
                });
                return slots.slice(0, labels.length).map(function(s, i) { return [s[0], s[1], labels[i], s[2]]; });
              })().map(([x, y, lbl, c]) => {
                const lines = lbl.split("\n");
                return (
                  <g key={lbl}>
                    <line x1={350} y1={80} x2={x} y2={y+20} stroke={c} strokeWidth="1" strokeDasharray="4,3" opacity="0.6"/>
                    <circle cx={x} cy={y+20} r="3" fill={c}/>
                    <rect x={x - 32} y={y - 4} width={64} height={34} rx="4" fill="var(--bg-2)" stroke={c} strokeWidth="1"/>
                    {lines.map((l, li) => (
                      <text key={l} x={x} y={y + 8 + li * 14} textAnchor="middle" fontSize="10" fontFamily="var(--font-mono)" fill="var(--ink-2)">{l}</text>
                    ))}
                  </g>
                );
              })}
            </svg>
          </div>
        </Panel>

        {/* connectors table */}
        <Panel title="Connectors" right={<Btn size="sm" icon="Plus" onClick={() => window.forgeToast && window.forgeToast("Add Connector queued — wired in v2")}>Add Connector</Btn>}>
          <table className="dtable">
            <thead><tr><th>System</th><th>Type</th><th>Status</th><th>Last Sync</th><th>Records</th><th>Latency</th></tr></thead>
            <tbody>
              {integrations.map(x => (
                <tr key={x.id} onClick={()=>setSel(x.id)} className={sel===x.id?"selected":""} style={{ cursor:"pointer" }}>
                  <td style={{ color:"var(--ink)", fontWeight:500 }}>{x.name}</td>
                  <td><Tag>{x.type}</Tag></td>
                  <td>
                    <span className={`pill ${x.status === "connected" ? "ok" : "warn"}`}>
                      <span className={`dot ${x.status === "connected" ? "pulse" : ""}`}/>
                      {x.status}
                    </span>
                  </td>
                  <td className="tnum">{lastSyncOverride[x.id] || x.lastSync}</td>
                  <td className="tnum">{x.records}</td>
                  <td className="tnum" style={{ color: x.latency === "timeout" ? "var(--err)" : "var(--ok)" }}>{x.latency}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </Panel>
      </div>

      {/* detail panel */}
      <div style={{ display:"flex", flexDirection:"column", gap:14, minHeight:0 }}>
        {integ && (
          <>
            <Panel title={`${integ.id} · Config`}>
              <div style={{ padding:12 }}>
                <div className="serif" style={{ fontSize:18 }}>{integ.name}</div>
                <div className="muted mono" style={{ fontSize: 12, marginTop:2 }}>{integ.type}</div>
                <div className="hr"/>
                {[["Status",integ.status],["Last Sync", lastSyncOverride[integ.id] || integ.lastSync],["Records",integ.records],["Latency",integ.latency]].map(([k,v])=>(
                  <div key={k} style={{ display:"grid", gridTemplateColumns:"80px 1fr", gap:8, padding:"3px 0" }}>
                    <span className="label">{k}</span>
                    <span className="mono" style={{ fontSize: 12, color:"var(--ink-2)" }}>{v}</span>
                  </div>
                ))}
                <div className="hr"/>
                <div style={{ display:"flex", gap:6, flexWrap:"wrap", alignItems:"center" }}>
                  <Btn size="sm" variant="primary"
                       icon={isSyncing ? "Clock" : "Plug"}
                       onClick={isSyncing ? undefined : () => onSync(integ)}>
                    {isSyncing ? "Syncing…" : "Sync Now"}
                  </Btn>
                  <Btn size="sm" icon="Gear" onClick={() => onConfigure(integ)}>Configure</Btn>
                  <Btn size="sm" icon="Eye"  onClick={() => onLogs(integ)}>Logs</Btn>
                  <Tag>demo</Tag>
                </div>
                {toast && (
                  <div className="mono" style={{ marginTop:10, padding:"6px 8px", borderRadius:4,
                    background:"var(--bg-2)", border:"1px solid var(--accent)", color:"var(--accent)", fontSize: 12 }}>
                    {toast}
                  </div>
                )}
              </div>
            </Panel>

            <Panel title="Data Flow Metrics">
              <div style={{ padding:12 }}>
                <Spark data={[88,91,87,93,95,90,88,92,96,93,97,95,88,94]} height={44} stroke={typeColor(integ.type)}/>
                <div style={{ display:"flex", justifyContent:"space-between", marginTop:8 }}>
                  <div><div className="label">Uptime 30d</div><div className="mono tnum" style={{ fontSize:16 }}>99.4%</div></div>
                  <div><div className="label">Errors 24h</div><div className="mono tnum" style={{ fontSize:16, color: integ.status==="warn"?"var(--err)":"var(--ok)" }}>{integ.status==="warn"?"3":"0"}</div></div>
                </div>
              </div>
            </Panel>

            <Panel title="Field Mappings">
              <div style={{ padding:10 }}>
                {FIELD_MAPPINGS.map(([l,r,t])=>(
                  <div key={l} style={{ display:"grid", gridTemplateColumns:"1fr 16px 1fr auto", gap:6, padding:"4px 0", borderBottom:"1px solid var(--line-soft)", alignItems:"center" }}>
                    <span className="mono" style={{ fontSize: 12 }}>{l}</span>
                    <span className="dim" style={{ textAlign:"center" }}>→</span>
                    <span className="mono" style={{ fontSize: 12 }}>{r}</span>
                    <span style={{ width:6, height:6, borderRadius:6, background:`var(--${t})`, display:"inline-block" }}/>
                  </div>
                ))}
              </div>
            </Panel>
          </>
        )}
      </div>

      {modal && modal.connector && (
        <div onClick={() => setModal(null)} style={{
          position:"fixed", inset:0, background:"rgba(0,0,0,0.45)", zIndex:50,
          display:"flex", alignItems:"center", justifyContent:"center",
        }}>
          <div onClick={(ev) => ev.stopPropagation()} style={{
            width: modal.kind === "logs" ? 640 : 520, maxHeight:"82vh", overflow:"auto",
            background:"var(--bg-1)", border:"1px solid var(--line-strong)", borderRadius:8, padding:18,
          }}>
            <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:10 }}>
              <div className="serif" style={{ fontSize:20 }}>
                {modal.kind === "config"
                  ? `Configure · ${modal.connector.name}`
                  : `Logs · ${modal.connector.name}`}
              </div>
              <Btn size="sm" onClick={() => setModal(null)}>Close</Btn>
            </div>
            <div className="muted mono" style={{ fontSize:12, marginBottom:10 }}>
              {modal.connector.id} · {modal.connector.type} · read-only
            </div>
            {modal.kind === "config" ? (
              <div>
                <div className="label" style={{ marginBottom:6 }}>Field Mappings</div>
                {FIELD_MAPPINGS.map(([l,r,t]) => (
                  <div key={l} style={{ display:"grid", gridTemplateColumns:"1fr 16px 1fr auto",
                    gap:6, padding:"6px 0", borderBottom:"1px solid var(--line-soft)", alignItems:"center" }}>
                    <span className="mono" style={{ fontSize:12 }}>{l}</span>
                    <span className="dim" style={{ textAlign:"center" }}>→</span>
                    <span className="mono" style={{ fontSize:12 }}>{r}</span>
                    <span style={{ width:8, height:8, borderRadius:8, background:`var(--${t})`, display:"inline-block" }}/>
                  </div>
                ))}
                <div className="muted mono" style={{ fontSize:11, marginTop:10 }}>
                  Editing mappings is disabled in this demo build.
                </div>
              </div>
            ) : (
              <pre style={{ margin:0, padding:12, background:"var(--bg-2)",
                border:"1px solid var(--line-soft)", borderRadius:4,
                fontFamily:"var(--font-mono)", fontSize:12, color:"var(--ink-2)",
                whiteSpace:"pre-wrap", maxHeight:420, overflow:"auto" }}>
{buildLogs(modal.connector).map(([ts, level, msg]) =>
  `[${ts}] ${level.padEnd(4)} ${msg}`
).join("\n")}
              </pre>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

// ─────────────────────────── DOCUMENTS · TRITAN ───────────────────────────
function ScreenDocumentsTritan({ tenant }) {
  const tenantName = (tenant && tenant.tenant && tenant.tenant.name) || "Tritan";
  const DOCS_T = [
    { id:"DOC-T01", name:"M-27418 Engineering BOM (rev B)",                  type:"BOM",  rev:"B", owner:"Devansh A.", updated:"2026-04-22", status:"approved", linked:"WO-44219 · 47 line items" },
    { id:"DOC-T02", name:"M-27418 Routing & Quality Plan (7 stations)",      type:"WI",   rev:"B", owner:"Meera S.",   updated:"2026-04-19", status:"approved", linked:"WO-44219 · QG-01..30" },
    { id:"DOC-T03", name:"DRG-M27418-PMP-rev-B (impeller W42-22-2.0)",       type:"DRG",  rev:"B", owner:"Devansh A.", updated:"2026-04-15", status:"approved", linked:"BOM-M27418 · L-08" },
    { id:"DOC-T04", name:"DRG-M27418-MOT-rev-A (rotor SS410 Ø17.98)",        type:"DRG",  rev:"A", owner:"Devansh A.", updated:"2026-04-12", status:"approved", linked:"BOM-M27418 · L-22" },
    { id:"DOC-T05", name:"ECO-0051 packet · NRV C.I.→S.G.-400",              type:"ECO",  rev:"-", owner:"Ishaan R.",  updated:"2026-04-25", status:"review",   linked:"WO-44219 · stage-A short" },
    { id:"DOC-T06", name:"ECO-0042 packet · V5→V4 carryover",                type:"ECO",  rev:"A", owner:"Devansh A.", updated:"2026-03-30", status:"approved", linked:"M-27418 release" },
    { id:"DOC-T07", name:"30-point CTQ Quality Plan QG-01..30",              type:"QP",   rev:"C", owner:"Priya I.",   updated:"2026-04-08", status:"approved", linked:"WI rev B · FMEA rev B" },
    { id:"DOC-T08", name:"PFMEA · M-27418 (12 modes, RPN scored)",           type:"FMEA", rev:"B", owner:"Priya I.",   updated:"2026-04-10", status:"approved", linked:"QG-12,17,24" },
    { id:"DOC-T09", name:"VQP 2.0 vendor questionnaire (334 items)",         type:"VQP",  rev:"2", owner:"Priya I.",   updated:"2026-03-12", status:"approved", linked:"Spire · Helios · Bharat" },
    { id:"DOC-T10", name:"Spire Foundry audit report · 87% conditional",     type:"AUD",  rev:"-", owner:"Priya I.",   updated:"2026-03-12", status:"review",   linked:"VQP-Spire-2026-03" },
    { id:"DOC-T11", name:"BEE Schedule 7 self-declaration · 3-star",         type:"CERT", rev:"1", owner:"Ishaan R.",  updated:"2026-04-01", status:"approved", linked:"M-27418 · IS:8034" },
    { id:"DOC-T12", name:"IS:8034 conformity certificate · M-27418",         type:"CERT", rev:"-", owner:"Ishaan R.",  updated:"2026-04-01", status:"approved", linked:"BEE Sched-7" },
    { id:"DOC-T13", name:"Helios AgriFlow private-label artwork · cartons",  type:"ART",  rev:"B", owner:"Karan V.",   updated:"2026-04-18", status:"approved", linked:"PO-AGR-2026-117" },
    { id:"DOC-T14", name:"Q-H performance test SOP",                         type:"SOP",  rev:"D", owner:"Neha G.",    updated:"2026-03-25", status:"draft",    linked:"QG-27 · TPX-rig" },
  ];

  const [sel, setSel] = uS5("DOC-T05");
  const [search, setSearch] = uS5("");
  const [toast, setToast] = uS5("");
  const doc = DOCS_T.find(d => d.id === sel) || DOCS_T[0];

  const flash = (msg) => { setToast(msg); setTimeout(() => setToast(""), 1800); };

  const toneForStatus = s => s === "approved" ? "ok" : s === "review" ? "warn" : s === "draft" ? "info" : "accent";
  const filtered = DOCS_T.filter(d =>
    !search || d.name.toLowerCase().includes(search.toLowerCase()) || d.type.toLowerCase().includes(search.toLowerCase()) || d.owner.toLowerCase().includes(search.toLowerCase())
  );

  // Synthesize per-doc revision history. Each rev letter / digit indicates one prior cycle.
  const revHistory = (function() {
    const r = doc.rev;
    if (r === "-" || r === "1") {
      return [["1", doc.owner.split(" ")[0], doc.updated, "Initial draft"]];
    }
    const isAlpha = /[A-Z]/.test(r);
    const max = isAlpha ? (r.charCodeAt(0) - 64) : parseInt(r, 10);
    const labels = ["Initial draft","Internal review fixes","Spec corrections","Customer redline","Current release"];
    const out = [];
    for (let i = max; i >= 1; i--) {
      const letter = isAlpha ? String.fromCharCode(64 + i) : String(i);
      const note = i === max ? "Current release" : i === max - 1 ? "Minor corrections" : labels[Math.min(i-1, labels.length-1)];
      const m = String(Math.max(1, 5 - (max - i))).padStart(2, "0");
      const dd = String(8 + (max - i) * 5).padStart(2, "0");
      out.push([letter, doc.owner.split(" ")[0], `2026-${m}-${dd}`, note]);
    }
    return out;
  })();

  // Approval workflow state derived from doc.status.
  const stages = ["Author","Reviewer","Approver","Release"];
  const stageIdx = doc.status === "approved" ? 4 : doc.status === "review" ? 2 : doc.status === "draft" ? 1 : 0;

  // Top KPI strip values. Counts via forgeI18n.formatNumber (en-IN 2-2-3
  // for tritan etc.), date strip via forgeI18n.formatDate (locale's native
  // separator and order). Both gracefully fall back when forgeI18n hasn't
  // bootstrapped yet.
  const _fmtN_doc = function (n) {
    return (window.forgeI18n && window.forgeI18n.formatNumber)
      ? window.forgeI18n.formatNumber(n)
      : String(n);
  };
  const _fmtD_doc = function (iso) {
    return (window.forgeI18n && window.forgeI18n.formatDate)
      ? window.forgeI18n.formatDate(iso)
      : iso;
  };
  const kpis = [
    ["Total Docs",  _fmtN_doc(DOCS_T.length),                                          "info"],
    ["Approved",    _fmtN_doc(DOCS_T.filter(d => d.status === "approved").length),     "ok"],
    ["In Review",   _fmtN_doc(DOCS_T.filter(d => d.status === "review").length),       "warn"],
    ["Drafts",      _fmtN_doc(DOCS_T.filter(d => d.status === "draft").length),        "info"],
    ["Owners",      _fmtN_doc(new Set(DOCS_T.map(d => d.owner)).size),                 "accent"],
    ["Latest Edit", _fmtD_doc("2026-04-25"),                                           "info"],
  ];

  return (
    <div style={{ padding:14, display:"grid", gridTemplateColumns:"1fr 320px", gridTemplateRows:"auto 1fr", gap:14, height:"100%", minHeight:0 }}>

      {/* KPI strip */}
      <Panel title={tenantName + " · Document Control"} style={{ gridColumn:"1/-1" }}>
        <div style={{ display:"grid", gridTemplateColumns:"repeat(6,1fr)" }}>
          {kpis.map(([k,v,t]) => (
            <div key={k} style={{ padding:"10px 12px", borderRight:"1px solid var(--line-soft)" }}>
              <div className="label" style={{ whiteSpace: "normal", overflow: "visible", textOverflow: "clip", lineHeight: 1.3 }}>{k}</div>
              <div className="mono tnum" style={{ fontSize:20, color:`var(--${t})` }}>{v}</div>
            </div>
          ))}
        </div>
      </Panel>

      {/* registry */}
      <Panel title="Document Registry" right={
        <>
          <div style={{ position:"relative" }}>
            {(() => {
              const _docSearch2Style = { background:"var(--bg-2)", border:"1px solid var(--line)", borderRadius:4, padding:"3px 8px 3px 24px",
                color:"var(--ink)", fontFamily:"var(--font-mono)", fontSize: 12, width:200 };
              return (
                <input id="docs-search-tritan" name="docs-search-tritan" aria-label="Search documents by name, type, or owner" value={search} onChange={e=>setSearch(e.target.value)} placeholder="Search · name / type / owner" style={_docSearch2Style}/>
              );
            })()}
            <span style={{ position:"absolute", left:7, top:"50%", transform:"translateY(-50%)", color:"var(--ink-4)" }}>{I("Search",{size:12})}</span>
          </div>
          <Btn size="sm" icon="Plus" onClick={()=>flash("Upload dialog · drag a file here")}>Upload</Btn>
        </>
      }>
        <table className="dtable">
          <thead><tr><th>ID</th><th>Document</th><th>Type</th><th>Rev</th><th>Owner</th><th>Updated</th><th>Status</th></tr></thead>
          <tbody>
            {filtered.map(d => (
              <tr key={d.id} onClick={()=>setSel(d.id)} className={sel===d.id?"selected":""} style={{ cursor:"pointer" }}>
                <td className="mono">{d.id}</td>
                <td style={{ color:"var(--ink)" }}>{d.name}</td>
                <td><Tag>{d.type}</Tag></td>
                <td className="mono tnum">{d.rev}</td>
                <td>{d.owner.split(" ")[0]}</td>
                <td className="tnum">{(window.forgeI18n && window.forgeI18n.formatDate && /^\d{4}-\d{2}-\d{2}$/.test(d.updated) && window.forgeI18n.formatDate(d.updated)) || d.updated}</td>
                <td><Pill tone={toneForStatus(d.status)} dot={false}>{d.status}</Pill></td>
              </tr>
            ))}
            {filtered.length === 0 && (
              <tr><td colSpan={7} style={{ padding:14, textAlign:"center", color:"var(--ink-3)", fontSize: 12 }}>No documents match "{search}"</td></tr>
            )}
          </tbody>
        </table>
      </Panel>

      {/* right column */}
      <div style={{ display:"flex", flexDirection:"column", gap:14, minHeight:0, overflowY:"auto" }}>
        <Panel title={`${doc.id} · Detail`}>
          <div style={{ padding:12 }}>
            <div className="serif" style={{ fontSize:16, lineHeight:1.2 }}>{doc.name}</div>
            <div className="muted mono" style={{ fontSize: 12, marginTop:2 }}>Rev {doc.rev} · {doc.type}</div>
            <div className="hr"/>
            {[["Owner",doc.owner],["Status",doc.status],["Updated",doc.updated],["Linked-to",doc.linked]].map(([k,v])=>(
              <div key={k} style={{ display:"grid", gridTemplateColumns:"80px 1fr", gap:8, padding:"3px 0" }}>
                <span className="label">{k}</span>
                <span className="mono" style={{ fontSize: 12, color:"var(--ink-2)" }}>{v}</span>
              </div>
            ))}
            <div className="hr"/>
            <div className="label" style={{ marginBottom:6 }}>Actions</div>
            <div style={{ display:"flex", gap:6, flexWrap:"wrap" }}>
              <Btn size="sm" variant="primary" icon="Eye" onClick={()=>flash(`Opening ${doc.id} preview…`)}>View</Btn>
              <Btn size="sm" icon="ArrowD" onClick={()=>flash(`Downloading ${doc.id} (rev ${doc.rev})…`)}>Download</Btn>
              <Btn size="sm" icon="Check" onClick={()=>flash(`Approval queued for ${doc.id}`)}>Approve</Btn>
            </div>
            {toast && (
              <div className="mono" style={{ marginTop:10, padding:"6px 8px", borderRadius:4, background:"var(--bg-2)", border:"1px solid var(--accent)", color:"var(--accent)", fontSize: 12 }}>
                {toast}
              </div>
            )}
          </div>
        </Panel>

        <Panel title="Revision History">
          <table className="dtable">
            <thead><tr><th>Rev</th><th>Author</th><th>Date</th><th>Note</th></tr></thead>
            <tbody>
              {revHistory.map(([r,a,d,n]) => (
                <tr key={r}>
                  <td className="mono tnum">{r}</td>
                  <td>{a}</td>
                  <td className="tnum">{d}</td>
                  <td style={{ fontSize: 12 }}>{n}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </Panel>

        <Panel title="Approval Workflow">
          <div style={{ padding:10 }}>
            {stages.map((stage, i) => {
              const done   = i < stageIdx;
              const active = i === stageIdx && stageIdx < stages.length;
              const who = ["Devansh A.","Priya I.","Ishaan R.","Doc Control"][i];
              return (
                <div key={stage} style={{ display:"grid", gridTemplateColumns:"20px 1fr auto", gap:8, padding:"6px 0",
                  borderBottom:"1px solid var(--line-soft)", alignItems:"center" }}>
                  <div style={{ width:10, height:10, borderRadius:10,
                    background: done?"var(--ok)":active?"var(--accent)":"var(--line-strong)" }}/>
                  <div>
                    <div style={{ fontSize:12 }}>{stage}</div>
                    <div className="muted mono" style={{ fontSize: 12 }}>{who}</div>
                  </div>
                  <Pill tone={done?"ok":active?"accent":""} dot={false}>{done?"Done":active?"Active":"Waiting"}</Pill>
                </div>
              );
            })}
            <div className="muted mono" style={{ fontSize: 12, marginTop:8 }}>
              Doc-control gate · {stageIdx === stages.length ? "released to manufacturing" : `${stageIdx}/${stages.length} stages cleared`}
            </div>
          </div>
        </Panel>
      </div>
    </div>
  );
}

// ────────────────────────── MAINTENANCE · TRITAN ──────────────────────────
function ScreenMaintenanceTritan({ tenant }) {
  const tenantName = (tenant && tenant.tenant && tenant.tenant.name) || "Tritan";
  const EQUIP_T = [
    { id:"EQ-T01", name:"CNC Lathe HMT-NH40 · Rotor shaft Ø17.98 turn",     station:"Machine Shop",     calib_due:"2026-05-08", interval:"6mo",  status:"due-soon",  owner:"Rohit B.", last_calib:"2025-11-08", linked_wi:"WI-MS-04 · QG-08" },
    { id:"EQ-T02", name:"VMC Doosan DNM4500 · Stator stack mill",           station:"Machine Shop",     calib_due:"2026-06-22", interval:"6mo",  status:"ok",        owner:"Rohit B.", last_calib:"2025-12-22", linked_wi:"WI-MS-07 · QG-09" },
    { id:"EQ-T03", name:"Coil winding machine W42-series",                  station:"Motor Assy",       calib_due:"2026-07-15", interval:"12mo", status:"ok",        owner:"Neha G.",  last_calib:"2025-07-15", linked_wi:"WI-MA-02 · QG-14" },
    { id:"EQ-T04", name:"HV Test Bench · 1500V AC withstand",               station:"Motor Test",       calib_due:"2026-04-30", interval:"3mo",  status:"due-soon",  owner:"Neha G.",  last_calib:"2026-01-30", linked_wi:"WI-MT-01 · QG-19" },
    { id:"EQ-T05", name:"Q-H Performance Test Rig (TPX serial logger)",     station:"Motor Test",       calib_due:"2026-08-12", interval:"12mo", status:"ok",        owner:"Neha G.",  last_calib:"2025-08-12", linked_wi:"WI-MT-04 · QG-27" },
    { id:"EQ-T06", name:"Hydraulic press · Stator stack pressing",          station:"Motor Assy",       calib_due:"2026-03-15", interval:"6mo",  status:"overdue",   owner:"Neha G.",  last_calib:"2025-09-15", linked_wi:"WI-MA-01 · QG-13" },
    { id:"EQ-T07", name:"Torque wrench cal-set 5–80Nm (×4)",                station:"Pump Assy",        calib_due:"2026-05-25", interval:"3mo",  status:"due-soon",  owner:"Rohit B.", last_calib:"2026-02-25", linked_wi:"WI-PA-03 · QG-22" },
    { id:"EQ-T08", name:"Mitutoyo CMM · CTQ dimension audit",               station:"Incoming Inspect", calib_due:"2026-09-10", interval:"12mo", status:"ok",        owner:"Aryan M.", last_calib:"2025-09-10", linked_wi:"WI-II-01 · QG-02" },
    { id:"EQ-T09", name:"Vibration analyser · pump balance check",          station:"Pump Test",        calib_due:"2026-06-04", interval:"6mo",  status:"ok",        owner:"Neha G.",  last_calib:"2025-12-04", linked_wi:"WI-PT-02 · QG-25" },
    { id:"EQ-T10", name:"Insulation resistance tester (megger)",            station:"Motor Test",       calib_due:"2026-04-29", interval:"3mo",  status:"due-today", owner:"Neha G.",  last_calib:"2026-01-29", linked_wi:"WI-MT-02 · QG-20" },
    { id:"EQ-T11", name:"Surface roughness gauge · bearing housing",        station:"Incoming Inspect", calib_due:"2026-07-20", interval:"6mo",  status:"ok",        owner:"Aryan M.", last_calib:"2026-01-20", linked_wi:"WI-II-04 · QG-05" },
    { id:"EQ-T12", name:"Ultrasonic thickness gauge · NRV body",            station:"Incoming Inspect", calib_due:"2026-05-15", interval:"6mo",  status:"due-soon",  owner:"Aryan M.", last_calib:"2025-11-15", linked_wi:"WI-II-06 · QG-07" },
  ];

  const [sel, setSel] = uS5("EQ-T06");
  const [filterStation, setFilterStation] = uS5("all");
  const [toast, setToast] = uS5("");
  const eq = EQUIP_T.find(e => e.id === sel) || EQUIP_T[0];

  const flash = (msg) => { setToast(msg); setTimeout(() => setToast(""), 1800); };

  const toneForStatus = s =>
    s === "ok"        ? "ok" :
    s === "due-soon"  ? "warn" :
    s === "due-today" ? "accent" :
    "err";
  const labelForStatus = s =>
    s === "ok"        ? "NOMINAL" :
    s === "due-soon"  ? "DUE SOON" :
    s === "due-today" ? "DUE TODAY" :
    "OVERDUE";

  const stations = ["all"].concat(Array.from(new Set(EQUIP_T.map(e => e.station))));
  const filtered = EQUIP_T.filter(e => filterStation === "all" || e.station === filterStation);

  // Per-equipment 3-prior calibration history. Stable derived from id hash.
  const calibHistory = (function() {
    const techs = ["Rohit B.","Neha G.","Aryan M."];
    const idNum = parseInt(eq.id.replace(/\D/g, ""), 10) || 1;
    const out = [];
    const baseDate = eq.last_calib;
    const [by, bm, bd] = baseDate.split("-").map(s => parseInt(s, 10));
    const intMonths = eq.interval === "3mo" ? 3 : eq.interval === "6mo" ? 6 : 12;
    for (let i = 0; i < 3; i++) {
      const offset = (i + 1) * intMonths;
      let ny = by, nm = bm - offset;
      while (nm <= 0) { nm += 12; ny -= 1; }
      const date = `${ny}-${String(nm).padStart(2,"0")}-${String(bd).padStart(2,"0")}`;
      const tech = techs[(idNum + i) % techs.length];
      const certNum = `CAL-${ny}-${String((idNum * 7 + i * 13) % 100).padStart(2,"0")}`;
      out.push([date, tech, "pass", certNum]);
    }
    return out;
  })();

  // KPI strip values.
  const counts = {
    overdue:   EQUIP_T.filter(e => e.status === "overdue").length,
    due_soon:  EQUIP_T.filter(e => e.status === "due-soon").length,
    due_today: EQUIP_T.filter(e => e.status === "due-today").length,
  };
  // Locale-aware count formatter (en-IN 2-2-3 grouping for tritan etc.)
  const _fmtN_eq = function (n) {
    return (window.forgeI18n && window.forgeI18n.formatNumber)
      ? window.forgeI18n.formatNumber(n)
      : String(n);
  };
  const kpis = [
    ["Assets",     _fmtN_eq(EQUIP_T.length),    "info"],
    ["Overdue",    _fmtN_eq(counts.overdue),    counts.overdue   ? "err"    : "ok"],
    ["Due Soon",   _fmtN_eq(counts.due_soon),   counts.due_soon  ? "warn"   : "ok"],
    ["Due Today",  _fmtN_eq(counts.due_today),  counts.due_today ? "accent" : "ok"],
    ["Uptime 30d", "92%",                       "ok"],
    ["Stations",   _fmtN_eq(stations.length-1), "info"],
  ];

  // Days-until calculation against current date.
  const daysUntil = (dateStr) => {
    const d = new Date(dateStr);
    const now = new Date("2026-04-29");
    return Math.round((d - now) / 86400000);
  };

  const onMarkServiced = () => {
    const today = new Date().toISOString().slice(0, 10);
    const _q = (err) => err && (err.status === 404 || err.status === 400);
    if (window.forgeApi && window.forgeApi.maintenance && typeof window.forgeApi.maintenance.logService === "function") {
      window.forgeApi.maintenance.logService({ equipment_id: eq.id, service_date: today })
        .then(() => flash(`${eq.id} marked serviced · ${today}`))
        .catch((err) => flash(_q(err) ? `${eq.id} service log queued · ${today}` : `Service log failed · ${(err && err.message) || "unknown"}`));
    } else {
      flash(`${eq.id} service log queued · ${today}`);
    }
  };

  return (
    <div style={{ padding:14, display:"grid", gridTemplateColumns:"1fr 320px", gridTemplateRows:"auto 1fr", gap:14, height:"100%", minHeight:0 }}>

      {/* KPI strip */}
      <Panel title={tenantName + " · Equipment & Calibration"} style={{ gridColumn:"1/-1" }}>
        <div style={{ display:"grid", gridTemplateColumns:"repeat(6,1fr)" }}>
          {kpis.map(([k,v,t]) => (
            <div key={k} style={{ padding:"10px 12px", borderRight:"1px solid var(--line-soft)" }}>
              <div className="label" style={{ whiteSpace: "normal", overflow: "visible", textOverflow: "clip", lineHeight: 1.3 }}>{k}</div>
              <div className="mono tnum" style={{ fontSize:20, color:`var(--${t})` }}>{v}</div>
            </div>
          ))}
        </div>
      </Panel>

      {/* registry */}
      <Panel title="Equipment Registry" right={
        <>
          <select id="maintenance-station-filter" name="maintenance-station-filter" aria-label="Filter equipment by station" value={filterStation} onChange={e=>setFilterStation(e.target.value)}
            style={{ background:"var(--bg-2)", border:"1px solid var(--line)", borderRadius:4, padding:"3px 6px",
              color:"var(--ink)", fontFamily:"var(--font-mono)", fontSize: 12 }}>
            {stations.map(s => <option key={s} value={s}>{s === "all" ? "All Stations" : s}</option>)}
          </select>
          <Btn size="sm" icon="Plus" onClick={()=>{
            var _q = function (err) { return err && (err.status === 404 || err.status === 400); };
            if (window.forgeApi && typeof window.forgeApi.mutate === "function") {
              window.forgeApi.mutate("assets", { op: "add", path: "/-", value: { added_at: Date.now(), station: filterStation === "all" ? "" : filterStation, status: "draft" } })
                .then(function () { flash("Asset draft created · scan QR or enter serial"); })
                .catch(function (err) { flash(_q(err) ? "Asset draft queued · scan QR or enter serial" : "Add failed · " + (err && err.message || "unknown")); });
            } else {
              flash("Asset draft queued · scan QR or enter serial");
            }
          }}>Add Asset</Btn>
        </>
      }>
        <table className="dtable">
          <thead><tr><th>ID</th><th>Equipment</th><th>Station</th><th>Calib Due</th><th>Days</th><th>Status</th><th>Owner</th></tr></thead>
          <tbody>
            {filtered.map(e => {
              const days = daysUntil(e.calib_due);
              return (
                <tr key={e.id} onClick={()=>setSel(e.id)} className={sel===e.id?"selected":""} style={{ cursor:"pointer" }}>
                  <td className="mono">{e.id}</td>
                  <td style={{ color:"var(--ink)" }}>{e.name}</td>
                  <td>{e.station}</td>
                  <td className="tnum">{e.calib_due}</td>
                  <td className="tnum" style={{ color: days < 0 ? "var(--err)" : days === 0 ? "var(--accent)" : days < 30 ? "var(--warn)" : "var(--ok)" }}>
                    {days < 0 ? `${Math.abs(days)}d over` : days === 0 ? "today" : `${days}d`}
                  </td>
                  <td><Pill tone={toneForStatus(e.status)} dot={false}>{labelForStatus(e.status)}</Pill></td>
                  <td>{e.owner.split(" ")[0]}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </Panel>

      {/* right column */}
      <div style={{ display:"flex", flexDirection:"column", gap:14, minHeight:0, overflowY:"auto" }}>
        <Panel title={`${eq.id} · Detail`}>
          <div style={{ padding:12 }}>
            <div className="serif" style={{ fontSize:15, lineHeight:1.2 }}>{eq.name}</div>
            <div className="muted mono" style={{ fontSize: 12, marginTop:2 }}>{eq.station}</div>
            <div className="hr"/>
            {[
              ["Calib due",  eq.calib_due],
              ["Last calib", eq.last_calib],
              ["Interval",   eq.interval],
              ["Owner",      eq.owner],
              ["Linked WI",  eq.linked_wi],
            ].map(([k,v])=>(
              <div key={k} style={{ display:"grid", gridTemplateColumns:"80px 1fr", gap:8, padding:"3px 0" }}>
                <span className="label">{k}</span>
                <span className="mono" style={{ fontSize: 12, color:"var(--ink-2)" }}>{v}</span>
              </div>
            ))}
            <div className="hr"/>
            <div className="label" style={{ marginBottom:6 }}>Status</div>
            <Pill tone={toneForStatus(eq.status)} dot={false}>{labelForStatus(eq.status)}</Pill>
            <div className="hr"/>
            <div className="label" style={{ marginBottom:6 }}>Actions</div>
            <div style={{ display:"flex", gap:6, flexWrap:"wrap" }}>
              <Btn size="sm" variant="primary" icon="Calendar" onClick={()=>{
                var _q = function (err) { return err && (err.status === 404 || err.status === 400); };
                if (window.forgeApi && typeof window.forgeApi.mutate === "function") {
                  window.forgeApi.mutate("calibrations", { op: "add", path: "/-", value: { equipment_id: eq.id, scheduled_at: Date.now(), status: "scheduled" } })
                    .then(function () { flash(`Calibration scheduled for ${eq.id}`); })
                    .catch(function (err) { flash(_q(err) ? `Calibration queued for ${eq.id}` : `Schedule failed · ${(err && err.message) || "unknown"}`); });
                } else {
                  flash(`Calibration queued for ${eq.id}`);
                }
              }}>Schedule calib</Btn>
              <Btn size="sm" icon="ArrowD" onClick={()=>flash(`Cert download queued — v2 · ${eq.id}`)}>Download cert</Btn>
              <Btn size="sm" icon="Check" onClick={onMarkServiced}>Mark serviced</Btn>
            </div>
            {toast && (
              <div className="mono" style={{ marginTop:10, padding:"6px 8px", borderRadius:4, background:"var(--bg-2)", border:"1px solid var(--accent)", color:"var(--accent)", fontSize: 12 }}>
                {toast}
              </div>
            )}
          </div>
        </Panel>

        <Panel title="Calibration History">
          <table className="dtable">
            <thead><tr><th>Date</th><th>Technician</th><th>Result</th><th>Cert #</th></tr></thead>
            <tbody>
              {calibHistory.map(([d,t,r,c]) => (
                <tr key={c}>
                  <td className="tnum">{d}</td>
                  <td>{t}</td>
                  <td><Pill tone="ok" dot={false}>{r}</Pill></td>
                  <td className="mono">{c}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </Panel>

        <Panel title="Upcoming · next 60d">
          <div style={{ padding:10 }}>
            {EQUIP_T
              .reduce((acc, e) => { const d = daysUntil(e.calib_due); if (d <= 60) acc.push([e, d]); return acc; }, [])
              .sort((a,b) => a[1] - b[1])
              .slice(0,6)
              .map(([e,d]) => (
                <div key={e.id} style={{ display:"grid", gridTemplateColumns:"1fr auto", gap:8, padding:"5px 0", borderBottom:"1px solid var(--line-soft)" }}>
                  <div>
                    <div style={{ fontSize: 12, color:"var(--ink)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{e.name}</div>
                    <div className="muted mono" style={{ fontSize: 12 }}>{e.station} · {e.calib_due}</div>
                  </div>
                  <Pill tone={toneForStatus(e.status)} dot={false}>
                    {d < 0 ? `${Math.abs(d)}d over` : d === 0 ? "today" : `${d}d`}
                  </Pill>
                </div>
              ))}
          </div>
        </Panel>
      </div>
    </div>
  );
}

Object.assign(window, { ScreenAnalytics, ScreenPeople, ScreenDocuments, ScreenMaintenance, ScreenIntegrations });
