(function(){
/* FORGE · Mittelstand tenant — Hero ECO screen (ECO-MS-0017)
   Granite-bed flatness re-grind tightening, Rev C → Rev D.

   Mirrors pump `#/build/eco` (ScreenECO) but swaps the visual palette to the
   cool anthracite/steel/graphite tones from `mittelstand/cross-cutting.jsx`
   (§10 of the tenant spec) and replaces blade-laminate beats with µm-precise
   tolerance bands, granite-cell routing impact, and the 5-stage IATF/ISO
   approval ladder.

   Single file. Babel-standalone in-browser pattern. NO ES imports / exports.
   Globals expected: React, getActiveTenant(), useActiveTenant(), navigate(),
   registerMittelstandRoute() (fallback to registerPumpRoute), Icons (I),
   Panel/Pill/Btn primitives. MS-prefixed atoms (MSCard/MSPill/MSBtn) from
   mittelstand/cross-cutting.jsx are preferred when available; we degrade
   gracefully to the generic primitives.
*/

const { useState: uSEH, useEffect: uEEH, useMemo: uMEH, useRef: uREH } = React;

/* ────────────────────────────────────────────────────────────────────
   Palette (matches cross-cutting.jsx §10 of tenant-spec/mittelstand.md)
   ──────────────────────────────────────────────────────────────────── */

const MS_BG          = "var(--mittel-bg, oklch(0.97 0.003 250))";
const MS_BG_2        = "var(--mittel-bg-2, oklch(0.92 0.004 250))";
const MS_BG_3        = "var(--mittel-bg-3, oklch(0.95 0.003 250))";
const MS_INK         = "var(--mittel-ink, oklch(0.18 0.01 250))";
const MS_INK_2       = "var(--mittel-ink-2, oklch(0.32 0.01 250))";
const MS_INK_3       = "var(--mittel-ink-3, oklch(0.48 0.01 250))";
const MS_INK_4       = "var(--mittel-ink-4, oklch(0.62 0.005 250))";
const MS_LINE        = "var(--mittel-line, oklch(0.82 0.005 250))";
const MS_LINE_SOFT   = "var(--mittel-line-soft, oklch(0.88 0.004 250))";
const MS_ACCENT      = "var(--mittel-accent, oklch(0.55 0.02 250))";
const MS_ACCENT_WARN = "var(--mittel-accent-warn, oklch(0.62 0.13 60))";
const MS_ACCENT_BAD  = "var(--mittel-accent-bad, oklch(0.55 0.18 25))";
const MS_ACCENT_OK   = "oklch(0.55 0.13 145)";
const MS_FONT_UI     = "var(--font-ui)";
const MS_FONT_MONO   = "var(--font-mono)";
const MS_FONT_SERIF  = "var(--font-serif)";

/* Locale-aware money/date helpers (forgeI18n with graceful fallback).
   Used in impact tiles + before/after table so €820 / €384,000 / €19,680
   re-flow into the active tenant locale (en-DE → 820 € · 384.000,00 €). */
function _eh_money(minor, currency, fallback) {
  const i18n = (typeof window !== "undefined") ? window.forgeI18n : null;
  if (i18n && typeof i18n.formatMoneyMinor === "function") {
    const out = i18n.formatMoneyMinor(minor, currency || "EUR");
    if (out) return out;
  }
  return fallback;
}
function _eh_moneyDelta(minor, currency, fallback) {
  const formatted = _eh_money(minor, currency, null);
  if (!formatted) return fallback;
  return "+" + formatted;
}
function _eh_date(iso, fallback) {
  const i18n = (typeof window !== "undefined") ? window.forgeI18n : null;
  if (i18n && typeof i18n.formatDate === "function") {
    const out = i18n.formatDate(iso);
    if (out) return out;
  }
  return fallback || iso;
}

/* ────────────────────────────────────────────────────────────────────
   Atom resolvers — prefer MS atoms from cross-cutting.jsx, fall back to
   generic Panel/Pill/Btn so this file stands on its own.
   ──────────────────────────────────────────────────────────────────── */

function _eh_MSCard(props) {
  const Native = (typeof window !== "undefined") ? window.MSCard : null;
  if (typeof Native === "function") return React.createElement(Native, props);
  const PanelCmp = (typeof window !== "undefined") ? window.Panel : null;
  if (typeof PanelCmp === "function") return React.createElement(PanelCmp, props);
  return React.createElement("div", {
    key: props && props.key,
    style: { background: MS_BG, border: "1px solid " + MS_LINE_SOFT, borderRadius: 6, display: "flex", flexDirection: "column", minHeight: 0, ...(props && props.style ? props.style : {}) },
  }, [
    props && props.title ? React.createElement("div", {
      key: "h",
      style: { padding: "10px 14px", borderBottom: "1px solid " + MS_LINE_SOFT, display: "flex", justifyContent: "space-between", alignItems: "center", fontFamily: MS_FONT_UI, fontSize: 12, letterSpacing: "0.06em", color: MS_INK_3, textTransform: "uppercase" },
    }, [
      React.createElement("span", { key: "t" }, props.title),
      props.right ? React.createElement("span", { key: "r", style: { display: "flex", gap: 6, alignItems: "center" } }, props.right) : null,
    ]) : null,
    React.createElement("div", { key: "b", style: { flex: 1, minHeight: 0, overflow: "auto" } }, props && props.children),
  ]);
}

function _eh_MSPill(props) {
  const Native = (typeof window !== "undefined") ? window.MSPill : null;
  if (typeof Native === "function") return React.createElement(Native, props);
  const tone = (props && props.tone) || "";
  const toneMap = {
    ok:   { bg: "color-mix(in oklch, " + MS_ACCENT_OK   + " 14%, transparent)", fg: MS_ACCENT_OK   },
    warn: { bg: "color-mix(in oklch, " + MS_ACCENT_WARN + " 16%, transparent)", fg: MS_ACCENT_WARN },
    err:  { bg: "color-mix(in oklch, " + MS_ACCENT_BAD  + " 14%, transparent)", fg: MS_ACCENT_BAD  },
    info: { bg: "color-mix(in oklch, " + MS_ACCENT      + " 16%, transparent)", fg: MS_ACCENT      },
    "":   { bg: MS_BG_3, fg: MS_INK_3 },
  };
  const t = toneMap[tone] || toneMap[""];
  return React.createElement("span", {
    key: props && props.key,
    style: { display: "inline-flex", alignItems: "center", gap: 4, height: 18, padding: "0 8px", borderRadius: 3, background: t.bg, color: t.fg, fontFamily: MS_FONT_MONO, fontSize: 12, letterSpacing: "0.04em", textTransform: "uppercase", border: "1px solid color-mix(in oklch, " + t.fg + " 24%, transparent)" },
  }, props && props.children);
}

function _eh_MSBtn(props) {
  const Native = (typeof window !== "undefined") ? window.MSBtn : null;
  if (typeof Native === "function") return React.createElement(Native, props);
  const variant = (props && props.variant) || "ghost";
  const size = (props && props.size) || "md";
  const sz = size === "sm" ? { h: 26, px: 9, fs: 11 } : size === "lg" ? { h: 36, px: 14, fs: 13 } : { h: 30, px: 12, fs: 12 };
  const variantStyle = {
    primary: { bg: MS_INK,   fg: MS_BG,   border: MS_INK },
    danger:  { bg: MS_ACCENT_BAD, fg: "#fff", border: MS_ACCENT_BAD },
    ghost:   { bg: "transparent", fg: MS_INK_2, border: MS_LINE },
    quiet:   { bg: MS_BG_3, fg: MS_INK_2, border: MS_LINE_SOFT },
  };
  const v = variantStyle[variant] || variantStyle.ghost;
  return React.createElement("button", {
    key: props && props.key,
    onClick: props && props.onClick, disabled: props && props.disabled, title: props && props.title,
    style: { height: sz.h, padding: "0 " + sz.px + "px", fontFamily: MS_FONT_UI, fontSize: sz.fs, background: v.bg, color: v.fg, border: "1px solid " + v.border, borderRadius: 4, cursor: (props && props.disabled) ? "not-allowed" : "pointer", opacity: (props && props.disabled) ? 0.5 : 1, display: "inline-flex", alignItems: "center", gap: 6, letterSpacing: "0.02em" },
  }, props && props.children);
}

function _eh_icon(name, size) {
  if (typeof I === "function") return I(name, { size: size || 14 });
  if (typeof window !== "undefined" && typeof window.I === "function") return window.I(name, { size: size || 14 });
  return null;
}

/* ────────────────────────────────────────────────────────────────────
   Static content — sourced from §6 (hero ECO detail) of tenant-spec
   ──────────────────────────────────────────────────────────────────── */

const ECO_MS_0017 = {
  id: "ECO-MS-0017",
  title: "Granite-bed flatness tightening, Rev C → Rev D",
  raised_by: "R. Vogt",
  raised_role: "Engineering Lead",
  date_raised: "2025-11-18",
  status: "in-review",
  severity: "critical",
  parts: [
    { num: "10.01", name: "Granite base block",   before: "±5 µm flatness", after: "±3 µm flatness, two-pass lap + re-grind" },
    { num: "10.02", name: "Granite cross-beam",   before: "±5 µm flatness", after: "±3 µm flatness, two-pass lap + re-grind" },
  ],
  trigger: {
    title: "3 Rev C field returns · vibration acceptance bust",
    units: ["S/N 0089", "S/N 0091", "S/N 0094"],
    measurement: "0.94 / 1.02 / 0.97 mm/s RMS at 12k rpm contouring",
    limit: "0.80 mm/s RMS",
    root_cause: "Granite cross-beam flatness drift (+8 µm peak-to-valley over 1.6 m span) traced to single-pass lap operation at S/N 0089–0094",
  },
  cost_per_unit: 820,                     // EUR
  units_in_batch: 24,
  cost_total: 24 * 820,                   // EUR
  lead_time_delta: 11,                    // days
  net_program_slip: 0,                    // days — spindle (180 d) is critical
  approvals: [
    { stage: 1, role: "Engineering",   name: "R. Vogt",   state: "passed",  ts: "2025-11-18 14:22", notes: "Root cause confirmed. ECO opened against 10.01 / 10.02." },
    { stage: 2, role: "Manufacturing", name: "D. Becker", state: "passed",  ts: "2025-11-21 09:48", notes: "Re-grind operation slotted between rough and finish lap. Cell capacity 1.2× nominal." },
    { stage: 3, role: "Quality",       name: "S. Klein",  state: "pending", ts: "—",                notes: "Awaiting CMM gauge R&R against revised 3 µm band. Zeiss UPMC scheduled 2025-11-26." },
    { stage: 4, role: "Sign-off",      name: "—",         state: "blocked", ts: "—",                notes: "Blocked on Quality stage 3." },
    { stage: 5, role: "FAI",           name: "—",         state: "blocked", ts: "—",                notes: "FAI scheduled 2026-08-14 once production batch enters Station 4." },
  ],
  conversation: [
    { who: "R. Vogt",   role: "Engineering Lead",   ts: "2025-11-18 14:24", body: "Three returns clustered at S/N 0089–0094 all show vibration > 0.80 mm/s at 12k rpm contouring. Pulled the granite QC traveler — single-pass lap was running 4–6 µm flatness, inside the ±5 µm spec but at the edge. Tightening to ±3 µm with a re-grind between rough and finish removes the band the field returns are sitting in." },
    { who: "D. Becker", role: "Manufacturing Lead", ts: "2025-11-19 08:11", body: "Re-grind op fits the cell. We have the lap stones for the rough pass and the finish pass — concern is whether the existing aluminium-oxide stones can hold a 3 µm band over a full 24-unit batch, or if we need to switch to the finer cerium-oxide compound mid-cycle. That's the lead-time risk: cerium stones are 6-week procurement from Diamant Boart." },
    { who: "S. Klein",  role: "Quality Lead",       ts: "2025-11-19 11:36", body: "Ran the numbers on our existing Zeiss UPMC repeatability — gauge R&R is 0.8 µm at the 3 µm tolerance band, so we're at 27% R&R. Acceptable but tight. I want a CMM verification on the first re-ground unit before we sign off. AS9102 form set will need re-issue at PPAP Level 3 either way." },
    { who: "R. Vogt",   role: "Engineering Lead",   ts: "2025-11-20 09:02", body: "Agreed on CMM check. Daniel — let's run a 3-piece pilot on the existing aluminium-oxide stones first. If we hold 3 µm across 3 units we don't trigger the cerium-oxide procurement. If we don't, we eat the 11-day cell delta and order the new compound. Either way the spindle is critical path at 180 d, so program slip is zero." },
    { who: "D. Becker", role: "Manufacturing Lead", ts: "2025-11-20 13:18", body: "OK. Pilot kicked off Monday. Slot blocked in granite cell 2025-11-24 → 2025-11-26. I'll publish the updated routing once the pilot reads out — should be Wednesday EOB." },
  ],
  before_after: [
    { field: "Granite base block flatness",   before: "±5 µm",        after: "±3 µm",        delta: "−2 µm",   tone: "ok" },
    { field: "Granite cross-beam flatness",   before: "±5 µm",        after: "±3 µm",        delta: "−2 µm",   tone: "ok" },
    { field: "Lap operation",                 before: "single pass",  after: "two-pass + re-grind", delta: "+1 op",  tone: "warn" },
    { field: "ATC carousel runout @ 24k rpm", before: "≤4.0 µm TIR",  after: "≤2.5 µm TIR",  delta: "−1.5 µm", tone: "ok" },
    { field: "FAI ISO 230-2 result",          before: "0.94 mm/s RMS", after: "≤0.50 mm/s RMS (predicted)", delta: "−0.44 mm/s", tone: "ok" },
    { field: "Cost per unit",                 before: _eh_money("38400000", "EUR", "€384,000"),      after: _eh_money("38482000", "EUR", "€384,820"),     delta: _eh_moneyDelta("82000", "EUR", "+€820"),   tone: "warn" },
    { field: "Lead-time (granite path)",      before: "75 d",          after: "86 d",         delta: "+11 d",   tone: "warn" },
    { field: "Lead-time (program critical)",  before: "180 d",         after: "180 d",        delta: "±0 d",    tone: "info" },
    { field: "Compliance",                    before: "PPAP Level 2",  after: "PPAP Level 3 re-submission", delta: "+1 level", tone: "info" },
  ],
  related_field_returns: [
    { sn: "S/N 0089", customer: "MAHLE — Pforzheim plant", returned: "2025-10-04", measurement: "0.94 mm/s RMS @ 12k rpm" },
    { sn: "S/N 0091", customer: "MAHLE — Cannstatt plant", returned: "2025-10-12", measurement: "1.02 mm/s RMS @ 12k rpm" },
    { sn: "S/N 0094", customer: "MAHLE — Bad Cannstatt",   returned: "2025-10-19", measurement: "0.97 mm/s RMS @ 12k rpm" },
  ],
};

// Sibling ECOs for the left-hand list (only 0017 highlighted, others muted)
const ECO_LIST = [
  { id: "ECO-MS-0014", title: "Coolant pump P3 swap (Bosch → Speck)",          state: "approved", sev: "low",      raised: "2025-08-22", owner: "D. Becker" },
  { id: "ECO-MS-0015", title: "Heidenhain TNC 640 firmware 18.07 → 18.09",     state: "closed",   sev: "low",      raised: "2025-09-30", owner: "R. Vogt"   },
  { id: "ECO-MS-0016", title: "ATC carousel pocket 18 alignment shim revision",state: "closed",   sev: "med",      raised: "2025-10-15", owner: "D. Becker" },
  { id: "ECO-MS-0017", title: "Granite-bed flatness ±5 µm → ±3 µm",            state: "in-review",sev: "critical", raised: "2025-11-18", owner: "R. Vogt"   },
  { id: "ECO-MS-0018", title: "Spindle HSK-A63 toolholder seat torque spec",    state: "draft",    sev: "med",      raised: "2025-11-26", owner: "S. Klein"  },
];

/* ────────────────────────────────────────────────────────────────────
   Toast helper — non-fatal if global toast hook is missing
   ──────────────────────────────────────────────────────────────────── */

function _eh_toast(msg, tone) {
  if (typeof window === "undefined") return;
  const setter = window.setForgeToast || window.__setToast;
  if (typeof setter === "function") return setter({ msg: msg, tone: tone || "info", ttl: 3500 });
  try { window.dispatchEvent(new CustomEvent("forge:toast", { detail: { msg: msg, tone: tone || "info" } })); } catch (_e) {}
  if (typeof document === "undefined") return;
  let host = document.getElementById("ms-eco-toast-host");
  if (!host) {
    host = document.createElement("div");
    host.id = "ms-eco-toast-host";
    host.style.cssText = "position:fixed;bottom:24px;right:24px;z-index:9999;display:flex;flex-direction:column;gap:6px;pointer-events:none;";
    document.body.appendChild(host);
  }
  const node = document.createElement("div");
  const fg = tone === "ok" ? "oklch(0.55 0.13 145)" : tone === "err" ? "oklch(0.55 0.18 25)" : tone === "warn" ? "oklch(0.62 0.13 60)" : "oklch(0.18 0.01 250)";
  node.style.cssText = "background:oklch(0.97 0.003 250);border:1px solid " + fg + ";color:" + fg + ";padding:8px 12px;border-radius:4px;font-family:var(--font-mono);font-size:11px;letter-spacing:.04em;text-transform:uppercase;box-shadow:0 6px 18px rgba(0,0,0,.08);min-width:240px;";
  node.textContent = msg;
  host.appendChild(node);
  setTimeout(function() { node.style.cssText += ";opacity:0;transition:opacity .4s;"; }, 2800);
  setTimeout(function() { try { host.removeChild(node); } catch (_e) {} }, 3400);
}

/* ────────────────────────────────────────────────────────────────────
   Sub-component — left list of related ECOs
   ──────────────────────────────────────────────────────────────────── */

function _EH_EcoList(props) {
  const sel = props.selectedId;
  const onSelect = props.onSelect;
  // Wave 3C item 23: prefer tenant.eco when present (4 ECOs from fixture),
  // fall back to the legacy hardcoded ECO_LIST for tests / stub renders.
  const tenantEcos = Array.isArray(props.ecos) && props.ecos.length ? props.ecos : null;
  const rows = tenantEcos
    ? tenantEcos.map(function(e) {
        return {
          id:     e.id,
          title:  e.title,
          state:  e.status || e.state || "—",
          sev:    e.severity || (e.sev || "low"),
          owner:  e.originator || e.owner || "—",
          raised: e.date_raised || "—",
        };
      })
    : ECO_LIST;
  return _eh_MSCard({
    title: "Change orders · Mittelstand",
    right: _eh_MSBtn({
      size: "sm",
      variant: "ghost",
      onClick: function() { _eh_toast("New ECO drafting available in Engineering portal", "info"); },
      children: [_eh_icon("Plus", 12), React.createElement("span", { key: "l" }, " New ECO")],
    }),
    children: React.createElement("div", { style: { padding: 0 } },
      rows.map(function(e) {
        const isSel = e.id === sel;
        const sevTone = e.sev === "critical" ? "err" : e.sev === "high" ? "warn" : e.sev === "med" ? "info" : "";
        const stateTone = e.state === "approved" ? "ok" : e.state === "closed" ? "" : e.state === "in-review" ? "warn" : "";
        return React.createElement("div", {
          key: e.id,
          onClick: function() { onSelect(e.id); },
          style: {
            padding: "12px 14px",
            borderBottom: "1px solid " + MS_LINE_SOFT,
            cursor: "pointer",
            background: isSel ? MS_BG_2 : "transparent",
            borderLeft: "3px solid " + (isSel ? MS_ACCENT : "transparent"),
            transition: "background 120ms ease",
          },
        }, [
          React.createElement("div", {
            key: "row1",
            style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 4 },
          }, [
            React.createElement("span", {
              key: "id",
              className: "mono",
              style: { fontFamily: MS_FONT_MONO, fontSize: 12, color: isSel ? MS_INK : MS_INK_3, letterSpacing: "0.04em" },
            }, e.id),
            _eh_MSPill({ tone: sevTone, children: e.sev }),
          ]),
          React.createElement("div", {
            key: "title",
            style: { fontSize: 12, color: isSel ? MS_INK : MS_INK_2, lineHeight: 1.3, marginBottom: 4 },
          }, e.title),
          React.createElement("div", {
            key: "meta",
            style: {
              display: "flex",
              justifyContent: "space-between",
              fontFamily: MS_FONT_MONO,
              fontSize: 12,
              color: MS_INK_3,
            },
          }, [
            React.createElement("span", { key: "owner" }, e.owner + " · " + _eh_date(e.raised, e.raised)),
            _eh_MSPill({ tone: stateTone, children: e.state }),
          ]),
        ]);
      })
    ),
  });
}

// Wave 3C item 23 — minimal detail panel for non-hero Mittelstand ECOs.
// The rich panel relies on ECO_MS_0017.{trigger, before_after, parts}; minor
// fixture entries don't have those, so we render a flat metadata view.
function _EH_MinimalDetailPanel(props) {
  const eco = props.eco || {};
  const parts = Array.isArray(eco.parts_affected) ? eco.parts_affected : [];
  return _eh_MSCard({
    title: eco.id + " · " + (eco.title || "—"),
    right: [
      _eh_MSPill({ key: "sev", tone: eco.severity === "critical" ? "err" : "info", children: eco.severity || "minor" }),
      _eh_MSPill({ key: "state", tone: (eco.status || eco.state) === "approved" ? "ok" : "warn", children: eco.status || eco.state || "—" }),
    ],
    children: React.createElement("div", {
      style: { padding: 16, display: "flex", flexDirection: "column", gap: 14 },
    }, [
      React.createElement("div", {
        key: "meta",
        style: { display: "grid", gridTemplateColumns: "repeat(3, minmax(0, 1fr))", gap: 10 },
      }, [
        ["Originator", eco.originator || eco.raised_by || "—"],
        ["Raised",     _eh_date(eco.date_raised, eco.date_raised || "—")],
        ["Closed",     _eh_date(eco.date_approved || eco.date_target_close, eco.date_approved || eco.date_target_close || "—")],
        ["Cost Δ / unit", (function() {
          if (typeof eco.cost_delta_eur_per_unit === "number") {
            return _eh_money(String(Math.round(eco.cost_delta_eur_per_unit * 100)), "EUR", "€" + eco.cost_delta_eur_per_unit);
          }
          if (eco.cost_delta_amount_minor != null && eco.cost_delta_currency) {
            const i18n = (typeof window !== "undefined") ? window.forgeI18n : null;
            if (i18n && i18n.formatMoneyMinor) return i18n.formatMoneyMinor(eco.cost_delta_amount_minor, eco.cost_delta_currency);
            return String(eco.cost_delta_amount_minor) + " " + eco.cost_delta_currency + " (minor)";
          }
          return "—";
        })()],
        ["Lead-time Δ", typeof eco.lead_time_delta_days === "number" ? (eco.lead_time_delta_days + " d") : "—"],
        ["Compliance", (eco.compliance || []).join(" · ") || "—"],
      ].map(function(kv) {
        return React.createElement("div", {
          key: kv[0],
          style: { padding: 10, border: "1px solid " + MS_LINE_SOFT, borderRadius: 4, background: MS_BG },
        }, [
          React.createElement("div", { key: "l", style: { fontFamily: MS_FONT_MONO, fontSize: 12, letterSpacing: "0.06em", textTransform: "uppercase", color: MS_INK_3 } }, kv[0]),
          React.createElement("div", { key: "v", style: { fontFamily: MS_FONT_MONO, fontSize: 13, color: MS_INK, marginTop: 4, lineHeight: 1.4 } }, kv[1]),
        ]);
      })),
      eco.justification ? React.createElement("div", { key: "just" }, [
        React.createElement("div", { key: "l", style: { fontFamily: MS_FONT_MONO, fontSize: 12, letterSpacing: "0.06em", textTransform: "uppercase", color: MS_INK_3, marginBottom: 6 } }, "Justification"),
        React.createElement("div", { key: "v", style: { fontFamily: MS_FONT_UI, fontSize: 13, color: MS_INK_2, lineHeight: 1.5 } }, eco.justification),
      ]) : null,
      parts.length ? React.createElement("div", { key: "parts" }, [
        React.createElement("div", { key: "l", style: { fontFamily: MS_FONT_MONO, fontSize: 12, letterSpacing: "0.06em", textTransform: "uppercase", color: MS_INK_3, marginBottom: 6 } }, "Parts affected"),
        React.createElement("div", { key: "rows", style: { display: "flex", flexDirection: "column", gap: 4 } },
          parts.map(function(p, i) {
            return React.createElement("div", {
              key: i,
              style: { padding: "6px 10px", background: MS_BG, border: "1px solid " + MS_LINE_SOFT, borderRadius: 3, fontFamily: MS_FONT_MONO, fontSize: 12, color: MS_INK_2 },
            }, (p.old || "—") + "  →  " + (p.new || "—"));
          })
        ),
      ]) : null,
      React.createElement("div", { key: "hint", style: { color: MS_INK_3, fontSize: 12, fontFamily: MS_FONT_MONO } },
        "Minimal viewer · select " + ECO_MS_0017.id + " for the full trigger / before-after / field-return chain."
      ),
    ]),
  });
}

/* ────────────────────────────────────────────────────────────────────
   Sub-component — trigger / field-return banner
   ──────────────────────────────────────────────────────────────────── */

function _EH_TriggerBanner() {
  return React.createElement("div", {
    style: {
      border: "1px solid " + MS_ACCENT_BAD,
      background: "color-mix(in oklch, " + MS_ACCENT_BAD + " 6%, " + MS_BG + ")",
      borderLeft: "4px solid " + MS_ACCENT_BAD,
      borderRadius: 4,
      padding: "12px 14px",
      display: "grid",
      gridTemplateColumns: "20px 1fr auto",
      gap: 12,
      alignItems: "start",
    },
  }, [
    React.createElement("div", { key: "ic", style: { color: MS_ACCENT_BAD, paddingTop: 1 } }, _eh_icon("AlertTriangle", 18)),
    React.createElement("div", { key: "body" }, [
      React.createElement("div", {
        key: "t",
        style: {
          fontFamily: MS_FONT_MONO, fontSize: 12, letterSpacing: "0.06em",
          textTransform: "uppercase", color: MS_ACCENT_BAD, marginBottom: 4,
        },
      }, "Trigger · 3 Rev C field returns"),
      React.createElement("div", {
        key: "m",
        style: { fontSize: 13, color: MS_INK, lineHeight: 1.45 },
      }, ECO_MS_0017.trigger.root_cause + "."),
      React.createElement("div", {
        key: "u",
        style: {
          marginTop: 6, fontFamily: MS_FONT_MONO, fontSize: 12,
          color: MS_INK_3, letterSpacing: "0.02em",
        },
      }, ECO_MS_0017.trigger.units.join("  ·  ") + "  →  " + ECO_MS_0017.trigger.measurement + "  (limit " + ECO_MS_0017.trigger.limit + ")"),
    ]),
    _eh_MSBtn({
      size: "sm",
      variant: "ghost",
      onClick: function() {
        if (typeof navigate === "function") navigate("/forge/field-issues");
        else if (typeof window !== "undefined") window.location.hash = "/forge/field-issues";
      },
      children: [React.createElement("span", { key: "l" }, "Open field-issues"), _eh_icon("ArrowRight", 12)],
    }),
  ]);
}

/* ────────────────────────────────────────────────────────────────────
   Sub-component — impact tile grid (cost + lead-time + units)
   ──────────────────────────────────────────────────────────────────── */

function _EH_ImpactTiles() {
  const tiles = [
    { k: "Parts affected",        v: "2",                                                          sub: "10.01 / 10.02",            tone: "info" },
    { k: "Cost / unit",           v: _eh_moneyDelta("82000",   "EUR", "+€820"),                    sub: "granite re-work",          tone: "warn" },
    { k: "Cost · 24-unit batch",  v: _eh_moneyDelta("1968000", "EUR", "+€19,680"),                 sub: "absorbed in Rev D quote",  tone: "warn" },
    { k: "Lead-time (cell)",      v: "+11 d",                                                      sub: "granite path",             tone: "warn" },
    { k: "Net program slip",      v: "0 d",                                                        sub: "spindle critical",         tone: "ok"   },
    { k: "Compliance",            v: "PPAP L3",                                                    sub: "AS9102/IATF re-issue",     tone: "info" },
  ];
  return React.createElement("div", { style: { display: "grid", gridTemplateColumns: "repeat(6, 1fr)", gap: 8 } },
    tiles.map(function(t) {
      const tone = t.tone === "warn" ? MS_ACCENT_WARN : t.tone === "ok" ? MS_ACCENT_OK : t.tone === "err" ? MS_ACCENT_BAD : MS_ACCENT;
      return React.createElement("div", {
        key: t.k,
        style: { padding: 12, background: MS_BG, border: "1px solid " + MS_LINE_SOFT, borderTop: "2px solid " + tone, borderRadius: 4 },
      }, [
        React.createElement("div", { key: "k", style: { fontFamily: MS_FONT_MONO, fontSize: 12, textTransform: "uppercase", letterSpacing: "0.06em", color: MS_INK_3, marginBottom: 4 } }, t.k),
        React.createElement("div", { key: "v", className: "mono tnum", style: { fontFamily: MS_FONT_MONO, fontSize: 22, color: tone, fontVariantNumeric: "tabular-nums", lineHeight: 1.1 } }, t.v),
        React.createElement("div", { key: "s", style: { fontSize: 12, color: MS_INK_3, marginTop: 4 } }, t.sub),
      ]);
    })
  );
}

/* ────────────────────────────────────────────────────────────────────
   Sub-component — before / after table (µm-precise rows)
   ──────────────────────────────────────────────────────────────────── */

function _EH_BeforeAfterTable() {
  return React.createElement("div", {
    style: { border: "1px solid " + MS_LINE_SOFT, borderRadius: 4, overflow: "hidden", background: MS_BG },
  }, [
    React.createElement("div", {
      key: "h",
      style: { display: "grid", gridTemplateColumns: "1.6fr 1fr 1fr 0.9fr", background: MS_BG_3, borderBottom: "1px solid " + MS_LINE, fontFamily: MS_FONT_MONO, fontSize: 12, textTransform: "uppercase", letterSpacing: "0.06em", color: MS_INK_3 },
    }, [
      React.createElement("div", { key: "f", style: { padding: "8px 12px" } }, "Field"),
      React.createElement("div", { key: "b", style: { padding: "8px 12px" } }, "Before · Rev C"),
      React.createElement("div", { key: "a", style: { padding: "8px 12px" } }, "After · Rev D"),
      React.createElement("div", { key: "d", style: { padding: "8px 12px", textAlign: "right" } }, "Δ"),
    ]),
    ECO_MS_0017.before_after.map(function(row, i) {
      const tone = row.tone === "ok" ? MS_ACCENT_OK : row.tone === "warn" ? MS_ACCENT_WARN : row.tone === "err" ? MS_ACCENT_BAD : MS_INK_3;
      return React.createElement("div", {
        key: row.field,
        style: {
          display: "grid",
          gridTemplateColumns: "1.6fr 1fr 1fr 0.9fr",
          borderBottom: i === ECO_MS_0017.before_after.length - 1 ? "none" : "1px solid " + MS_LINE_SOFT,
          fontSize: 12,
          background: i % 2 === 0 ? "transparent" : MS_BG_3,
        },
      }, [
        React.createElement("div", { key: "f", style: { padding: "10px 12px", color: MS_INK } }, row.field),
        React.createElement("div", { key: "b", style: { padding: "10px 12px", color: MS_INK_3, fontFamily: MS_FONT_MONO, fontVariantNumeric: "tabular-nums", fontSize: 12 } }, row.before),
        React.createElement("div", { key: "a", style: { padding: "10px 12px", color: MS_INK, fontFamily: MS_FONT_MONO, fontVariantNumeric: "tabular-nums", fontSize: 12 } }, row.after),
        React.createElement("div", { key: "d", style: { padding: "10px 12px", textAlign: "right", color: tone, fontFamily: MS_FONT_MONO, fontVariantNumeric: "tabular-nums", fontSize: 12, fontWeight: 500 } }, row.delta),
      ]);
    }),
  ]);
}

/* ────────────────────────────────────────────────────────────────────
   Sub-component — field-return drill-down rows
   ──────────────────────────────────────────────────────────────────── */

function _EH_FieldReturns() {
  return React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 6 } },
    ECO_MS_0017.related_field_returns.map(function(fr) {
      return React.createElement("div", {
        key: fr.sn,
        onClick: function() {
          _eh_toast("Open " + fr.sn + " in field-issues drill-down", "info");
          if (typeof navigate === "function") navigate("/forge/field-issues");
        },
        style: { padding: "10px 12px", background: MS_BG, border: "1px solid " + MS_LINE_SOFT, borderLeft: "3px solid " + MS_ACCENT_BAD, borderRadius: 4, display: "grid", gridTemplateColumns: "100px 1fr auto", gap: 12, alignItems: "center", cursor: "pointer", transition: "background 120ms ease" },
      }, [
        React.createElement("span", { key: "sn", style: { fontFamily: MS_FONT_MONO, fontSize: 12, color: MS_INK, fontVariantNumeric: "tabular-nums" } }, fr.sn),
        React.createElement("div", { key: "info" }, [
          React.createElement("div", { key: "c", style: { fontSize: 12, color: MS_INK_2 } }, fr.customer),
          React.createElement("div", { key: "m", style: { fontFamily: MS_FONT_MONO, fontSize: 12, color: MS_ACCENT_BAD, marginTop: 2 } }, "returned " + _eh_date(fr.returned, fr.returned) + "  ·  " + fr.measurement),
        ]),
        _eh_icon("ArrowRight", 14),
      ]);
    })
  );
}

/* ────────────────────────────────────────────────────────────────────
   Stage derivation — single source of truth for the 5-stage ladder.

   The bug we are fixing: `stages` was previously a local `useState` seeded
   from the hardcoded ECO_MS_0017.approvals constant. It never re-synced
   to the live `eco.approval_chain` from the server, so a RELEASED ECO in
   the left list still painted PENDING/BLOCKED rows + active Approve/Reject
   buttons on the right.

   Fix: derive the 5-stage display from `currentStatus` (FSM status) +
   `approval_chain` (server-authoritative names/timestamps) on every render.

   Role → Stage mapping (Mittelstand, fixed by storyboard):
     1  Engineering   ← approval_chain entry "Engineering Lead"
     2  Manufacturing ← approval_chain entry "Manufacturing Lead"
     3  Quality       ← approval_chain entry "Quality Lead"
     4  Sign-off      ← approval_chain entry "Plant Director"  (display label
                        "Sign-off" to match the storyboard 5-stage ladder)
     5  FAI           ← synthetic — no chain entry; gated on status==="released"

   Status → stage-state table (drives WHICH stage is which colour):
     draft                 → [B, B, B, B, B]
     in-review             → [P, P, p, B, B]      (canonical demo state)
     quality-approved      → [P, P, P, p, B]
     customer-acknowledged → [P, P, P, P, B]
     approved              → same as customer-acknowledged
     released | applied    → [P, P, P, P, P]      (terminal)
     rejected              → prior P stays P · rejecting role → F · rest B

   The approval_chain only supplies `name`/`at`/`notes` for the row; the
   pass/pending/blocked colour is driven by status, not by chain length.
   This keeps the 5-row ladder stable even though the chain has 4 entries.
   ──────────────────────────────────────────────────────────────────── */

const _EH_TERMINAL_STATES = ["released", "applied", "rejected"];
const _EH_ROLE_LABELS = ["Engineering", "Manufacturing", "Quality", "Sign-off", "FAI"];
const _EH_ROLE_CHAIN_KEYS = ["Engineering Lead", "Manufacturing Lead", "Quality Lead", "Plant Director", null];

function _eh_isTerminal(status) {
  return _EH_TERMINAL_STATES.indexOf(status) !== -1;
}

// Look up an approval_chain entry by role (case-insensitive substring match
// so the same derivation works for fixture entries that label it
// "Plant Director" or "Customer Quality" alike).
function _eh_findChainEntry(chain, roleKey) {
  if (!Array.isArray(chain) || !roleKey) return null;
  const want = roleKey.toLowerCase();
  for (let i = 0; i < chain.length; i++) {
    const c = chain[i];
    if (!c || typeof c.role !== "string") continue;
    if (c.role.toLowerCase() === want) return c;
  }
  return null;
}

// Compute the 5-stage display states from currentStatus.
// Returns an array of "passed" | "pending" | "blocked" | "failed", indexed 0..4.
function _eh_stageStatesForStatus(status, rejectingStageIdx) {
  // 5 = FAI (synthetic) · only "passed" when ECO is released/applied
  if (status === "released" || status === "applied") {
    return ["passed", "passed", "passed", "passed", "passed"];
  }
  if (status === "rejected") {
    // prior passed stays passed; rejecting stage = failed; rest blocked.
    const out = ["blocked", "blocked", "blocked", "blocked", "blocked"];
    const idx = (typeof rejectingStageIdx === "number" && rejectingStageIdx >= 0)
      ? rejectingStageIdx
      : 2; // default: Quality (Stage 3) is the most common rejection point
    for (let i = 0; i < idx; i++) out[i] = "passed";
    out[idx] = "failed";
    return out;
  }
  if (status === "customer-acknowledged" || status === "approved") {
    return ["passed", "passed", "passed", "passed", "blocked"];
  }
  if (status === "quality-approved") {
    return ["passed", "passed", "passed", "pending", "blocked"];
  }
  if (status === "in-review") {
    return ["passed", "passed", "pending", "blocked", "blocked"];
  }
  // draft / unknown
  return ["blocked", "blocked", "blocked", "blocked", "blocked"];
}

// Pick the rejecting stage index from approval_chain (find the entry whose
// status === "rejected"). Returns -1 if none found.
function _eh_rejectingStageIdx(chain) {
  if (!Array.isArray(chain)) return -1;
  for (let i = 0; i < _EH_ROLE_CHAIN_KEYS.length; i++) {
    const roleKey = _EH_ROLE_CHAIN_KEYS[i];
    if (!roleKey) continue;
    const entry = _eh_findChainEntry(chain, roleKey);
    if (entry && typeof entry.status === "string" && entry.status.toLowerCase() === "rejected") {
      return i;
    }
  }
  return -1;
}

// Compose the 5 stage rows the renderer consumes.
// `eco` may be the rich hardcoded fixture (ECO_MS_0017 with .approvals) or
// the slim tenant fixture (with .approval_chain). We prefer .approval_chain
// when present so server transitions flow through; we fall back to .approvals
// for the original fixture row so test/stub renders keep working.
function deriveMittelstandEcoStages(eco, currentStatus) {
  const chain = (eco && Array.isArray(eco.approval_chain)) ? eco.approval_chain : null;
  const legacy = (eco && Array.isArray(eco.approvals)) ? eco.approvals : null;
  const rejIdx = _eh_rejectingStageIdx(chain || []);
  const states = _eh_stageStatesForStatus(currentStatus, rejIdx);

  const rows = [];
  for (let i = 0; i < 5; i++) {
    const stageNum = i + 1;
    const role = _EH_ROLE_LABELS[i];
    const state = states[i];
    const chainEntry = chain ? _eh_findChainEntry(chain, _EH_ROLE_CHAIN_KEYS[i]) : null;
    const legacyEntry = legacy && legacy[i] ? legacy[i] : null;
    // Prefer chain metadata (server-authoritative) when present; fall back
    // to the legacy fixture row for FAI (no chain entry) or for stub renders.
    const name = (chainEntry && chainEntry.name)
      || (legacyEntry && legacyEntry.name)
      || "—";
    const ts = (chainEntry && chainEntry.at)
      || (legacyEntry && legacyEntry.ts)
      || "—";
    // Note text: use the legacy fixture's rich note when state matches
    // (or when there's no chain entry, e.g. FAI). Otherwise synthesize a
    // short status line so the renderer doesn't leave a blank row.
    let notes = legacyEntry ? legacyEntry.notes : null;
    if (chainEntry && chainEntry.status && state === "pending" && typeof chainEntry.status === "string"
        && chainEntry.status.toLowerCase().indexOf("pending") === 0) {
      // surface fixture's sub-status ("pending · awaiting CMM gauge R&R")
      notes = chainEntry.status.replace(/^pending\s*·?\s*/i, "Pending · ") || notes;
    }
    if (state === "failed") notes = (notes ? notes + " · " : "") + "Rejected.";
    if (state === "blocked" && stageNum === 5 && currentStatus !== "released" && currentStatus !== "applied") {
      notes = legacyEntry && legacyEntry.notes
        ? legacyEntry.notes
        : "FAI gate · runs after release";
    }
    if (currentStatus === "released" || currentStatus === "applied") {
      notes = legacyEntry && legacyEntry.notes
        ? legacyEntry.notes
        : (stageNum === 5 ? "FAI passed · ledger arc closed" : "Approved");
    }
    rows.push({
      stage: stageNum,
      role: role,
      state: state,
      name: name,
      ts: ts,
      notes: notes || "",
    });
  }
  return rows;
}

// Expose for snapshot testing under the Babel-standalone harness.
if (typeof window !== "undefined") {
  window.__msEcoDeriveStages = deriveMittelstandEcoStages;
}

/* ────────────────────────────────────────────────────────────────────
   Sub-component — 5-stage approval ladder
   ──────────────────────────────────────────────────────────────────── */

function _EH_ApprovalLadder(props) {
  const stages = props.stages;
  return React.createElement("div", {
    style: { display: "flex", flexDirection: "column", gap: 0 },
  }, stages.map(function(s, i) {
    const isLast = i === stages.length - 1;
    const stateTone =
      s.state === "passed"  ? MS_ACCENT_OK   :
      s.state === "pending" ? MS_ACCENT_WARN :
      s.state === "blocked" ? MS_INK_4       :
      s.state === "failed"  ? MS_ACCENT_BAD  : MS_INK_4;
    const dotIcon = s.state === "passed" ? "Check" : s.state === "pending" ? "Clock" : s.state === "failed" ? "X" : "Minus";
    return React.createElement("div", {
      key: s.stage,
      style: {
        display: "grid",
        gridTemplateColumns: "32px 1fr",
        gap: 0,
        position: "relative",
      },
    }, [
      // rail dot column
      React.createElement("div", {
        key: "rail",
        style: { position: "relative", display: "flex", justifyContent: "center" },
      }, [
        !isLast ? React.createElement("div", { key: "vl", style: { position: "absolute", top: 22, bottom: -4, left: 15, width: 2, background: MS_LINE_SOFT } }) : null,
        React.createElement("div", {
          key: "dot",
          style: { width: 22, height: 22, borderRadius: 22, background: s.state === "passed" ? stateTone : MS_BG, border: "2px solid " + stateTone, color: s.state === "passed" ? MS_BG : stateTone, display: "flex", alignItems: "center", justifyContent: "center", marginTop: 4, zIndex: 1 },
        }, _eh_icon(dotIcon, 12)),
      ]),
      React.createElement("div", { key: "body", style: { padding: "4px 0 16px 8px" } }, [
        React.createElement("div", {
          key: "h",
          style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 3 },
        }, [
          React.createElement("div", { key: "l", style: { display: "flex", gap: 8, alignItems: "center" } }, [
            React.createElement("span", { key: "stg", style: { fontFamily: MS_FONT_MONO, fontSize: 12, textTransform: "uppercase", letterSpacing: "0.06em", color: MS_INK_3 } }, "Stage " + s.stage),
            React.createElement("span", { key: "rl", style: { fontSize: 12, color: MS_INK } }, s.role),
          ]),
          _eh_MSPill({
            tone: s.state === "passed" ? "ok" : s.state === "pending" ? "warn" : s.state === "failed" ? "err" : "",
            children: s.state,
          }),
        ]),
        React.createElement("div", { key: "n", style: { fontSize: 12, color: MS_INK_3, lineHeight: 1.4, marginTop: 2 } }, [
          s.name !== "—" ? React.createElement("span", { key: "nm", style: { fontFamily: MS_FONT_MONO, fontSize: 12, color: MS_INK_2, marginRight: 8 } }, s.name) : null,
          s.ts   !== "—" ? React.createElement("span", { key: "ts", style: { fontFamily: MS_FONT_MONO, fontSize: 12, color: MS_INK_3 } }, s.ts) : null,
        ]),
        React.createElement("div", { key: "notes", style: { fontSize: 12, color: MS_INK_3, lineHeight: 1.4, marginTop: 4 } }, s.notes),
      ]),
    ]);
  }));
}

/* ────────────────────────────────────────────────────────────────────
   Sub-component — conversation thread
   ──────────────────────────────────────────────────────────────────── */

function _EH_Conversation(props) {
  const messages = props.messages;
  const [draft, setDraft] = uSEH("");
  const [posted, setPosted] = uSEH([]);
  const send = function() {
    const txt = draft.trim();
    if (!txt) return;
    setPosted(function(arr) {
      return arr.concat([{
        who: "Demo user",
        role: "Operator",
        ts: new Date().toISOString().slice(0, 16).replace("T", " "),
        body: txt,
        local: true,
      }]);
    });
    setDraft("");
    _eh_toast("Reply posted to ECO-MS-0017 thread", "ok");
  };
  const all = messages.concat(posted);
  return React.createElement("div", {
    style: { display: "flex", flexDirection: "column", gap: 12 },
  }, [
    React.createElement("div", {
      key: "thread",
      style: { display: "flex", flexDirection: "column", gap: 14 },
    }, all.map(function(m, i) {
      const initials = m.who.split(/\s+/).map(function(p) { return p[0]; }).join("").slice(0, 2).toUpperCase();
      const rowTone = m.local ? MS_ACCENT : MS_INK_3;
      return React.createElement("div", {
        key: i,
        style: {
          display: "grid",
          gridTemplateColumns: "26px 1fr",
          gap: 10,
          padding: "0 0 10px",
          borderBottom: i === all.length - 1 ? "none" : "1px dashed " + MS_LINE_SOFT,
        },
      }, [
        React.createElement("div", {
          key: "ava",
          style: {
            width: 26, height: 26, borderRadius: 26,
            background: "color-mix(in oklch, " + rowTone + " 12%, " + MS_BG_2 + ")",
            color: rowTone,
            border: "1px solid color-mix(in oklch, " + rowTone + " 28%, " + MS_LINE + ")",
            display: "flex", alignItems: "center", justifyContent: "center",
            fontFamily: MS_FONT_MONO, fontSize: 12, letterSpacing: "0.04em",
            fontWeight: 600,
          },
        }, initials),
        React.createElement("div", { key: "msg" }, [
          React.createElement("div", {
            key: "h",
            style: { display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 4 },
          }, [
            React.createElement("div", { key: "left" }, [
              React.createElement("span", {
                key: "n", style: { fontSize: 12, color: MS_INK, fontWeight: 500 },
              }, m.who),
              React.createElement("span", {
                key: "r",
                style: { fontSize: 12, color: MS_INK_3, marginLeft: 6 },
              }, "· " + m.role),
            ]),
            React.createElement("span", {
              key: "ts",
              style: {
                fontFamily: MS_FONT_MONO, fontSize: 12, color: MS_INK_3,
                fontVariantNumeric: "tabular-nums",
              },
            }, m.ts),
          ]),
          React.createElement("div", {
            key: "b",
            style: { fontSize: 12, color: MS_INK_2, lineHeight: 1.5 },
          }, m.body),
        ]),
      ]);
    })),
    React.createElement("div", {
      key: "compose",
      style: {
        marginTop: 4,
        border: "1px solid " + MS_LINE,
        borderRadius: 4,
        padding: 8,
        background: MS_BG,
      },
    }, [
      React.createElement("textarea", {
        key: "ta",
        value: draft,
        onChange: function(e) { setDraft(e.target.value); },
        placeholder: "Reply to thread… (mentions: @vogt @becker @klein)",
        rows: 2,
        style: {
          width: "100%",
          background: "transparent",
          border: 0,
          color: MS_INK,
          font: "inherit",
          fontSize: 12,
          resize: "none",
          outline: "none",
        },
      }),
      React.createElement("div", {
        key: "btns",
        style: { display: "flex", justifyContent: "flex-end", gap: 6, marginTop: 4 },
      }, [
        _eh_MSBtn({
          size: "sm", variant: "quiet",
          onClick: function() { setDraft(""); },
          children: "Clear",
        }),
        _eh_MSBtn({
          size: "sm", variant: "primary",
          onClick: send,
          disabled: !draft.trim(),
          children: [_eh_icon("Send", 12), React.createElement("span", { key: "l" }, " Send")],
        }),
      ]),
    ]),
  ]);
}

/* ════════════════════════════════════════════════════════════════════
   Top-level screen — ScreenMittelstandECO
   ──────────────────────────────────────────────────────────────────── */

function ScreenMittelstandECO() {
  const tenant = useActiveTenant();
  const tenantId = (tenant && tenant.tenant && tenant.tenant.id) || (typeof getActiveTenantId === "function" ? getActiveTenantId() : "tritan");
  // Pump-tenant fallback — render a tiny notice. This screen is mittelstand-only.
  if (tenantId !== "mittelstand") {
    return React.createElement("div", {
      style: {
        padding: 28, height: "100%",
        display: "flex", alignItems: "center", justifyContent: "center",
        background: MS_BG,
      },
    }, React.createElement("div", { style: { maxWidth: 540, textAlign: "center" } }, [
      React.createElement("div", {
        key: "h",
        className: "serif",
        style: { fontFamily: MS_FONT_SERIF, fontSize: 26, lineHeight: 1.15, marginBottom: 10, color: MS_INK },
      }, "Mittelstand ECO viewer"),
      React.createElement("div", {
        key: "m",
        style: { fontSize: 13, color: MS_INK_3, marginBottom: 18 },
      }, "Switch to the Mittelstand tenant to view ECO-MS-0017 (granite-bed flatness ±5 µm → ±3 µm)."),
      _eh_MSBtn({
        variant: "primary",
        onClick: function() {
          if (typeof setActiveTenant === "function") setActiveTenant("mittelstand");
          if (typeof navigate === "function") navigate("/build/eco");
        },
        children: "Switch to Mittelstand",
      }),
    ]));
  }

  // Wave 3C item 23 — pull live ECO list from tenant.
  const tenantEcos = (tenant && Array.isArray(tenant.eco)) ? tenant.eco : [];
  // Default selection — first in-review ECO from tenant; else hero; else first.
  const defaultId = (function() {
    const inReview = tenantEcos.find(function(e) { return (e.status || e.state) === "in-review"; });
    if (inReview) return inReview.id;
    const hero = tenantEcos.find(function(e) { return e.id === ECO_MS_0017.id; });
    if (hero) return hero.id;
    return (tenantEcos[0] && tenantEcos[0].id) || ECO_MS_0017.id;
  })();
  const [selId, setSelId] = uSEH(defaultId);
  const [decision, setDecision] = uSEH(null); // "approved" | "rejected" | "changes" | null
  // PPAP level form — used when Mittelstand Quality approve is fired.
  // Defaults to 3 per the brief example.
  const [ppapLevel, setPpapLevel] = uSEH(3);

  // selId drives which fixture entry is displayed; the rich detail only
  // renders for the hero ECO. Minor entries get _EH_MinimalDetailPanel.
  const eco = (selId === ECO_MS_0017.id || !tenantEcos.length)
    ? ECO_MS_0017
    : (tenantEcos.find(function(e) { return e.id === selId; }) || ECO_MS_0017);
  const isHeroSelected = (eco.id === ECO_MS_0017.id);

  // Wave 8C — track the live FSM status locally so successive verbs
  // (approve-quality → acknowledge-customer → release) can advance the
  // hero ECO through the chain without requiring a server round-trip
  // to update the visible button set. Initialized from fixture; reset
  // when the user selects a different ECO from the left list.
  const [currentStatus, setCurrentStatus] = uSEH(eco.status || "in-review");
  uEEH(function() {
    setCurrentStatus(eco.status || "in-review");
    setDecision(null);
  }, [selId]);

  // Wave 11C — stages are *derived* from (eco, currentStatus) instead of
  // being seeded once from ECO_MS_0017.approvals. This is the fix for the
  // demo-recording bug where a RELEASED ECO still showed PENDING/BLOCKED
  // rows and active Approve/Reject buttons. The previous useState seed
  // was a stale local cache that never re-read after a transition.
  const stages = uMEH(function() {
    return deriveMittelstandEcoStages(eco, currentStatus);
  }, [eco, currentStatus]);

  // Wave 7B item 24 — server-side transitions for Mittelstand.
  // FSM verbs: submit · approve-quality · acknowledge-customer · approve
  // (generic) · reject · release. `approve-quality` requires
  // body.ppap_level ∈ {1..5} (defaults from the ppapLevel state above).
  // `reject` requires body.ncr_id — we default to the ECO's first
  // linked_ncrs entry, falling back to "NCR-MS-0241" for the hero.
  // No `request-changes` verb exists; that button stays UI-only.
  //
  // Returns a Promise the caller can chain to surface server outcome via
  // toast. Optimistic local-state mutation still runs first; the SSE
  // refetch via useTenantState reconciles authoritative server state.
  function callTransition(verb, extra) {
    const fApi = (typeof window !== "undefined") ? window.forgeApi : null;
    const cur  = (typeof window !== "undefined" && window.__forgeCurrentUser) || { name: "S. Klein", role: "Quality" };
    if (!(fApi && fApi.eco && typeof fApi.eco.transition === "function")) {
      return Promise.reject(new Error("forgeApi.eco.transition unavailable"));
    }
    const body = Object.assign({ actor: cur.name, role: cur.role }, extra || {});
    return fApi.eco.transition(eco.id, verb, body);
  }

  // Pull the first linked NCR for the rejection body. Mittelstand's reject
  // FSM rejects 400 if ncr_id is absent (see server/state-machines/
  // mittelstand.js requiresNcr). The hero ECO has linked_ncrs: ["NCR-MS-0241",
  // ...]; minor ECOs may lack the field, in which case we fall back to the
  // hero's first NCR so the demo never silently breaks.
  function pickNcrId() {
    if (Array.isArray(eco.linked_ncrs) && eco.linked_ncrs.length) return eco.linked_ncrs[0];
    if (typeof eco.linked_ncr === "string" && eco.linked_ncr) return eco.linked_ncr;
    return "NCR-MS-0241";
  }

  const handleApprove = function() {
    // Wave 11C: stages now derive from currentStatus; no manual stamping.
    setDecision("approved");
    setCurrentStatus("quality-approved");
    _eh_toast(eco.id + " approved · PPAP Level " + ppapLevel + " · stages 3 + 4 advanced", "ok");
    callTransition("approve-quality", { ppap_level: ppapLevel }).then(function(result) {
      if (result && result.eco) {
        _eh_toast(eco.id + " · server state · " + result.eco.status, "ok");
        if (result.eco.status) setCurrentStatus(result.eco.status);
      }
    }).catch(function(err) {
      const msg = (err && err.message) || String(err);
      console.error("[mittelstand-eco] approve-quality failed", err);
      _eh_toast(eco.id + " approve failed · " + msg, "err");
    });
  };

  // Wave 8C — submit verb: draft → in-review.
  const handleSubmit = function() {
    setCurrentStatus("in-review");
    _eh_toast(eco.id + " submitted for review", "info");
    callTransition("submit", {}).then(function(result) {
      if (result && result.eco) {
        _eh_toast(eco.id + " · server state · " + result.eco.status, "ok");
        if (result.eco.status) setCurrentStatus(result.eco.status);
      }
    }).catch(function(err) {
      const msg = (err && err.message) || String(err);
      console.error("[mittelstand-eco] submit failed", err);
      _eh_toast(eco.id + " submit failed · " + msg, "err");
    });
  };

  // Wave 8C — acknowledge-customer: quality-approved → customer-acknowledged.
  // The Mittelstand FSM's stamp pass looks for a "Customer Quality" chain
  // entry. The tenant.people roster has no such role, so we fall back to
  // "Plant Director" (K. Hofer) — the role with eco.* permission scope.
  // The FSM does not enforce role auth, so the transition succeeds either
  // way; the role choice only affects approval_chain stamping.
  const handleAcknowledgeCustomer = function() {
    const fApi = (typeof window !== "undefined") ? window.forgeApi : null;
    const cur  = (typeof window !== "undefined" && window.__forgeCurrentUser) || { name: "K. Hofer", role: "Plant Director" };
    // If the active user is already Customer Quality, honor that; otherwise
    // override to Plant Director so the stamp call has a sane fallback.
    const isCustomerQuality = typeof cur.role === "string" && /customer\s*quality/i.test(cur.role);
    const ackActor = isCustomerQuality ? cur.name : "K. Hofer";
    const ackRole  = isCustomerQuality ? cur.role : "Plant Director";
    setCurrentStatus("customer-acknowledged");
    // Wave 11C: stages now derive from currentStatus; no manual stamping.
    _eh_toast("Customer (MAHLE Industriebeteiligungen) acknowledged", "ok");
    if (!(fApi && fApi.eco && typeof fApi.eco.transition === "function")) return;
    fApi.eco.transition(eco.id, "acknowledge-customer", { actor: ackActor, role: ackRole }).then(function(result) {
      if (result && result.eco) {
        _eh_toast(eco.id + " · server state · " + result.eco.status, "ok");
        if (result.eco.status) setCurrentStatus(result.eco.status);
      }
    }).catch(function(err) {
      const msg = (err && err.message) || String(err);
      console.error("[mittelstand-eco] acknowledge-customer failed", err);
      _eh_toast(eco.id + " acknowledge failed · " + msg, "err");
    });
  };

  // Wave 8C — release: customer-acknowledged (or approved) → released.
  const handleRelease = function() {
    setCurrentStatus("released");
    _eh_toast(eco.id + " released to production", "ok");
    callTransition("release", {}).then(function(result) {
      if (result && result.eco) {
        _eh_toast(eco.id + " · server state · " + result.eco.status, "ok");
        if (result.eco.status) setCurrentStatus(result.eco.status);
      }
    }).catch(function(err) {
      const msg = (err && err.message) || String(err);
      console.error("[mittelstand-eco] release failed", err);
      _eh_toast(eco.id + " release failed · " + msg, "err");
    });
  };

  const handleReject = function() {
    const ncrId = pickNcrId();
    // Wave 11C: stages now derive from currentStatus + approval_chain;
    // server's reject verb stamps the chain entry as "rejected" and the
    // SSE refetch propagates it. UI-only fallback is the synthetic
    // "Quality rejecting" default in _eh_stageStatesForStatus.
    setDecision("rejected");
    setCurrentStatus("rejected");
    _eh_toast(eco.id + " rejected · NCR " + ncrId + " linked · returned to engineering", "err");
    callTransition("reject", { ncr_id: ncrId }).then(function(result) {
      if (result && result.eco) {
        _eh_toast(eco.id + " · server state · " + result.eco.status, "err");
        if (result.eco.status) setCurrentStatus(result.eco.status);
      }
    }).catch(function(err) {
      const msg = (err && err.message) || String(err);
      console.error("[mittelstand-eco] reject failed", err);
      _eh_toast(eco.id + " reject failed · " + msg, "err");
    });
  };

  const handleChanges = function() {
    // No `request-changes` verb in the Mittelstand FSM (verbs: submit,
    // approve-quality, acknowledge-customer, approve, reject, release).
    // This button stays UI-only; SSE refetch will not touch it. We keep
    // currentStatus at "in-review" so the derived stages still show
    // Quality as pending.
    setDecision("changes");
    _eh_toast("Changes requested · pinged @vogt + @becker on thread · (UI-only, no FSM verb)", "warn");
  };

  return React.createElement("div", {
    style: {
      padding: 14,
      display: "grid",
      gridTemplateColumns: "320px minmax(0, 1fr) 360px",
      gap: 14,
      minHeight: 0,
      height: "100%",
      background: MS_BG_3,
    },
  }, [
    /* ── LEFT panel · ECO list ─────────────────────────────────────── */
    React.createElement("div", {
      key: "left",
      style: { display: "flex", flexDirection: "column", minHeight: 0 },
    }, _EH_EcoList({ selectedId: selId, onSelect: setSelId, ecos: tenantEcos })),

    /* ── MIDDLE panel · ECO detail (rich only for hero; minimal otherwise) ─ */
    !isHeroSelected ? React.createElement("div", { key: "mid" }, _EH_MinimalDetailPanel({ eco: eco })) :
    _eh_MSCard({
      key: "mid",
      title: eco.id + " · " + eco.title,
      right: [
        _eh_MSPill({
          key: "sev",
          tone: "err",
          children: "severity · critical",
        }),
        _eh_MSPill({
          key: "state",
          tone:
            currentStatus === "released" || currentStatus === "customer-acknowledged" || currentStatus === "quality-approved" ? "ok" :
            currentStatus === "rejected" ? "err" :
            decision === "changes" ? "warn" : "warn",
          children: currentStatus || "in-review",
        }),
      ],
      children: React.createElement("div", {
        style: { padding: 16, display: "flex", flexDirection: "column", gap: 18 },
      }, [
        /* trigger banner */
        React.createElement("div", { key: "trig" }, _EH_TriggerBanner()),

        /* impact tiles */
        React.createElement("div", { key: "impact-section" }, [
          React.createElement("div", {
            key: "h",
            className: "serif",
            style: {
              fontFamily: MS_FONT_SERIF, fontSize: 24, lineHeight: 1.2,
              color: MS_INK, marginBottom: 8,
            },
          }, "Impact"),
          _EH_ImpactTiles(),
        ]),

        /* part-numbers affected */
        React.createElement("div", { key: "parts-section" }, [
          React.createElement("div", {
            key: "h",
            className: "serif",
            style: {
              fontFamily: MS_FONT_SERIF, fontSize: 18, lineHeight: 1.2,
              color: MS_INK, marginBottom: 8,
            },
          }, "Parts affected"),
          React.createElement("div", {
            key: "rows",
            style: { display: "flex", flexDirection: "column", gap: 6 },
          }, eco.parts.map(function(p) {
            return React.createElement("div", {
              key: p.num,
              style: {
                padding: "10px 12px",
                background: MS_BG,
                border: "1px solid " + MS_LINE_SOFT,
                borderRadius: 4,
                display: "grid",
                gridTemplateColumns: "100px 1.5fr 1fr 1fr",
                gap: 12,
                alignItems: "center",
              },
            }, [
              React.createElement("span", {
                key: "n",
                style: {
                  fontFamily: MS_FONT_MONO, fontSize: 13, color: MS_INK,
                  fontVariantNumeric: "tabular-nums", letterSpacing: "0.02em",
                },
              }, "MTL-220." + p.num),
              React.createElement("span", {
                key: "name",
                style: { fontSize: 12, color: MS_INK_2 },
              }, p.name),
              React.createElement("span", {
                key: "before",
                style: {
                  fontFamily: MS_FONT_MONO, fontSize: 12, color: MS_INK_3,
                },
              }, p.before),
              React.createElement("span", {
                key: "after",
                style: {
                  fontFamily: MS_FONT_MONO, fontSize: 12, color: MS_ACCENT_OK,
                },
              }, p.after),
            ]);
          })),
        ]),

        /* before/after table */
        React.createElement("div", { key: "ba-section" }, [
          React.createElement("div", {
            key: "h",
            className: "serif",
            style: {
              fontFamily: MS_FONT_SERIF, fontSize: 18, lineHeight: 1.2,
              color: MS_INK, marginBottom: 8,
            },
          }, "Before · Rev C  →  After · Rev D"),
          _EH_BeforeAfterTable(),
        ]),

        /* field returns */
        React.createElement("div", { key: "fr-section" }, [
          React.createElement("div", {
            key: "h",
            className: "serif",
            style: {
              fontFamily: MS_FONT_SERIF, fontSize: 18, lineHeight: 1.2,
              color: MS_INK, marginBottom: 8,
            },
          }, "Field returns · Rev C feeders"),
          _EH_FieldReturns(),
        ]),

        /* compliance tags */
        React.createElement("div", { key: "comp-section" }, [
          React.createElement("div", {
            key: "h",
            style: {
              fontFamily: MS_FONT_MONO, fontSize: 12, letterSpacing: "0.06em",
              textTransform: "uppercase", color: MS_INK_3, marginBottom: 6,
            },
          }, "Compliance scope"),
          React.createElement("div", {
            key: "tags",
            style: { display: "flex", flexWrap: "wrap", gap: 6 },
          }, [
            "IATF 16949 §8.5.6 (change control)",
            "ISO 9001 §8.3.6 (design changes)",
            "EN ISO 230-2 (geometric performance)",
            "PPAP Level 3 re-submission",
            "AS9102 form set re-issue",
            "CE / Machinery Dir. 2006/42/EC",
          ].map(function(t) {
            return React.createElement("span", {
              key: t,
              style: {
                padding: "4px 10px",
                background: MS_BG,
                border: "1px solid " + MS_LINE_SOFT,
                borderRadius: 3,
                fontFamily: MS_FONT_MONO, fontSize: 12,
                color: MS_INK_3, letterSpacing: "0.02em",
              },
            }, t);
          })),
        ]),
      ]),
    }),

    /* ── RIGHT panel · stack of approval ladder + actions + thread ─── */
    React.createElement("div", {
      key: "right",
      style: { display: "flex", flexDirection: "column", gap: 14, minHeight: 0 },
    }, [
      /* approval ladder card */
      _eh_MSCard({
        key: "ladder",
        title: "Approval ladder · 5-stage",
        right: _eh_MSPill({
          tone: stages.every(function(s) { return s.state === "passed"; }) ? "ok" :
                stages.some(function(s)  { return s.state === "failed"; }) ? "err" : "warn",
          children: stages.filter(function(s) { return s.state === "passed"; }).length + "/" + stages.length + " passed",
        }),
        children: React.createElement("div", { style: { padding: "12px 14px" } }, [
          _EH_ApprovalLadder({ stages: stages }),

          /* Wave 3C item 24 — PPAP level form (body for approve-quality verb).
             Wave 11C: only render when the ECO is in-review (i.e. Quality
             is the next-pending stage and the Approve button is visible).
             Hidden in terminal states (released / rejected / applied) and
             also hidden when Quality has already approved. */
          (currentStatus === "in-review") ? React.createElement("div", {
            key: "ppap",
            style: {
              marginTop: 12, paddingTop: 12,
              borderTop: "1px dashed " + MS_LINE_SOFT,
              display: "flex", alignItems: "center", gap: 8,
            },
          }, [
            React.createElement("label", {
              key: "lbl",
              htmlFor: "ms-ppap-level",
              style: {
                fontFamily: MS_FONT_MONO, fontSize: 12, letterSpacing: "0.06em",
                textTransform: "uppercase", color: MS_INK_3,
              },
            }, "PPAP level"),
            React.createElement("select", {
              key: "sel",
              id: "ms-ppap-level",
              value: String(ppapLevel),
              onChange: function(ev) { setPpapLevel(Number(ev.target.value)); },
              style: {
                fontFamily: MS_FONT_MONO, fontSize: 13, padding: "4px 8px",
                background: MS_BG, color: MS_INK,
                border: "1px solid " + MS_LINE_SOFT, borderRadius: 3,
              },
            }, [1, 2, 3, 4, 5].map(function(n) {
              return React.createElement("option", { key: n, value: String(n) }, "Level " + n);
            })),
            React.createElement("span", {
              key: "hint",
              style: { fontFamily: MS_FONT_MONO, fontSize: 12, color: MS_INK_3 },
            }, "IATF 16949 PPAP submission level"),
          ]) : null,

          /* Wave 8C — state-machine-aware action buttons.
             Verb gating by currentStatus per server/state-machines/mittelstand.js:
               submit              from: draft               → in-review
               approve-quality     from: in-review           → quality-approved (requires ppap_level 1..5)
               acknowledge-customer from: quality-approved   → customer-acknowledged (Customer Quality / Plant Director fallback)
               release             from: customer-acknowledged | approved → released
               reject              from: in-review | quality-approved | customer-acknowledged → rejected (requires ncr_id)
             Request-changes has no FSM verb; UI-only escape hatch retained. */
          React.createElement("div", {
            key: "actions",
            style: {
              marginTop: 12,
              paddingTop: 12,
              borderTop: "1px dashed " + MS_LINE_SOFT,
              display: "grid",
              gridTemplateColumns: "1fr 1fr",
              gap: 6,
            },
          }, (function() {
            const btns = [];
            const isReleased  = currentStatus === "released";
            const isRejected  = currentStatus === "rejected";
            const isApplied   = currentStatus === "applied";
            const isTerminal  = isReleased || isRejected || isApplied;
            const canSubmit   = currentStatus === "draft";
            const canApproveQ = currentStatus === "in-review";
            const canAckCust  = currentStatus === "quality-approved";
            const canRelease  = currentStatus === "customer-acknowledged" || currentStatus === "approved";
            const canReject   = currentStatus === "in-review" || currentStatus === "quality-approved" || currentStatus === "customer-acknowledged";

            if (canSubmit) {
              btns.push(_eh_MSBtn({
                key: "sb",
                variant: "primary",
                size: "md",
                onClick: handleSubmit,
                children: [_eh_icon("ArrowRight", 13), React.createElement("span", { key: "l" }, " Submit for review")],
              }));
            }
            if (canApproveQ) {
              btns.push(_eh_MSBtn({
                key: "ap",
                variant: "primary",
                size: "md",
                onClick: handleApprove,
                children: [_eh_icon("Check", 13), React.createElement("span", { key: "l" }, " Approve quality (PPAP " + ppapLevel + ")")],
              }));
            }
            if (canAckCust) {
              btns.push(_eh_MSBtn({
                key: "ack",
                variant: "primary",
                size: "md",
                onClick: handleAcknowledgeCustomer,
                children: [_eh_icon("Check", 13), React.createElement("span", { key: "l" }, " Acknowledge customer")],
              }));
            }
            if (canRelease) {
              btns.push(_eh_MSBtn({
                key: "rel",
                variant: "primary",
                size: "md",
                onClick: handleRelease,
                children: [_eh_icon("Check", 13), React.createElement("span", { key: "l" }, " Release")],
              }));
            }
            // Wave 11C — Reject hidden (not just disabled) in terminal states.
            // The previous disabled-but-visible pattern paired with stale
            // hardcoded stages was the demo-recording bug surface.
            if (canReject && !isTerminal) {
              btns.push(_eh_MSBtn({
                key: "rj",
                variant: "danger",
                size: "md",
                onClick: handleReject,
                children: [_eh_icon("X", 13), React.createElement("span", { key: "l" }, " Reject")],
              }));
            }
            // Terminal state hint
            if (isTerminal) {
              btns.push(React.createElement("div", {
                key: "terminal",
                style: { gridColumn: "1 / span 2", fontFamily: MS_FONT_MONO, fontSize: 12, color: MS_INK_3, textAlign: "center", padding: "6px 0" },
              }, isReleased
                ? "RELEASED · ledger arc closed"
                : isApplied
                  ? "APPLIED · routing updated"
                  : "REJECTED · returned to engineering"));
            }
            // Request-changes — UI-only escape hatch, present while not terminal.
            if (!isTerminal) {
              btns.push(React.createElement("div", { key: "wide", style: { gridColumn: "1 / span 2" } },
                _eh_MSBtn({
                  variant: "ghost",
                  size: "md",
                  onClick: handleChanges,
                  disabled: decision === "changes",
                  children: [_eh_icon("MessageSquare", 13), React.createElement("span", { key: "l" }, " Request changes")],
                })
              ));
            }
            return btns;
          })()),

          /* metadata footer */
          React.createElement("div", {
            key: "meta",
            style: {
              marginTop: 10,
              paddingTop: 10,
              borderTop: "1px dashed " + MS_LINE_SOFT,
              fontFamily: MS_FONT_MONO, fontSize: 12,
              color: MS_INK_3, lineHeight: 1.6,
            },
          }, [
            React.createElement("div", { key: "1" }, "Raised by " + eco.raised_by + " · " + _eh_date(eco.date_raised, eco.date_raised)),
            React.createElement("div", { key: "2" }, "Customer · MAHLE Industriebeteiligungen GmbH"),
            React.createElement("div", { key: "3" }, "Program · MTL-220 Rev D · 24-unit batch"),
            React.createElement("div", { key: "4" }, "FAI target · " + _eh_date("2026-08-14", "2026-08-14")),
          ]),
        ]),
      }),

      /* conversation card */
      _eh_MSCard({
        key: "thread",
        title: "Conversation · 3-way",
        right: _eh_MSPill({ tone: "info", children: eco.conversation.length + " messages" }),
        children: React.createElement("div", { style: { padding: 14, minHeight: 0 } },
          _EH_Conversation({ messages: eco.conversation })
        ),
      }),
    ]),
  ]);
}

/* ────────────────────────────────────────────────────────────────────
   Globals + route registration
   ──────────────────────────────────────────────────────────────────── */

if (typeof window !== "undefined") {
  window.ScreenMittelstandECO = ScreenMittelstandECO;
  // Also expose under a tenant-routing override symbol the registry-router
  // (agent #3) can pick up when active tenant id is "mittelstand".
  window.MittelstandECOOverride = ScreenMittelstandECO;
}

// Prefer registerMittelstandRoute from registry-index.jsx (agent #3); fall
// back to registerPumpRoute so this screen still resolves when the merge-
// with-tenant patch hasn't landed yet. Either way, `/build/eco` resolves
// to the mittelstand renderer when the tenant is active.
(function _registerEcoHero() {
  const route = {
    path: "/build/eco",
    mode: "build",
    title: "ECO · Granite flatness",
    tenant: "mittelstand",
    renderer: function() { return React.createElement(ScreenMittelstandECO); },
  };
  if (typeof window === "undefined") return;
  if (typeof window.registerMittelstandRoute === "function") {
    window.registerMittelstandRoute(route);
    return;
  }
  // fallback — register against pump route table; the App router already
  // merges PUMP_ROUTES first, so this resolves provided the tenant guard
  // inside ScreenMittelstandECO renders the friendly redirect for non-MS.
  if (typeof window.registerPumpRoute === "function") {
    window.registerPumpRoute(route);
    return;
  }
  // last-resort — push onto a deferred registration queue for cross-cutting
  // to drain once the registry exists.
  window.__MITTELSTAND_PENDING_ROUTES = (window.__MITTELSTAND_PENDING_ROUTES || []).concat([route]);
})();
})();
