/* FORGE — cross-cutting affordances for the Mittelstand-pilot Werkzeugbau demo.
   Single file. Babel-standalone in-browser pattern. NO ES imports / exports.

   Tone: cool gray, German-precision, no warm cast. Mono-privileged.
   Hex anchors (spec §1):  #1f2328 anthracite · #6b7480 steel · #b8bcc4 graphite
   oklch counterparts (spec §10) live in :root vars below.

   Atom catalog (all attached to window):
     1.  MSCard         — flat 1px-border card, zero shadow, restrained padding
     2.  MSPill         — mono pill badge: pass · fail · warn · neutral · info
     3.  MSBtn          — primary / ghost / destructive button variants
     4.  MSToolbar      — top toolbar shell with left/right slots
     5.  MSStatRow      — KPI label/value row, mono on values when asked
     6.  MSSectionTitle — section heading with optional kicker
     7.  MSFlash        — toast / inline flash card with kind tone
     8.  MSPalette      — Mittelstand-flavored ⌘K command palette
     9.  MSNotificationBell — derived alert bell for the cockpit
     10. MSCrossCuttingMount — composite mount helper

   Tolerances render in µm. Cost in €. Lead-time in d. Mass / power not relevant.
*/

const {
  useState: uSMS,
  useEffect: uEMS,
  useMemo:  uMMS,
  useRef:   uRMS,
} = React;

// ──────────────────────────────────────────────────────────────────────
// 1. CSS variable injection — anthracite / steel / graphite cool gray
// ──────────────────────────────────────────────────────────────────────

(function msInjectVars() {
  if (typeof document === "undefined") return;
  if (document.getElementById("ms-cross-cutting-vars")) return;
  const css = ""
    + ":root {\n"
    // raw hex anchors from spec §1
    + "  --mittel-anthracite: #1f2328;\n"
    + "  --mittel-steel:      #6b7480;\n"
    + "  --mittel-graphite:   #b8bcc4;\n"
    // oklch surface stack (spec §10)
    + "  --mittel-bg:         oklch(0.97  0.003 250);\n"
    + "  --mittel-bg-2:       oklch(0.92  0.004 250);\n"
    + "  --mittel-bg-3:       oklch(0.95  0.003 250);\n"
    + "  --mittel-bg-inset:   oklch(0.99  0.002 250);\n"
    // ink stack
    + "  --mittel-fg:         oklch(0.18  0.01  250);\n"
    + "  --mittel-ink:        oklch(0.18  0.01  250);\n"
    + "  --mittel-ink-2:      oklch(0.32  0.01  250);\n"
    + "  --mittel-ink-3:      oklch(0.48  0.01  250);\n"
    + "  --mittel-ink-4:      oklch(0.62  0.005 250);\n"
    // rule lines
    + "  --mittel-border:     oklch(0.82  0.005 250);\n"
    + "  --mittel-line:       oklch(0.82  0.005 250);\n"
    + "  --mittel-line-soft:  oklch(0.88  0.004 250);\n"
    // accent + status
    + "  --mittel-accent:     oklch(0.50  0.02  250);\n"
    + "  --mittel-accent-ink: #ffffff;\n"
    + "  --mittel-pass:       oklch(0.50  0.10 155);\n"
    + "  --mittel-warn:       oklch(0.55  0.13  60);\n"
    + "  --mittel-fail:       oklch(0.55  0.18  25);\n"
    + "  --mittel-info:       oklch(0.50  0.06 250);\n"
    // "-accent-warn" / "-accent-bad" naming, used by dashboard/eco-hero/line/
    // act5-6/travelers/ledger-events alongside the names above
    + "  --mittel-accent-warn: oklch(0.55  0.13  60);\n"
    + "  --mittel-accent-bad:  oklch(0.55  0.18  25);\n"
    // typography
    + "  --mittel-mono:       \"Geist Mono\", ui-monospace, \"SF Mono\", Menlo, monospace;\n"
    + "  --mittel-ui:         \"Inter Tight\", ui-sans-serif, system-ui, -apple-system, sans-serif;\n"
    + "  --mittel-serif:      \"Instrument Serif\", ui-serif, Georgia, serif;\n"
    + "}\n";
  const style = document.createElement("style");
  style.id = "ms-cross-cutting-vars";
  style.appendChild(document.createTextNode(css));
  document.head.appendChild(style);
})();

// Local style atoms (so internal components don't have to read CSS vars
// every render — matches the pump cross-cutting pattern).
const MS_BG        = "var(--mittel-bg)";
const MS_BG_2      = "var(--mittel-bg-2)";
const MS_BG_3      = "var(--mittel-bg-3)";
const MS_BG_INSET  = "var(--mittel-bg-inset)";
const MS_INK       = "var(--mittel-ink)";
const MS_INK_2     = "var(--mittel-ink-2)";
const MS_INK_3     = "var(--mittel-ink-3)";
const MS_INK_4     = "var(--mittel-ink-4)";
const MS_LINE      = "var(--mittel-line)";
const MS_LINE_SOFT = "var(--mittel-line-soft)";
const MS_ACCENT    = "var(--mittel-accent)";
const MS_PASS      = "var(--mittel-pass)";
const MS_WARN      = "var(--mittel-warn)";
const MS_FAIL      = "var(--mittel-fail)";
const MS_INFO      = "var(--mittel-info)";
const MS_MONO      = "var(--mittel-mono)";
const MS_UI        = "var(--mittel-ui)";

// ──────────────────────────────────────────────────────────────────────
// Tone resolver for pills + flashes
// ──────────────────────────────────────────────────────────────────────

function msToneFor(tone) {
  switch (tone) {
    case "pass":
      return { fg: "#fff", bg: MS_PASS, border: MS_PASS, label: "pass" };
    case "fail":
      return { fg: "#fff", bg: MS_FAIL, border: MS_FAIL, label: "fail" };
    case "warn":
      return { fg: "#1f2328", bg: "oklch(0.88 0.08 80)", border: MS_WARN, label: "warn" };
    case "info":
      return { fg: "#fff", bg: MS_INFO, border: MS_INFO, label: "info" };
    case "neutral":
    default:
      return { fg: MS_INK_2, bg: MS_BG_3, border: MS_LINE, label: "neutral" };
  }
}

// ──────────────────────────────────────────────────────────────────────
// 1. MSCard — flat 1px-border card, zero shadow
// ──────────────────────────────────────────────────────────────────────

function MSCard(props) {
  const pad = (typeof props.pad === "number") ? props.pad : 14;
  const style = Object.assign({
    background: MS_BG,
    color: MS_INK,
    border: "1px solid " + MS_LINE,
    borderRadius: 4,
    padding: pad,
    boxShadow: "none",
    fontFamily: MS_UI,
  }, props.style || {});
  return React.createElement("div", { style: style, className: props.className }, props.children);
}

// ──────────────────────────────────────────────────────────────────────
// 2. MSPill — mono pill badge, 11px, tones pass/fail/warn/neutral/info
// ──────────────────────────────────────────────────────────────────────

function MSPill(props) {
  const tone = msToneFor(props.tone || "neutral");
  return React.createElement(
    "span",
    {
      style: {
        display: "inline-flex",
        alignItems: "center",
        gap: 4,
        padding: "1px 7px",
        borderRadius: 3,
        fontFamily: MS_MONO,
        fontSize: 12,
        lineHeight: "16px",
        letterSpacing: "0.04em",
        textTransform: props.upper === false ? "none" : "uppercase",
        color: tone.fg,
        background: tone.bg,
        border: "1px solid " + tone.border,
        whiteSpace: "nowrap",
      },
      title: props.title,
    },
    props.children == null ? tone.label : props.children
  );
}

// ──────────────────────────────────────────────────────────────────────
// 3. MSBtn — variants: primary | ghost | destructive
// ──────────────────────────────────────────────────────────────────────

function msBtnStyle(variant, small, hover) {
  const h = small ? 24 : 30;
  const base = {
    height: h,
    padding: small ? "0 10px" : "0 14px",
    borderRadius: 4,
    fontFamily: MS_MONO,
    fontSize: small ? 11 : 12,
    letterSpacing: "0.03em",
    cursor: "pointer",
    display: "inline-flex",
    alignItems: "center",
    justifyContent: "center",
    gap: 6,
    boxShadow: "none",
    transition: "background .14s ease, color .14s ease, border-color .14s ease",
  };
  if (variant === "destructive") {
    return Object.assign({}, base, {
      background: hover ? "oklch(0.50 0.18 25)" : MS_FAIL,
      color: "#fff",
      border: "1px solid " + MS_FAIL,
    });
  }
  if (variant === "ghost") {
    return Object.assign({}, base, {
      background: hover ? MS_BG_2 : "transparent",
      color: MS_INK_2,
      border: "1px solid " + MS_LINE,
    });
  }
  // primary (default)
  return Object.assign({}, base, {
    background: hover ? "#1f2328" : MS_INK,
    color: "#fff",
    border: "1px solid " + MS_INK,
  });
}

function MSBtn(props) {
  const [hover, setHover] = uSMS(false);
  const variant = props.variant || "primary";
  return React.createElement(
    "button",
    {
      type: props.type || "button",
      onClick: props.onClick,
      disabled: !!props.disabled,
      onMouseEnter: function() { setHover(true); },
      onMouseLeave: function() { setHover(false); },
      title: props.title,
      style: Object.assign(
        msBtnStyle(variant, !!props.small, hover && !props.disabled),
        props.disabled
          ? { opacity: 0.55, cursor: "not-allowed", filter: "grayscale(0.4)" }
          : null,
        props.style || {}
      ),
    },
    props.children
  );
}

// ──────────────────────────────────────────────────────────────────────
// 4. MSToolbar — top toolbar pattern, left/right slots, fixed height
// ──────────────────────────────────────────────────────────────────────

function MSToolbar(props) {
  const h = props.height || 44;
  return React.createElement(
    "div",
    {
      style: {
        height: h,
        display: "flex",
        alignItems: "center",
        justifyContent: "space-between",
        padding: "0 16px",
        background: MS_BG,
        borderBottom: "1px solid " + MS_LINE,
        fontFamily: MS_UI,
        color: MS_INK,
        gap: 12,
      },
    },
    React.createElement(
      "div",
      { style: { display: "flex", alignItems: "center", gap: 10, minWidth: 0, flex: 1 } },
      props.left || null
    ),
    React.createElement(
      "div",
      { style: { display: "flex", alignItems: "center", gap: 10, flexShrink: 0 } },
      props.right || null
    )
  );
}

// ──────────────────────────────────────────────────────────────────────
// 5. MSStatRow — KPI label / value row
// ──────────────────────────────────────────────────────────────────────

function MSStatRow(props) {
  const mono = props.mono !== false;
  return React.createElement(
    "div",
    {
      style: Object.assign({
        display: "flex",
        alignItems: "baseline",
        justifyContent: "space-between",
        gap: 12,
        padding: "6px 0",
        borderBottom: "1px solid " + MS_LINE_SOFT,
      }, props.style || {}),
    },
    React.createElement(
      "span",
      {
        style: {
          fontFamily: MS_MONO,
          fontSize: 12,
          letterSpacing: "0.08em",
          textTransform: "uppercase",
          color: MS_INK_3,
        },
      },
      props.label
    ),
    React.createElement(
      "span",
      {
        style: {
          fontFamily: mono ? MS_MONO : MS_UI,
          fontSize: 13,
          color: MS_INK,
          textAlign: "right",
        },
      },
      props.value
    )
  );
}

// ──────────────────────────────────────────────────────────────────────
// 6. MSSectionTitle — kicker + heading
// ──────────────────────────────────────────────────────────────────────

function MSSectionTitle(props) {
  return React.createElement(
    "div",
    {
      style: Object.assign({
        marginBottom: 8,
        fontFamily: MS_UI,
        color: MS_INK,
      }, props.style || {}),
    },
    props.kicker
      ? React.createElement(
          "div",
          {
            style: {
              fontFamily: MS_MONO,
              fontSize: 12,
              letterSpacing: "0.10em",
              textTransform: "uppercase",
              color: MS_INK_3,
              marginBottom: 2,
            },
          },
          props.kicker
        )
      : null,
    React.createElement(
      "div",
      {
        style: {
          fontSize: 16,
          fontWeight: 600,
          letterSpacing: "-0.005em",
          color: MS_INK,
          lineHeight: 1.25,
        },
      },
      props.children
    )
  );
}

// ──────────────────────────────────────────────────────────────────────
// 7. MSFlash — toast / inline flash card
// ──────────────────────────────────────────────────────────────────────

function MSFlash(props) {
  const tone = msToneFor(props.kind || "info");
  return React.createElement(
    "div",
    {
      role: "status",
      style: {
        display: "flex",
        alignItems: "flex-start",
        gap: 10,
        padding: "10px 12px",
        background: MS_BG,
        border: "1px solid " + MS_LINE,
        borderLeft: "3px solid " + tone.bg,
        borderRadius: 4,
        fontFamily: MS_UI,
        color: MS_INK,
        boxShadow: "none",
      },
    },
    React.createElement(MSPill, { tone: props.kind || "info" }),
    React.createElement(
      "div",
      {
        style: {
          flex: 1,
          fontSize: 13,
          lineHeight: 1.45,
          color: MS_INK_2,
        },
      },
      props.msg
    ),
    props.onClose
      ? React.createElement(
          "button",
          {
            onClick: props.onClose,
            "aria-label": "dismiss",
            style: {
              background: "transparent",
              border: 0,
              color: MS_INK_3,
              fontFamily: MS_MONO,
              fontSize: 14,
              cursor: "pointer",
              padding: "0 2px",
              lineHeight: 1,
            },
          },
          "×"
        )
      : null
  );
}

// ──────────────────────────────────────────────────────────────────────
// 8. MSPalette — ⌘K command palette, Mittelstand flavor
// ──────────────────────────────────────────────────────────────────────

function msScore(query, label) {
  if (!query) return 0;
  const q = String(query).toLowerCase();
  const l = String(label || "").toLowerCase();
  if (l.length === 0) return -1;
  if (l === q) return 1000;
  if (l.startsWith(q)) return 800;
  const parts = l.split(/[^a-z0-9]+/);
  for (let i = 0; i < parts.length; i++) {
    if (parts[i].startsWith(q)) return 600;
  }
  if (l.indexOf(q) >= 0) return 400;
  return -1;
}

function msBuildIndex() {
  const out = {
    Screens:        [],
    Parts:          [],
    BOMs:           [],
    Suppliers:      [],
    "Work Orders":  [],
    Travelers:      [],
    "Recent Events": [],
  };

  // Routes — built-in plus any Mittelstand registry
  const builtin = (typeof window !== "undefined" && Array.isArray(window.BUILTIN_ROUTES)) ? window.BUILTIN_ROUTES : [];
  const ms      = (typeof window !== "undefined" && Array.isArray(window.MITTELSTAND_ROUTES)) ? window.MITTELSTAND_ROUTES : [];
  const allRoutes = builtin.concat(ms);
  for (let i = 0; i < allRoutes.length; i++) {
    const r = allRoutes[i];
    out.Screens.push({
      kind: "screen",
      label: r.title || r.path,
      path: r.path,
      mode: r.mode,
      hint: r.path,
    });
  }

  const tenant = (typeof getActiveTenant === "function") ? getActiveTenant() : null;
  if (!tenant) return out;

  // Parts — tolerance + lead in mono units
  const parts = (tenant.parts || []).slice(0, 40);
  for (let i = 0; i < parts.length; i++) {
    const p = parts[i];
    const hintBits = [];
    if (p.supplier) hintBits.push(p.supplier);
    if (p.lead_days != null) hintBits.push(p.lead_days + " d");
    if (p.unit_cost_eur != null) hintBits.push("€" + p.unit_cost_eur.toLocaleString("de-DE"));
    if (p.tolerance_um != null) hintBits.push("±" + p.tolerance_um + " µm");
    out.Parts.push({
      kind: "part",
      label: p.num + " · " + p.name,
      path: "/forge/ebom",
      hint: hintBits.join(" · "),
    });
  }

  // BOMs
  const boms = (tenant.boms || []);
  for (let i = 0; i < boms.length; i++) {
    out.BOMs.push({
      kind: "bom",
      label: boms[i].sku,
      path: "/forge/ebom",
      hint: (boms[i].lines || []).length + " lines",
    });
  }

  // Suppliers — call out spindle / control / head focus
  const sups = (tenant.suppliers || []);
  for (let i = 0; i < sups.length; i++) {
    const s = sups[i];
    out.Suppliers.push({
      kind: "supplier",
      label: s.name,
      path: "/forge/ebom",
      hint: [s.category, s.location, s.on_time_pct != null ? s.on_time_pct + "% OTD" : null]
        .filter(Boolean).join(" · "),
    });
  }

  // Work orders — WO-MTL-2401..2424
  const wos = (tenant.work_orders || []);
  for (let i = 0; i < wos.length; i++) {
    const w = wos[i];
    out["Work Orders"].push({
      kind: "wo",
      label: w.id + " · " + w.sku,
      path: "/build/workflows",
      hint: (w.status || "open") + " · qty " + (w.qty != null ? w.qty : 1),
    });
  }

  // Travelers — four stations
  const travs = (tenant.travelers || []);
  for (let i = 0; i < travs.length; i++) {
    const t = travs[i];
    out.Travelers.push({
      kind: "traveler",
      label: t.id + " · " + (t.station || "station"),
      path: t.path || "/traveler/receiving",
      hint: t.serial ? "S/N " + t.serial : "",
    });
  }

  // Recent ledger
  const ledger = (tenant.ledger || []);
  const recent = ledger.slice(-6).reverse();
  for (let i = 0; i < recent.length; i++) {
    const e = recent[i];
    out["Recent Events"].push({
      kind: "event",
      label: (e.event_id || e.event) + " · " + (e.summary || ""),
      path: "/auditor/ledger",
      hint: (e.actor || "") + " · " + ((e.ts || "") + "").slice(0, 10),
    });
  }

  return out;
}

function MSPalette() {
  const [open, setOpen]     = uSMS(false);
  const [query, setQuery]   = uSMS("");
  const [active, setActive] = uSMS(0);
  const inputRef = uRMS(null);

  // ⌘K toggles
  uEMS(function() {
    function onKey(e) {
      const isMeta = e.metaKey || e.ctrlKey;
      if (isMeta && (e.key === "k" || e.key === "K")) {
        e.preventDefault();
        setOpen(function(v) { return !v; });
      } else if (e.key === "Escape") {
        setOpen(false);
      }
    }
    window.addEventListener("keydown", onKey);
    return function() { window.removeEventListener("keydown", onKey); };
  }, []);

  uEMS(function() {
    if (!open) return undefined;
    setQuery("");
    setActive(0);
    const t = setTimeout(function() {
      if (inputRef.current && inputRef.current.focus) inputRef.current.focus();
    }, 18);
    return function() { clearTimeout(t); };
  }, [open]);

  const index = uMMS(function() { return open ? msBuildIndex() : null; }, [open]);

  const grouped = uMMS(function() {
    if (!index) return [];
    const cats = ["Screens", "Parts", "BOMs", "Suppliers", "Work Orders", "Travelers", "Recent Events"];
    const out = [];
    let total = 0;
    for (let ci = 0; ci < cats.length; ci++) {
      const cat   = cats[ci];
      const items = index[cat] || [];
      let scored = items.map(function(it) {
        const sName = msScore(query, it.label);
        const sPath = msScore(query, it.path);
        const score = Math.max(sName, sPath);
        return { it: it, score: score };
      });
      if (query) scored = scored.filter(function(x) { return x.score >= 0; });
      scored.sort(function(a, b) { return b.score - a.score; });
      const top = scored.slice(0, 5).map(function(x) { return x.it; });
      if (top.length === 0) continue;
      out.push({ cat: cat, items: top });
      total += top.length;
      if (total >= 20) break;
    }
    let count = 0;
    const capped = [];
    for (let i = 0; i < out.length; i++) {
      const left = 20 - count;
      if (left <= 0) break;
      const slice = out[i].items.slice(0, left);
      capped.push({ cat: out[i].cat, items: slice });
      count += slice.length;
    }
    return capped;
  }, [index, query]);

  const flat = uMMS(function() {
    const f = [];
    for (let i = 0; i < grouped.length; i++) {
      for (let j = 0; j < grouped[i].items.length; j++) {
        f.push({ cat: grouped[i].cat, it: grouped[i].items[j] });
      }
    }
    return f;
  }, [grouped]);

  uEMS(function() {
    if (active >= flat.length) setActive(flat.length > 0 ? flat.length - 1 : 0);
  }, [flat, active]);

  function pick(it) {
    setOpen(false);
    if (it && it.path && typeof navigate === "function") navigate(it.path);
  }

  function onKey(e) {
    if (e.key === "ArrowDown") {
      e.preventDefault();
      setActive(function(a) { return Math.min(flat.length - 1, a + 1); });
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setActive(function(a) { return Math.max(0, a - 1); });
    } else if (e.key === "Enter") {
      e.preventDefault();
      const sel = flat[active];
      if (sel) pick(sel.it);
    }
  }

  if (!open) return null;

  return React.createElement(
    "div",
    {
      style: {
        position: "fixed",
        inset: 0,
        zIndex: 1000,
        display: "flex",
        alignItems: "flex-start",
        justifyContent: "center",
        paddingTop: "12vh",
        background: "rgba(31,35,40,0.36)",
        backdropFilter: "blur(2px)",
        fontFamily: MS_UI,
      },
      onClick: function() { setOpen(false); },
    },
    React.createElement(
      "div",
      {
        onClick: function(e) { e.stopPropagation(); },
        style: {
          width: 660,
          maxHeight: "70vh",
          background: MS_BG,
          color: MS_INK,
          border: "1px solid " + MS_LINE,
          borderRadius: 4,
          boxShadow: "0 0 0 1px rgba(31,35,40,0.04)",
          overflow: "hidden",
          display: "flex",
          flexDirection: "column",
        },
      },
      // Header — kicker
      React.createElement(
        "div",
        {
          style: {
            display: "flex",
            alignItems: "center",
            gap: 10,
            padding: "10px 14px",
            borderBottom: "1px solid " + MS_LINE_SOFT,
            background: MS_BG_3,
          },
        },
        React.createElement(
          "span",
          {
            style: {
              fontFamily: MS_MONO,
              fontSize: 12,
              color: MS_INK_3,
              letterSpacing: "0.10em",
              textTransform: "uppercase",
            },
          },
          "⌘K · mittelstand"
        ),
        React.createElement("input", {
          ref: inputRef,
          value: query,
          placeholder: "search screens · parts · BOMs · suppliers · WOs · travelers …",
          onChange: function(e) { setQuery(e.target.value); setActive(0); },
          onKeyDown: onKey,
          style: {
            flex: 1,
            border: 0,
            outline: "none",
            background: "transparent",
            fontFamily: MS_MONO,
            fontSize: 13,
            color: MS_INK,
            padding: 4,
          },
        }),
        React.createElement(
          "span",
          {
            style: {
              fontFamily: MS_MONO,
              fontSize: 12,
              color: MS_INK_3,
              padding: "2px 6px",
              border: "1px solid " + MS_LINE,
              borderRadius: 3,
            },
          },
          "esc"
        )
      ),
      // Results
      React.createElement(
        "div",
        { style: { flex: 1, overflowY: "auto", padding: "6px 0" } },
        grouped.length === 0
          ? React.createElement(
              "div",
              {
                style: {
                  padding: "26px 20px",
                  fontFamily: MS_MONO,
                  fontSize: 12,
                  color: MS_INK_3,
                  textAlign: "center",
                },
              },
              query ? "no matches" : "loading mittelstand index…"
            )
          : grouped.map(function(g, gi) {
              return React.createElement(
                "div",
                { key: g.cat, style: { padding: "4px 0 8px" } },
                React.createElement(
                  "div",
                  {
                    style: {
                      fontFamily: MS_MONO,
                      fontSize: 12,
                      letterSpacing: "0.10em",
                      textTransform: "uppercase",
                      color: MS_INK_3,
                      padding: "6px 16px 4px",
                    },
                  },
                  g.cat
                ),
                g.items.map(function(it, ii) {
                  let flatIdx = 0;
                  for (let x = 0; x < gi; x++) flatIdx += grouped[x].items.length;
                  flatIdx += ii;
                  const isActive = flatIdx === active;
                  return React.createElement(
                    "button",
                    {
                      key: it.label + "_" + ii,
                      onMouseEnter: function() { setActive(flatIdx); },
                      onClick: function() { pick(it); },
                      style: {
                        display: "flex",
                        alignItems: "center",
                        gap: 8,
                        width: "100%",
                        padding: "8px 16px",
                        border: 0,
                        background: isActive ? MS_BG_3 : "transparent",
                        borderLeft: isActive ? "2px solid " + MS_ACCENT : "2px solid transparent",
                        cursor: "pointer",
                        textAlign: "left",
                        fontFamily: MS_UI,
                        fontSize: 13,
                        color: MS_INK,
                      },
                    },
                    React.createElement(
                      "span",
                      {
                        style: {
                          width: 18,
                          fontFamily: MS_MONO,
                          fontSize: 12,
                          color: MS_INK_3,
                          textAlign: "center",
                        },
                      },
                      it.kind === "part" ? "·"
                        : it.kind === "bom" ? "≡"
                        : it.kind === "supplier" ? "▸"
                        : it.kind === "wo" ? "WO"
                        : it.kind === "traveler" ? "TR"
                        : it.kind === "event" ? "E"
                        : "→"
                    ),
                    React.createElement(
                      "span",
                      {
                        style: {
                          flex: 1,
                          minWidth: 0,
                          overflow: "hidden",
                          textOverflow: "ellipsis",
                          whiteSpace: "nowrap",
                        },
                      },
                      it.label
                    ),
                    it.hint
                      ? React.createElement(
                          "span",
                          {
                            style: {
                              fontFamily: MS_MONO,
                              fontSize: 12,
                              color: MS_INK_3,
                              marginLeft: 8,
                              flexShrink: 0,
                            },
                          },
                          it.hint
                        )
                      : null,
                    isActive
                      ? React.createElement(
                          "span",
                          {
                            style: {
                              fontFamily: MS_MONO,
                              fontSize: 12,
                              color: MS_INK_3,
                              marginLeft: 8,
                              padding: "1px 6px",
                              border: "1px solid " + MS_LINE,
                              borderRadius: 3,
                            },
                          },
                          "↵"
                        )
                      : null
                  );
                })
              );
            })
      ),
      // Footer
      React.createElement(
        "div",
        {
          style: {
            padding: "8px 14px",
            borderTop: "1px solid " + MS_LINE_SOFT,
            display: "flex",
            justifyContent: "space-between",
            fontFamily: MS_MONO,
            fontSize: 12,
            color: MS_INK_3,
            background: MS_BG_3,
          },
        },
        React.createElement("span", null, "↑↓ navigate · ↵ open · esc close"),
        React.createElement("span", null, flat.length + " result" + (flat.length === 1 ? "" : "s"))
      )
    )
  );
}

// ──────────────────────────────────────────────────────────────────────
// 9. MSNotificationBell — derived alerts (ECO, granite cell, FAI, NCR)
// ──────────────────────────────────────────────────────────────────────

function msBuildNotifications() {
  const tenant = (typeof getActiveTenant === "function") ? getActiveTenant() : null;
  const out = [];
  if (!tenant) return out;

  // ECO-MS-0017 awaiting Quality
  const eco = tenant.eco || tenant.active_eco;
  if (eco && (eco.id || "").indexOf("MS-0017") >= 0) {
    out.push({
      id: "eco-ms-0017",
      severity: eco.approval_state && /awaiting/i.test(eco.approval_state) ? "warn" : "info",
      ts: eco.opened_on || "2025-11-18",
      title: "ECO-MS-0017 awaiting Quality",
      summary: "Granite flatness ±5 µm → ±3 µm, +€820/unit. CMM gauge R&R pending S. Klein.",
      cta: "Open ECO",
      path: "/build/eco",
    });
  }

  // Field returns from the three Rev C feeder units
  const fr = tenant.field_returns || [];
  if (fr.length > 0) {
    out.push({
      id: "field-returns-rev-c",
      severity: "fail",
      ts: fr[fr.length - 1] ? fr[fr.length - 1].date_returned : "2025-10-22",
      title: fr.length + " Rev C returns · vibration > 0.8 mm/s RMS",
      summary: "S/N 0089–0094 traced to granite cross-beam flatness drift. ECO-MS-0017 routed.",
      cta: "Drill into returns",
      path: "/build/eco",
    });
  }

  // Granite cell readiness drop (line readiness 91% from spec §4)
  out.push({
    id: "granite-cell-readiness",
    severity: "warn",
    ts: "2026-03-04",
    title: "Granite cell readiness 91% (−3 pt)",
    summary: "Lap-stones reorder pending; re-grind op qualified, two CMM slots free.",
    cta: "Open line",
    path: "/line/queue",
  });

  // GMN spindle ETA — single-source 180 d
  out.push({
    id: "gmn-spindle-eta",
    severity: "info",
    ts: "2026-01-12",
    title: "GMN spindle 50.01 · ETA D-180",
    summary: "Single-source critical path, no dual qualified. Tracker green for 2026-08-14 FAI.",
    cta: "Audit supplier",
    path: "/forge/suppliers",
  });

  // FAI window
  out.push({
    id: "fai-target",
    severity: "info",
    ts: "2026-08-14",
    title: "FAI gate 4 target · 2026-08-14",
    summary: "AS9102 / IATF PPAP Level 3 package due. MAHLE witness slot booked.",
    cta: "Open traveler",
    path: "/traveler/test",
  });

  return out;
}

function MSNotificationBell() {
  const [open, setOpen]     = uSMS(false);
  const [pulse, setPulse]   = uSMS(true);
  const [seenAt, setSeenAt] = uSMS(0);
  const wrapRef = uRMS(null);

  const items = uMMS(function() { return msBuildNotifications(); }, [open, seenAt]);

  uEMS(function() {
    const t = setTimeout(function() { setPulse(false); }, 2800);
    return function() { clearTimeout(t); };
  }, []);

  uEMS(function() {
    const interval = setInterval(function() {
      setPulse(true);
      setTimeout(function() { setPulse(false); }, 1600);
    }, 60000);
    return function() { clearInterval(interval); };
  }, []);

  uEMS(function() {
    if (!open) return undefined;
    function onDown(e) {
      if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
    }
    document.addEventListener("mousedown", onDown);
    return function() { document.removeEventListener("mousedown", onDown); };
  }, [open]);

  function takeAction(it) {
    setOpen(false);
    if (it && it.path && typeof navigate === "function") navigate(it.path);
  }

  const Ic = (typeof Icons !== "undefined") ? Icons : {};
  const BellIcon = Ic.Bell || function() { return React.createElement("span", null, "♪"); };

  return React.createElement(
    "div",
    {
      ref: wrapRef,
      style: {
        position: "fixed",
        top: 14,
        right: 18,
        zIndex: 900,
        fontFamily: MS_UI,
      },
    },
    React.createElement(
      "button",
      {
        onClick: function() { setOpen(function(v) { return !v; }); setSeenAt(Date.now()); },
        title: "alerts",
        style: {
          position: "relative",
          width: 30,
          height: 30,
          borderRadius: 4,
          background: open ? MS_BG_2 : "transparent",
          border: "1px solid " + (open ? MS_LINE : "transparent"),
          color: MS_INK_2,
          cursor: "pointer",
          display: "inline-flex",
          alignItems: "center",
          justifyContent: "center",
          transition: "background .15s ease",
        },
      },
      React.createElement(BellIcon, { size: 16 }),
      items.length > 0
        ? React.createElement(
            "span",
            {
              style: {
                position: "absolute",
                top: 2,
                right: 2,
                minWidth: 14,
                height: 14,
                padding: "0 3px",
                borderRadius: 7,
                fontFamily: MS_MONO,
                fontSize: 12,
                lineHeight: "14px",
                color: "#fff",
                background: MS_FAIL,
                textAlign: "center",
                boxShadow: pulse ? "0 0 0 4px rgba(150,50,40,0.18)" : "none",
                transition: "box-shadow .35s ease",
              },
            },
            items.length
          )
        : null
    ),
    open
      ? React.createElement(
          "div",
          {
            style: {
              position: "absolute",
              top: 36,
              right: 0,
              width: 380,
              background: MS_BG,
              border: "1px solid " + MS_LINE,
              borderRadius: 4,
              boxShadow: "0 0 0 1px rgba(31,35,40,0.04)",
              overflow: "hidden",
            },
          },
          React.createElement(
            "div",
            {
              style: {
                padding: "8px 12px",
                borderBottom: "1px solid " + MS_LINE_SOFT,
                background: MS_BG_3,
                fontFamily: MS_MONO,
                fontSize: 12,
                letterSpacing: "0.10em",
                textTransform: "uppercase",
                color: MS_INK_3,
                display: "flex",
                justifyContent: "space-between",
              },
            },
            React.createElement("span", null, "alerts · mittelstand"),
            React.createElement("span", null, items.length + " active")
          ),
          React.createElement(
            "div",
            { style: { maxHeight: 440, overflowY: "auto" } },
            items.length === 0
              ? React.createElement(
                  "div",
                  {
                    style: {
                      padding: 18,
                      fontFamily: MS_MONO,
                      fontSize: 12,
                      color: MS_INK_3,
                      textAlign: "center",
                    },
                  },
                  "no alerts"
                )
              : items.map(function(it) {
                  const tone = msToneFor(it.severity || "info");
                  return React.createElement(
                    "div",
                    {
                      key: it.id,
                      style: {
                        padding: "10px 12px",
                        borderBottom: "1px solid " + MS_LINE_SOFT,
                        display: "flex",
                        flexDirection: "column",
                        gap: 4,
                      },
                    },
                    React.createElement(
                      "div",
                      { style: { display: "flex", alignItems: "center", gap: 8 } },
                      React.createElement(
                        "span",
                        {
                          style: {
                            fontFamily: MS_MONO,
                            fontSize: 12,
                            letterSpacing: "0.06em",
                            textTransform: "uppercase",
                            padding: "1px 6px",
                            borderRadius: 3,
                            background: tone.bg,
                            color: tone.fg,
                            border: "1px solid " + tone.border,
                          },
                        },
                        tone.label
                      ),
                      React.createElement(
                        "span",
                        {
                          style: {
                            fontFamily: MS_UI,
                            fontSize: 12,
                            fontWeight: 600,
                            color: MS_INK,
                            flex: 1,
                          },
                        },
                        it.title
                      ),
                      React.createElement(
                        "span",
                        {
                          style: {
                            fontFamily: MS_MONO,
                            fontSize: 12,
                            color: MS_INK_3,
                          },
                        },
                        ((it.ts || "") + "").slice(0, 10)
                      )
                    ),
                    React.createElement(
                      "div",
                      {
                        style: {
                          fontFamily: MS_UI,
                          fontSize: 12,
                          color: MS_INK_2,
                          lineHeight: 1.45,
                        },
                      },
                      it.summary
                    ),
                    React.createElement(
                      "button",
                      {
                        onClick: function() { takeAction(it); },
                        style: {
                          alignSelf: "flex-start",
                          marginTop: 4,
                          padding: "3px 10px",
                          fontFamily: MS_MONO,
                          fontSize: 12,
                          color: MS_ACCENT,
                          background: "transparent",
                          border: "1px solid " + MS_LINE,
                          borderRadius: 3,
                          cursor: "pointer",
                        },
                      },
                      it.cta + " →"
                    )
                  );
                })
          )
        )
      : null
  );
}

// ──────────────────────────────────────────────────────────────────────
// 10. MSCrossCuttingMount — composite
// ──────────────────────────────────────────────────────────────────────

function MSCrossCuttingMount() {
  return React.createElement(
    React.Fragment,
    null,
    React.createElement(MSPalette),
    React.createElement(MSNotificationBell)
  );
}

// ──────────────────────────────────────────────────────────────────────
// Globals
// ──────────────────────────────────────────────────────────────────────

if (typeof window !== "undefined") {
  window.MSCard               = MSCard;
  window.MSPill               = MSPill;
  window.MSBtn                = MSBtn;
  window.MSToolbar            = MSToolbar;
  window.MSStatRow            = MSStatRow;
  window.MSSectionTitle       = MSSectionTitle;
  window.MSFlash              = MSFlash;
  window.MSPalette            = MSPalette;
  window.MSNotificationBell   = MSNotificationBell;
  window.MSCrossCuttingMount  = MSCrossCuttingMount;
}
