// Onboarding — adaptive multi-vertical client setup wizard
// Replaces ScreenOnboarding from screens1.jsx

const { useState: uSOB, useMemo: uMOB } = React;

// ─── Preset demo cards — each is a {currency, locale} preset. Money chips
// resolve through forgeI18n.formatMoneyMinor at render time so Tritan reads
// ₹2,400 (en-IN), Mittelstand reads 32.000,00 € (de-DE), Aetherion shows
// "$" hints. The fallback strings preserve the demo legibility if i18n
// hasn't bootstrapped (script-order race).
function _ob_money(minor, currency, fallback) {
  var i = (typeof window !== "undefined") ? window.forgeI18n : null;
  if (i && typeof i.formatMoneyMinor === "function") {
    // Force the tenant-default locale so the preset card always reads in
    // its own currency convention, regardless of the active tenant on the
    // user's machine when they open the picker.
    var loc = (currency === "INR") ? "en-IN" : (currency === "EUR") ? "de-DE" : "en-US";
    var out = i.formatMoneyMinor(minor, currency, loc);
    if (out) return out;
  }
  return fallback;
}

// ─── Tritan demo card config (preset, bypasses wizard) ───────────────────
const TRITAN_DEMO_VERT = {
  id: "tritan-pump",
  label: "Pump · CDMO",
  tagline: "Contract design + manufacturing of private-label submersible pumpsets",
  examples: "1.0HP / 4-inch · BEE 3-star · Helios AgriFlow private-label",
  icon: "Factory",
  color: "oklch(0.55 0.13 180)",
  chars: [
    "Pump-platform CDMO with 117 active SKUs and ~340 employees",
    "M-27418 hero program · 500-unit pumpset run for Helios AgriFlow",
    "7-station routing · 30-point CTQ test gates · BEE/IS:8034 compliance",
    "Live ECO-0051 (NRV C.I. → S.G.-400) under approval",
    "Loads with full tenant data: parts, BOMs, work orders, ledger",
  ],
  defaultModules: ["ebom","mbom","eco","gantt","line","traveler","auditor"],
  bomExtra: ["Tolerance","Cost (₹)","Lead Time","Supplier"],
  // ₹2,400 = 240,000 paise (minor). Resolved en-IN → "₹2,400.00".
  bomTagPreviews: ["TOLERANCE ±0.05", "LEAD-TIME 14 d", "COST " + _ob_money("240000", "INR", "₹2,400")],
  isDemoBypass: true,
  isPreset: true,
};

// ─── Aetherion demo card config (preset, bypasses wizard) ─────────────────
// Aetherion preview chips don't carry a money value (mass/power/heritage),
// so no i18n wiring is needed in the BOM tag previews. The narrative line
// "$4.2M FFP for Aperture Earth" reads naturally regardless of viewer
// locale; we keep it as marketing copy.
const AETHERION_DEMO_VERT = {
  id: "aetherion-space",
  label: "Rockets · Space program",
  tagline: "Mission-class hardware, shipped on a fixed-price clock",
  examples: "12U cubesat · X-band downlink · sun-sync LEO 525 km",
  icon: "Satellite",
  color: "oklch(0.62 0.14 250)",
  chars: [
    "Aetherion Microsat tenant — KESTREL-3 12U bus, $4.2M FFP for Aperture Earth",
    "11 subassemblies wired to flight heritage (TRL-9 Honeybee hinges, AAC Clyde OBC)",
    "9-gate lifecycle SRR → PDR → CDR → FAB → ASSY → I&T → TVAC → ACC → LAUNCH",
    "Live ECO-AET-0042 against the solar-array hinge after TVAC chatter",
    "ITAR-aware ledger and AS9100 / ECSS-Q-ST-70 quality gates wired in",
  ],
  defaultModules: ["ebom","mbom","eco","plc","gantt","traveler","auditor","docs","people","analytics"],
  bomExtra: ["Mass (g)","Power (W)","Heritage","Qual"],
  bomTagPreviews: ["MASS 14kg", "POWER 32W", "HERITAGE TRL-9"],
  isDemoBypass: true,
  isPreset: true,
};

// ─── Mittelstand demo card config (preset, bypasses wizard) ───────────────
const MITTELSTAND_DEMO_VERT = {
  id: "mittelstand-machine",
  label: "Mittelstand · Machine builder",
  tagline: "Series-production CNC mills for the German Tier-1 base",
  examples: "MTL-220 Rev D · 5-axis bridge mill · MAHLE 24-unit frame contract",
  icon: "Factory",
  color: "oklch(0.55 0.02 250)",
  chars: [
    "Mittelstand-pilot Werkzeugbau, Stuttgart · 42 active SKUs · SAP B1 + proALPHA",
    "MTL-220 hero program · 24-unit MAHLE batch · series production Rev D",
    "5-gate quality flow · ISO 9001 / IATF 16949 PPAP Level 3",
    "Live ECO-MS-0017 · granite flatness ±5 µm → ±3 µm · vibration root-cause",
    "Loads with full tenant data: 30+ parts, BOMs, work orders, ledger",
  ],
  defaultModules: ["ebom","mbom","eco","gantt","line","traveler","auditor"],
  bomExtra: ["Tolerance","Lead Time","Cost (€)","Supplier"],
  // 32,000 EUR = 3,200,000 cents. de-DE renders "32.000,00 €" (group dots,
  // comma decimal, currency suffix).
  bomTagPreviews: ["TOLERANCE ±3 µm", "LEAD-TIME 180 d", "COST " + _ob_money("3200000", "EUR", "€32,000")],
  isDemoBypass: true,
  isPreset: true,
};

// ─── Preset card (highlighted, demo-bypass) ───────────────────────────────
function PresetCard({ v, onPick, prominent }) {
  const _presetCardStyle = {
    border: `1px solid color-mix(in oklch,${v.color} 45%,var(--line))`,
    borderRadius: 10, overflow: "hidden", background: "var(--bg-1)",
    cursor: "pointer", transition: "transform .15s, box-shadow .15s",
    position: "relative",
    boxShadow: prominent ? `0 1px 0 color-mix(in oklch,${v.color} 12%,transparent)` : "none",
  };
  const _presetPillStyle = {
    position: "absolute", top: 14, right: 14,
    padding: "2px 7px", borderRadius: 3,
    border: `1px solid color-mix(in oklch,${v.color} 50%,var(--line))`,
    background: `color-mix(in oklch,${v.color} 10%,transparent)`,
    color: v.color, fontFamily: "var(--font-mono)",
    fontSize: 12, letterSpacing: ".08em", textTransform: "uppercase",
  };
  return (
    <div
      role="button"
      tabIndex={0}
      style={_presetCardStyle}
      onClick={() => onPick(v.id)}
      onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onPick(v.id); } }}
      onMouseEnter={e => { Object.assign(e.currentTarget.style, { transform: "translateY(-3px)", boxShadow: `0 12px 32px color-mix(in oklch,${v.color} 22%,transparent)` }); }}
      onMouseLeave={e => { Object.assign(e.currentTarget.style, { transform: "none", boxShadow: prominent ? `0 1px 0 color-mix(in oklch,${v.color} 12%,transparent)` : "none" }); }}
    >
      {/* accent stripe */}
      <div style={{ height: 4, background: v.color }}/>

      {/* PRESET pill */}
      <div style={_presetPillStyle}>preset</div>

      <div style={{ padding: "20px 22px" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 12 }}>
          <div style={{ width: 40, height: 40, borderRadius: 8, background: `color-mix(in oklch,${v.color} 15%,transparent)`,
            display: "grid", placeItems: "center", color: v.color }}>
            {I(v.icon, { size: 22 })}
          </div>
          <div style={{ paddingRight: 56 }}>
            <div style={{ fontSize: 15, fontWeight: 600, color: "var(--ink)" }}>{v.label}</div>
            <div className="muted" style={{ fontSize: 12 }}>{v.tagline}</div>
          </div>
        </div>

        <div className="muted mono" style={{ fontSize: 12, marginBottom: 12 }}>{v.examples}</div>

        <div style={{ display: "flex", flexDirection: "column", gap: 5, marginBottom: 14 }}>
          {v.chars.map((c) => (
            <div key={c} style={{ display: "flex", gap: 8, alignItems: "flex-start" }}>
              <span style={{ color: v.color, marginTop: 1, flexShrink: 0 }}>{I("Check", { size: 11 })}</span>
              <span style={{ fontSize: 12, color: "var(--ink-2)", lineHeight: 1.4 }}>{c}</span>
            </div>
          ))}
        </div>

        {/* BOM tag previews — mono 11px chips */}
        <div style={{ display: "flex", gap: 5, flexWrap: "wrap", marginBottom: 14 }}>
          {(v.bomTagPreviews || v.bomExtra.slice(0, 3)).map(tag => {
            const _bomTagChipStyle = {
              padding: "2px 7px", borderRadius: 3,
              border: `1px solid color-mix(in oklch,${v.color} 35%,var(--line))`,
              background: `color-mix(in oklch,${v.color} 6%,transparent)`,
              color: v.color, fontFamily: "var(--font-mono)",
              fontSize: 12, lineHeight: 1.4,
            };
            return <span key={tag} style={_bomTagChipStyle}>{tag}</span>;
          })}
        </div>

        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
          <span className="mono" style={{ fontSize: 12, color: "var(--ink-3)" }}>
            {v.defaultModules.length} modules pre-selected
          </span>
        </div>

        {(() => {
          const _presetCtaStyle = { width: "100%", padding: "9px 0", borderRadius: 6, cursor: "pointer",
            border: `1px solid ${v.color}`, background: v.color,
            color: v.color.includes("250") ? "oklch(0.98 0.01 250)" : "oklch(0.14 0.02 55)",
            fontFamily: "var(--font-ui)", fontSize: 12, fontWeight: 600 };
          return (
            <button onClick={(e) => { e.stopPropagation(); onPick(v.id); }} style={_presetCtaStyle}>
              Load {v.label.split("·")[0].trim()} demo →
            </button>
          );
        })()}
      </div>
    </div>
  );
}

// ─── Wizard vertical card (for net-new vertical configuration) ────────────
function WizardVertCard({ v, onPick }) {
  const _wizardVertCardStyle = {
    border: `1px solid color-mix(in oklch,${v.color} 30%,var(--line))`,
    borderRadius: 10, overflow: "hidden", background: "var(--bg-1)",
    cursor: "pointer", transition: "transform .15s, box-shadow .15s",
  };
  return (
    <div key={v.id}
      style={_wizardVertCardStyle}
      onMouseEnter={e => { Object.assign(e.currentTarget.style, { transform: "translateY(-3px)", boxShadow: `0 12px 32px color-mix(in oklch,${v.color} 18%,transparent)` }); }}
      onMouseLeave={e => { Object.assign(e.currentTarget.style, { transform: "none", boxShadow: "none" }); }}>

      <div style={{ height: 4, background: v.color }}/>

      <div style={{ padding: "20px 22px" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 12 }}>
          <div style={{ width: 40, height: 40, borderRadius: 8, background: `color-mix(in oklch,${v.color} 15%,transparent)`,
            display: "grid", placeItems: "center", color: v.color }}>
            {I(v.icon, { size: 22 })}
          </div>
          <div>
            <div style={{ fontSize: 15, fontWeight: 600, color: "var(--ink)" }}>{v.label}</div>
            <div className="muted" style={{ fontSize: 12 }}>{v.tagline}</div>
          </div>
        </div>

        <div className="muted mono" style={{ fontSize: 12, marginBottom: 12 }}>{v.examples}</div>

        <div style={{ display: "flex", flexDirection: "column", gap: 5, marginBottom: 18 }}>
          {v.chars.map((c) => (
            <div key={c} style={{ display: "flex", gap: 8, alignItems: "flex-start" }}>
              <span style={{ color: v.color, marginTop: 1, flexShrink: 0 }}>{I("Check", { size: 11 })}</span>
              <span style={{ fontSize: 12, color: "var(--ink-2)", lineHeight: 1.4 }}>{c}</span>
            </div>
          ))}
        </div>

        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
          <span className="mono" style={{ fontSize: 12, color: "var(--ink-3)" }}>
            {v.defaultModules.length} modules pre-selected
          </span>
          <div style={{ display: "flex", gap: 4 }}>
            {v.bomExtra.slice(0, 3).map(col => (
              <span key={col} className="tag" style={{ fontSize: 12, borderColor: `color-mix(in oklch,${v.color} 30%,var(--line))` }}>{col}</span>
            ))}
          </div>
        </div>

        {(() => {
          const _wizardCtaStyle = { width: "100%", padding: "9px 0", borderRadius: 6, cursor: "pointer",
            border: `1px solid ${v.color}`, background: v.color,
            color: v.id === "space" ? "oklch(0.16 0.01 250)" : "oklch(0.14 0.02 55)",
            fontFamily: "var(--font-ui)", fontSize: 12, fontWeight: 600 };
          return (
            <button onClick={() => onPick(v.id)} style={_wizardCtaStyle}>
              Configure Forge for {v.label} →
            </button>
          );
        })()}
      </div>
    </div>
  );
}

// ─── Vertical Picker ──────────────────────────────────────────────────────
function VertPicker({ onPick }) {
  const [showWizard, setShowWizard] = uSOB(false);
  const wizardVerts = Object.values(VERTICALS);

  return (
    <div style={{ position: "relative", padding: 32, display: "flex", flexDirection: "column", alignItems: "center", gap: 28, height: "100%", overflowY: "auto" }}>
      {/* ── Return to Dashboard escape hatch (Wave 8J) ── */}
      <div style={{ position: "absolute", top: 16, right: 16 }}>
        <button
          onClick={function() { if (typeof navigate === "function") navigate("/forge/dashboard"); else window.location.hash = "/forge/dashboard"; }}
          style={{
            display: "inline-flex",
            alignItems: "center",
            gap: 6,
            height: 28,
            padding: "0 12px",
            borderRadius: 4,
            background: "var(--bg-2, oklch(0.965 0.005 85))",
            border: "1px solid var(--line, oklch(0.84 0.006 85))",
            fontFamily: "var(--font-ui)",
            fontSize: 12,
            fontWeight: 500,
            color: "var(--ink-2, oklch(0.30 0.01 85))",
            cursor: "pointer",
            boxShadow: "0 1px 2px rgba(0,0,0,0.02)",
            transition: "all .1s",
          }}
          onMouseEnter={function(e) { e.currentTarget.style.background = "var(--bg-3)"; e.currentTarget.style.borderColor = "var(--line-strong)"; }}
          onMouseLeave={function(e) { e.currentTarget.style.background = "var(--bg-2)"; e.currentTarget.style.borderColor = "var(--line)"; }}
        >
          {I("Home", { size: 12 })}
          <span>Return to Dashboard</span>
        </button>
      </div>

      <div style={{ textAlign: "center", maxWidth: 620 }}>
        <div className="serif" style={{ fontSize: 36, lineHeight: 1.1, marginBottom: 8 }}>
          Pick a preset, or configure a new vertical
        </div>
        <div className="muted" style={{ fontSize: 14 }}>
          Presets load a fully-wired tenant in one click: parts, BOMs, work orders, ledger, and dashboards. Net-new verticals run through the setup wizard.
        </div>
      </div>

      {/* ── Three OEM preset cards (single row, all top-tier) ── */}
      <div style={{ width: "100%", maxWidth: 1400 }}>
        <div className="mono" style={{ fontSize: 12, color: "var(--ink-3)", textTransform: "uppercase", letterSpacing: ".08em", marginBottom: 10, paddingLeft: 4 }}>
          OEM presets · ready to demo
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 18 }}>
          <PresetCard v={TRITAN_DEMO_VERT}        onPick={onPick} prominent />
          <PresetCard v={AETHERION_DEMO_VERT}     onPick={onPick} prominent />
          <PresetCard v={MITTELSTAND_DEMO_VERT}   onPick={onPick} prominent />
        </div>
      </div>

      {/* ── Divider + wizard toggle ── */}
      <div style={{ width: "100%", maxWidth: 1180, display: "flex", alignItems: "center", gap: 14, marginTop: 6 }}>
        <div style={{ flex: 1, height: 1, background: "var(--line-soft)" }}/>
        {(() => {
          const _wizardToggleStyle = { padding: "8px 18px", borderRadius: 6, cursor: "pointer",
            border: "1px solid var(--line)", background: "var(--bg-2)",
            color: "var(--ink-2)", fontFamily: "var(--font-ui)", fontSize: 12, fontWeight: 500 };
          return (
            <button onClick={() => setShowWizard(s => !s)} style={_wizardToggleStyle}>
              {showWizard ? "Hide wizard" : "Configure new vertical →"}
            </button>
          );
        })()}
        <div style={{ flex: 1, height: 1, background: "var(--line-soft)" }}/>
      </div>

      {/* ── Wizard verticals (revealed on toggle) ── */}
      {showWizard && (
        <div style={{ width: "100%", maxWidth: 1180 }}>
          <div className="mono" style={{ fontSize: 12, color: "var(--ink-3)", textTransform: "uppercase", letterSpacing: ".08em", marginBottom: 10, paddingLeft: 4 }}>
            Net-new vertical · 5-step wizard
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 20 }}>
            {wizardVerts.map(v => <WizardVertCard key={v.id} v={v} onPick={onPick} />)}
          </div>
        </div>
      )}

      <div className="muted mono" style={{ fontSize: 12 }}>
        You can switch verticals or re-run setup any time from Settings
      </div>
    </div>
  );
}

// ─── Step form field sets per vertical ───────────────────────────────────
const STEP_FIELDS = {
  space: [
    [["Mission Name","missionName"],["Customer / Programme Owner","customer"],
     ["Target Orbit","orbit"],["Spacecraft Dry Mass (kg)","mass"],
     ["Power Envelope (W)","power"],["Target Launch Date","launchDate"]],
    [["Mission Lead (Systems Eng.)","lead"],["Propulsion Lead","propLead"],
     ["Structures Lead","structLead"],["Avionics Lead","avioLead"],
     ["Thermal Lead","thermLead"],["Quality Lead","qualLead"]],
    [["Mass Budget Strategy","massBudget"],["Power Budget Strategy","powerBudget"],
     ["Part Classes (comma-sep)","partClasses"],["Heritage Policy","heritage"],
     ["CAD System","cad"],["PDM / Vault","pdm"]],
    [["Milestone Sequence","milestones"],["Qual Strategy","qualStrategy"],
     ["Vibration Test Standard","vibStd"],["TVAC Range (°C)","tvacRange"],
     ["EMC Standard","emcStd"],["Shock Spectrum","shock"]],
    [["ITAR Classification","itar"],["EAR Category","ear"],
     ["Cleanroom Class","cleanroom"],["ESD Level","esd"],
     ["Documentation Standard","docStd"],["Calibration Cycle (months)","calCycle"]],
  ],
  mittelstand: [
    [["Company Name","company"],["Founded","founded"],
     ["Employees","employees"],["Primary Industry Segment","segment"],
     ["Quality Certifications","certs"],["Primary Market","market"]],
    [["Product Family 1","family1"],["Product Family 2","family2"],
     ["Part Numbering Scheme","pnScheme"],["BOM Levels (typical)","bomLevels"],
     ["Current BOM Format","bomFmt"],["Drawing Numbering","dwgScheme"]],
    [["Production Type","prodType"],["Assembly Cell Count","cellCount"],
     ["Shift Pattern","shifts"],["Takt Time Target (min)","takt"],
     ["Primary Constraint","constraint"],["Lead Time (weeks)","leadTime"]],
    [["ERP System","erp"],["ERP Version","erpVer"],
     ["CAD System","cad"],["PDM System","pdm"],
     ["MES System","mes"],["Integration Method","intMethod"]],
    [["Quality Standard","qualStd"],["Customer-Specific Reqs.","custReqs"],
     ["NCR Workflow Lead","ncrLead"],["CAPA Responsible","capaResp"],
     ["Inspection Plan Template","inspTmpl"],["Calibration Scope","calScope"]],
  ],
  pump: [
    [["Company Name","company"],["Primary Market Segments","markets"],
     ["Product Families","families"],["OEM Revenue %","oemPct"],
     ["Aftermarket Revenue %","amPct"],["Approx. Installed Base","installedBase"]],
    [["Base Model Count","modelCount"],["Option Code Format","optFmt"],
     ["Configuration Logic","configLogic"],["Customer P/N Format","custPn"],
     ["Max Variants per Model","maxVariants"],["Configurator Tool (if any)","configTool"]],
    [["Customer Count","custCount"],["Serial Number Format","serialFmt"],
     ["Site Data Fields","siteFields"],["Fluid Types Covered","fluidTypes"],
     ["Depth Range (m)","depthRange"],["Temperature Range (°C)","tempRange"]],
    [["Spare Parts Strategy","sparePol"],["Service Interval (hrs)","svcInterval"],
     ["Warranty Period (months)","warranty"],["Service Team Size","svcTeam"],
     ["Mobile Reporting Tool","mobileApp"],["Field ERP","fieldErp"]],
    [["Material Grades (CSV)","materials"],["Max Pressure Rating (bar)","maxPressure"],
     ["Applicable Certs","certs"],["ATEX Zones","atex"],
     ["API Standards","api"],["Third-Party Body","tpb"]],
  ],
  pyrolysis: [
    [["Customer / Plant Owner","customer"],["Plant Capacity (t/yr)","capacity"],
     ["Feedstock Type","feedstock"],["Target Char Grade","charGrade"],
     ["EPCC Scope","epccScope"],["Site Location","siteLoc"]],
    [["Feedstock Moisture (%)","feedMoisture"],["Reactor Type","reactorType"],
     ["Reactor Temp Range (°C)","reactorTemp"],["Residence Time (min)","residence"],
     ["FES Fan Capacity (Nm³/hr)","fesFan"],["Packaging Format","packFmt"]],
    [["Reactor SCADA Vendor","scada"],["ERP for Batch Lots","erp"],
     ["LIMS for Char QC","lims"],["PLC Platform","plc"],
     ["Historian / Time-Series","historian"],["Integration Method","intMethod"]],
    [["Kickoff Date (W1)","kickoff"],["P&ID Freeze Week","pidWeek"],
     ["GA Freeze Week","gaWeek"],["Long-Lead PO Week","poWeek"],
     ["FAT Window","fatWindow"],["Cold Commissioning (W12)","coldComm"]],
    [["ATEX Zoning","atex"],["BIS Biochar Grade","bisGrade"],
     ["IS Engineered Carbon","isCarbon"],["CPCB Consent (CTE/CTO)","cpcb"],
     ["State PCB","statePcb"],["Third-Party Inspection","tpi"]],
  ],
};

// ─── Stepper column ───────────────────────────────────────────────────────
function StepperCol({ cfg, step, setStep, onReset }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 0 }}>
      <div style={{ padding: "10px 12px", borderBottom: "1px solid var(--line-soft)", display: "flex", alignItems: "center", gap: 8, background: `color-mix(in oklch,${cfg.color} 8%,transparent)` }}>
        <span style={{ color: cfg.color }}>{I(cfg.icon, { size: 16 })}</span>
        <div>
          <div style={{ fontSize: 12, fontWeight: 600, color: cfg.color }}>{cfg.label}</div>
          <div className="muted mono" style={{ fontSize: 12 }}>Setup Wizard</div>
        </div>
      </div>

      <Panel title="Setup steps" style={{ flex: 1 }}>
        <div style={{ padding: 8 }}>
          {cfg.steps.map((s, i) => {
            const done = i < step, cur = i === step;
            const _stepRowStyle = { display: "grid", gridTemplateColumns: "26px 1fr", gap: 8, padding: "8px 6px",
              cursor: "pointer", borderRadius: 5,
              background: cur ? "var(--bg-2)" : "transparent" };
            const _stepBadgeStyle = { width: 20, height: 20, borderRadius: 5, display: "grid", placeItems: "center",
              background: done ? cfg.color : cur ? "var(--bg-3)" : "var(--bg-2)",
              color: done ? "oklch(0.14 0.02 55)" : "var(--ink-3)",
              border: `1px solid ${done || cur ? cfg.color : "var(--line)"}`,
              fontFamily: "var(--font-mono)", fontSize: 12 };
            return (
              <div key={s.id} role="button" tabIndex={0} onClick={() => setStep(i)}
                onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setStep(i); } }}
                style={_stepRowStyle}>
                <div style={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
                  <div style={_stepBadgeStyle}>
                    {done ? "✓" : s.id}
                  </div>
                  {i < cfg.steps.length - 1 && (
                    <div style={{ width: 1, flex: 1, background: done ? cfg.color : "var(--line-soft)", marginTop: 2 }}/>
                  )}
                </div>
                <div style={{ paddingBottom: 4 }}>
                  <div className="mono" style={{ fontSize: 12, color: "var(--ink-3)", textTransform: "uppercase", letterSpacing: ".06em" }}>
                    Step {s.id} · {s.label}
                  </div>
                  <div style={{ color: cur ? "var(--ink)" : "var(--ink-2)", fontSize: 12 }}>{s.title}</div>
                  <div className="muted" style={{ fontSize: 12 }}>{s.sub}</div>
                </div>
              </div>
            );
          })}
        </div>
      </Panel>

      <div style={{ padding: 10 }}>
        {(() => {
          const _resetBtnStyle = { width: "100%", padding: "6px 0", border: "1px solid var(--line)", borderRadius: 5,
            background: "transparent", color: "var(--ink-3)", fontFamily: "var(--font-mono)",
            fontSize: 12, cursor: "pointer" };
          return (
            <button onClick={onReset} style={_resetBtnStyle}>
              ← Change vertical
            </button>
          );
        })()}
      </div>
    </div>
  );
}

// ─── Module grid ──────────────────────────────────────────────────────────
function ModuleGrid({ cfg, mods, setMods }) {
  const groups = [...new Set(MODULE_CATALOG.map(m => m.group))];
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      {groups.map(grp => (
        <div key={grp}>
          <div className="label" style={{ marginBottom: 8 }}>{grp}</div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 8 }}>
            {MODULE_CATALOG.reduce((acc, m) => { if (m.group === grp) acc.push(m); return acc; }, []).map(mod => {
              const on = !!mods[mod.id];
              const recommended = cfg.defaultModules.includes(mod.id);
              const _modCardStyle = { padding: "12px 12px", border: `1px solid ${on ? cfg.color : "var(--line-soft)"}`,
                borderRadius: 7, cursor: "pointer", background: on ? `color-mix(in oklch,${cfg.color} 7%,var(--bg-1))` : "var(--bg-1)",
                position: "relative", transition: "border-color .15s, background .15s" };
              return (
                <div key={mod.id} role="button" tabIndex={0} onClick={() => setMods(m => ({ ...m, [mod.id]: !m[mod.id] }))}
                  onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setMods(m => ({ ...m, [mod.id]: !m[mod.id] })); } }}
                  style={_modCardStyle}>
                  {recommended && (() => {
                    const _modRecBadgeStyle = { position: "absolute", top: 6, right: 8, fontSize: 12,
                      fontFamily: "var(--font-mono)", color: cfg.color,
                      textTransform: "uppercase", letterSpacing: ".06em" };
                    return <div style={_modRecBadgeStyle}>recommended</div>;
                  })()}
                  <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 5 }}>
                    <span style={{ color: on ? cfg.color : "var(--ink-3)" }}>{I(mod.icon, { size: 15 })}</span>
                    <span style={{ fontSize: 12, color: on ? "var(--ink)" : "var(--ink-3)", fontWeight: on ? 600 : 400 }}>{mod.name}</span>
                  </div>
                  <div className="muted" style={{ fontSize: 12, lineHeight: 1.4 }}>{mod.desc}</div>
                  <div style={{ marginTop: 8, display: "flex", justifyContent: "flex-end" }}>
                    <div style={{ width: 28, height: 16, borderRadius: 8,
                      background: on ? cfg.color : "var(--bg-3)",
                      position: "relative", transition: "background .2s" }}>
                      {(() => {
                        const _modToggleHandleStyle = { position: "absolute", top: 2, left: on ? 14 : 2, width: 12, height: 12,
                          borderRadius: 6, background: "var(--bg-inset)", transition: "left .2s" };
                        return <div style={_modToggleHandleStyle}/>;
                      })()}
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      ))}
    </div>
  );
}

// ─── Form panel ───────────────────────────────────────────────────────────
function FormArea({ cfg, step, setStep, form, setForm, mods, setMods, setToast, onFinish }) {
  const stepCfg = cfg.steps[step];
  const fields  = STEP_FIELDS[cfg.id]?.[step] || [];
  const isLast  = step === cfg.steps.length - 1;

  const setF = (k, v) => setForm(f => ({ ...f, [k]: v }));

  return (
    <Panel title={`Step ${stepCfg.id} · ${stepCfg.title}`} right={
      <>
        <Btn size="sm" variant="ghost" icon="ChevL" onClick={() => setStep(Math.max(0, step - 1))} title="Back">Back</Btn>
        <Btn size="sm" variant="primary" onClick={() => {
          if (isLast) { if (onFinish) onFinish(); else if (setToast) setToast("✓ Forge configured — welcome aboard"); }
          else setStep(prev => prev + 1);
        }}>
          {isLast ? "Go Live →" : "Continue →"}
        </Btn>
      </>
    }>
      <div style={{ padding: 22, overflowY: "auto", height: "100%" }}>
        <div className="serif" style={{ fontSize: 28, lineHeight: 1.1, marginBottom: 6 }}>{stepCfg.title}</div>
        <div className="muted" style={{ marginBottom: 22, fontSize: 13 }}>{stepCfg.sub}</div>

        {isLast ? (
          <ModuleGrid cfg={cfg} mods={mods} setMods={setMods} />
        ) : (
          <>
            {/* STEP 0 — sub-vertical chooser, regulation multi-select, ERP flavor */}
            {step === 0 && (
              <div style={{ marginBottom: 22, display: "flex", flexDirection: "column", gap: 18 }}>
                <div>
                  <div className="label" style={{ marginBottom: 8 }}>Sub-vertical · pick the one closest to you</div>
                  <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
                    {(cfg.subVerticals || []).map(sv => {
                      const on = form.subVertId === sv.id;
                      const _subVertCardStyle = { padding: "10px 12px", border: `1px solid ${on ? cfg.color : "var(--line-soft)"}`,
                        borderRadius: 6, cursor: "pointer",
                        background: on ? `color-mix(in oklch,${cfg.color} 8%,var(--bg-1))` : "var(--bg-1)",
                        transition: "border-color .15s, background .15s" };
                      return (
                        <div key={sv.id} role="button" tabIndex={0} onClick={() => setF("subVertId", sv.id)}
                          onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setF("subVertId", sv.id); } }}
                          style={_subVertCardStyle}>
                          <div style={{ fontSize: 12, fontWeight: 600, color: on ? "var(--ink)" : "var(--ink-2)" }}>{sv.label}</div>
                          <div className="muted" style={{ fontSize: 12, lineHeight: 1.4, marginTop: 3 }}>{sv.desc}</div>
                        </div>
                      );
                    })}
                  </div>
                </div>
                <div>
                  <div className="label" style={{ marginBottom: 8 }}>Regulations / standards in scope · multi-select</div>
                  <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
                    {(cfg.regulations || []).map(r => {
                      const sel = (form.regs || []).includes(r);
                      const _regChipStyle = { padding: "4px 10px", borderRadius: 999, cursor: "pointer",
                        border: `1px solid ${sel ? cfg.color : "var(--line)"}`,
                        color: sel ? cfg.color : "var(--ink-3)",
                        background: sel ? `color-mix(in oklch,${cfg.color} 12%,transparent)` : "var(--bg-2)",
                        fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".04em", textTransform: "uppercase" };
                      return (
                        <span key={r} role="button" tabIndex={0} onClick={() => {
                          const cur = form.regs || [];
                          setF("regs", sel ? cur.filter(x => x !== r) : [...cur, r]);
                        }}
                          onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); const cur = form.regs || []; setF("regs", sel ? cur.filter(x => x !== r) : [...cur, r]); } }}
                          style={_regChipStyle}>
                          {r}
                        </span>
                      );
                    })}
                  </div>
                </div>
                <div>
                  <div className="label" style={{ marginBottom: 8 }}>Existing ERP / system of record</div>
                  <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
                    {(cfg.erpFlavors || []).map(ef => {
                      const sel = form.erpFlavor === ef;
                      const _erpChipStyle = { padding: "4px 10px", borderRadius: 4, cursor: "pointer",
                        border: `1px solid ${sel ? cfg.color : "var(--line)"}`,
                        color: sel ? "var(--ink)" : "var(--ink-3)",
                        background: sel ? `color-mix(in oklch,${cfg.color} 14%,transparent)` : "var(--bg-2)",
                        fontFamily: "var(--font-mono)", fontSize: 12 };
                      return (
                        <span key={ef} role="button" tabIndex={0} onClick={() => setF("erpFlavor", ef)}
                          onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setF("erpFlavor", ef); } }}
                          style={_erpChipStyle}>
                          {ef}
                        </span>
                      );
                    })}
                  </div>
                </div>
              </div>
            )}

            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
              {fields.map(([label, key]) => {
                const _formInputStyle = { background: "var(--bg-2)", border: "1px solid var(--line)", borderRadius: 5,
                  padding: "7px 10px", color: "var(--ink)", fontFamily: "var(--font-mono)",
                  fontSize: 12, outline: "0 solid transparent" };
                return (
                <label key={key} style={{ display: "flex", flexDirection: "column", gap: 5 }}>
                  <span className="label">{label}</span>
                  <input id="onb-f1" name="onb-f1" value={form[key] || ""} onChange={e => setF(key, e.target.value)}
                    style={_formInputStyle}
                    onFocus={e => e.target.style.borderColor = cfg.color}
                    onBlur={e => e.target.style.borderColor = "var(--line)"}
                  />
                </label>
                );
              })}
            </div>

            {/* STEP 1 — persona multi-pick (who's actually on this team) */}
            {step === 1 && cfg.personaPresets && (
              <div style={{ marginTop: 22 }}>
                <div className="label" style={{ marginBottom: 8 }}>Active personas · who'll use Forge in your org</div>
                <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
                  {cfg.personaPresets.map(p => {
                    const sel = (form.personas || []).includes(p);
                    return (
                      <span key={p} role="button" tabIndex={0} onClick={() => {
                        const cur = form.personas || [];
                        setF("personas", sel ? cur.filter(x => x !== p) : [...cur, p]);
                      }}
                        onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); const cur = form.personas || []; setF("personas", sel ? cur.filter(x => x !== p) : [...cur, p]); } }}
                        style={{ padding: "4px 10px", borderRadius: 999, cursor: "pointer",
                          border: `1px solid ${sel ? cfg.color : "var(--line)"}`,
                          color: sel ? cfg.color : "var(--ink-3)",
                          background: sel ? `color-mix(in oklch,${cfg.color} 12%,transparent)` : "var(--bg-2)",
                          fontSize: 12 }}>
                        {sel ? "✓ " : ""}{p}
                      </span>
                    );
                  })}
                </div>
                <div className="muted mono" style={{ fontSize: 12, marginTop: 8 }}>
                  Each persona shapes the rail order, default workshop prompts, and inspector tabs.
                </div>
              </div>
            )}

            {/* Vertical-specific extra content per step */}
            {cfg.id === "space" && step === 2 && (
              <div style={{ marginTop: 20 }}>
                <div className="label" style={{ marginBottom: 8 }}>BOM Column Preview</div>
                <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
                  {["Part","Name","Qty","Rev",...cfg.bomExtra].map(col => (
                    <span key={col} className="tag" style={{ borderColor: `color-mix(in oklch,${cfg.color} 40%,var(--line))`, color: cfg.color }}>{col}</span>
                  ))}
                </div>
              </div>
            )}
            {cfg.id === "space" && step === 3 && (
              <div style={{ marginTop: 20 }}>
                <div className="label" style={{ marginBottom: 8 }}>Qualification Gate Sequence</div>
                <div style={{ display: "flex", alignItems: "center", gap: 0, flexWrap: "wrap" }}>
                  {cfg.lifecycleStages.map((s, i) => (
                    <React.Fragment key={s}>
                      <div style={{ padding: "4px 10px", border: `1px solid color-mix(in oklch,${cfg.color} 30%,var(--line))`,
                        borderRadius: 4, fontSize: 12, fontFamily: "var(--font-mono)", color: cfg.color,
                        background: `color-mix(in oklch,${cfg.color} 8%,transparent)` }}>{s}</div>
                      {i < cfg.lifecycleStages.length - 1 && (
                        <div style={{ width: 16, height: 1, background: "var(--line-strong)" }}/>
                      )}
                    </React.Fragment>
                  ))}
                </div>
              </div>
            )}
            {cfg.id === "mittelstand" && step === 4 && (
              <div style={{ marginTop: 20 }}>
                <div className="label" style={{ marginBottom: 8 }}>Quality Gate Sequence</div>
                <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
                  {["Design Review","Prototype Approval","Validation Test","FAI","Production Release"].map(g => (
                    <span key={g} className="tag" style={{ borderColor: `color-mix(in oklch,${cfg.color} 40%,var(--line))`, color: cfg.color }}>{g}</span>
                  ))}
                </div>
              </div>
            )}
            {cfg.id === "pump" && step === 2 && (
              <div style={{ marginTop: 20 }}>
                <div className="label" style={{ marginBottom: 8 }}>Installed-base record fields</div>
                <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
                  {["Customer","Site","Serial No.","Model","Fluid","Depth (m)","Install Date","Last Service"].map(f => (
                    <span key={f} className="tag" style={{ borderColor: `color-mix(in oklch,${cfg.color} 40%,var(--line))`, color: cfg.color }}>{f}</span>
                  ))}
                </div>
              </div>
            )}
            {cfg.id === "pump" && step === 3 && (
              <div style={{ marginTop: 20 }}>
                <div className="label" style={{ marginBottom: 8 }}>Aftermarket lifecycle stages</div>
                <div style={{ display: "flex", alignItems: "center", gap: 0, flexWrap: "wrap" }}>
                  {["Commission","First Service","Mid-Life Overhaul","End-of-Life Repl."].map((s, i, arr) => (
                    <React.Fragment key={s}>
                      <div style={{ padding: "4px 10px", border: `1px solid color-mix(in oklch,${cfg.color} 30%,var(--line))`,
                        borderRadius: 4, fontSize: 12, fontFamily: "var(--font-mono)", color: cfg.color,
                        background: `color-mix(in oklch,${cfg.color} 8%,transparent)` }}>{s}</div>
                      {i < arr.length - 1 && <div style={{ width: 16, height: 1, background: "var(--line-strong)" }}/>}
                    </React.Fragment>
                  ))}
                </div>
              </div>
            )}
          </>
        )}
      </div>
    </Panel>
  );
}

// ─── Preview / context panel ──────────────────────────────────────────────
function PreviewCol({ cfg, step, form, mods }) {
  const activeCount = Object.values(mods).filter(Boolean).length;
  const isLastStep  = step === cfg.steps.length - 1;

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 14, minHeight: 0 }}>
      {/* Identity card */}
      <Panel title="Live Context">
        <div style={{ padding: 12 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 10 }}>
            <div style={{ width: 36, height: 36, borderRadius: 8,
              background: `color-mix(in oklch,${cfg.color} 15%,transparent)`,
              display: "grid", placeItems: "center", color: cfg.color }}>
              {I(cfg.icon, { size: 20 })}
            </div>
            <div>
              <div className="serif" style={{ fontSize: 16 }}>
                {form.missionName || form.company || form.families?.split(",")[0] || cfg.label}
              </div>
              <div className="muted mono" style={{ fontSize: 12 }}>{cfg.label}</div>
            </div>
          </div>
          <div className="hr"/>
          {cfg.id === "space" && (
            <>
              {[["Orbit", form.orbit || "—"], ["Mass", form.mass ? form.mass + " kg" : "—"],
                ["Customer", form.customer || "—"], ["Launch", form.launchDate || "—"]].map(([k, v]) => (
                <div key={k} style={{ display: "grid", gridTemplateColumns: "80px 1fr", gap: 8, padding: "3px 0" }}>
                  <span className="label">{k}</span>
                  <span className="mono" style={{ fontSize: 12, color: "var(--ink-2)" }}>{v}</span>
                </div>
              ))}
            </>
          )}
          {cfg.id === "mittelstand" && (
            <>
              {[["Company", form.company || "—"], ["Employees", form.employees || "—"],
                ["Segment", form.segment || "—"], ["ERP", form.erp || "—"]].map(([k, v]) => (
                <div key={k} style={{ display: "grid", gridTemplateColumns: "80px 1fr", gap: 8, padding: "3px 0" }}>
                  <span className="label">{k}</span>
                  <span className="mono" style={{ fontSize: 12, color: "var(--ink-2)" }}>{v}</span>
                </div>
              ))}
            </>
          )}
          {cfg.id === "pump" && (
            <>
              {[["Company", form.company || "—"], ["Markets", form.markets || "—"],
                ["Installed Base", form.installedBase || "—"], ["OEM / AM", `${form.oemPct || "—"}% / ${form.amPct || "—"}%`]].map(([k, v]) => (
                <div key={k} style={{ display: "grid", gridTemplateColumns: "80px 1fr", gap: 8, padding: "3px 0" }}>
                  <span className="label">{k}</span>
                  <span className="mono" style={{ fontSize: 12, color: "var(--ink-2)" }}>{v}</span>
                </div>
              ))}
            </>
          )}
          {cfg.id === "pyrolysis" && (
            <>
              {[["Customer", form.customer || "—"], ["Capacity", form.capacity ? form.capacity + " t/yr" : "—"],
                ["Feedstock", form.feedstock || "—"], ["Char Grade", form.charGrade || "—"]].map(([k, v]) => (
                <div key={k} style={{ display: "grid", gridTemplateColumns: "80px 1fr", gap: 8, padding: "3px 0" }}>
                  <span className="label">{k}</span>
                  <span className="mono" style={{ fontSize: 12, color: "var(--ink-2)" }}>{v}</span>
                </div>
              ))}
            </>
          )}
        </div>
      </Panel>

      {/* BOM columns preview */}
      <Panel title="BOM Column Preview">
        <div style={{ padding: 10 }}>
          <div style={{ display: "flex", gap: 4, flexWrap: "wrap" }}>
            {["Part", "Name", "Qty", "Rev", ...cfg.bomExtra].map((c, i) => (
              <span key={c} className="tag" style={{ fontSize: 12,
                borderColor: i >= 4 ? `color-mix(in oklch,${cfg.color} 40%,var(--line))` : "var(--line)",
                color: i >= 4 ? cfg.color : "var(--ink-3)" }}>{c}</span>
            ))}
          </div>
          <div className="muted mono" style={{ fontSize: 12, marginTop: 8 }}>
            {cfg.bomExtra.length} vertical-specific columns added
          </div>
        </div>
      </Panel>

      {/* Lifecycle stages */}
      <Panel title="Lifecycle Stages">
        <div style={{ padding: 10 }}>
          {cfg.lifecycleStages.map((s, i) => {
            const _lifecycleIconStyle = { width: 18, height: 18, borderRadius: 4, display: "grid", placeItems: "center",
              background: i < 2 ? cfg.color : "var(--bg-2)",
              border: `1px solid ${i < 2 ? cfg.color : "var(--line)"}`,
              fontFamily: "var(--font-mono)", fontSize: 12,
              color: i < 2 ? "oklch(0.14 0.02 55)" : "var(--ink-3)" };
            return (
            <div key={s} style={{ display: "flex", alignItems: "center", gap: 8, padding: "4px 0",
              borderBottom: "1px solid var(--line-soft)" }}>
              <div style={_lifecycleIconStyle}>
                {i < 2 ? "✓" : i + 1}
              </div>
              <span style={{ fontSize: 12, color: i < 2 ? cfg.color : i === 2 ? "var(--ink)" : "var(--ink-3)" }}>{s}</span>
              {i === 2 && <Pill tone="accent" dot={false} style={{ marginLeft: "auto" }}>CURRENT</Pill>}
            </div>
            );
          })}
        </div>
      </Panel>

      {/* Module summary */}
      {isLastStep && (
        <Panel title="Active Modules">
          <div style={{ padding: 10 }}>
            <div className="mono tnum" style={{ fontSize: 24, color: cfg.color, marginBottom: 4 }}>{activeCount}</div>
            <div className="muted" style={{ fontSize: 12, marginBottom: 10 }}>modules enabled</div>
            <div style={{ display: "flex", flexWrap: "wrap", gap: 4 }}>
              {MODULE_CATALOG.reduce((acc, m) => { if (mods[m.id]) acc.push(m); return acc; }, []).map(m => (
                <span key={m.id} style={{ display: "inline-flex", alignItems: "center", gap: 4,
                  padding: "2px 7px", borderRadius: 3,
                  background: `color-mix(in oklch,${cfg.color} 12%,transparent)`,
                  border: `1px solid color-mix(in oklch,${cfg.color} 30%,var(--line))` }}>
                  <span style={{ color: cfg.color }}>{I(m.icon, { size: 10 })}</span>
                  <span className="mono" style={{ fontSize: 12, color: cfg.color }}>{m.name}</span>
                </span>
              ))}
            </div>
          </div>
        </Panel>
      )}
    </div>
  );
}

// ─── Loading overlay shown during preset → dashboard transition (Wave 8I) ─
// Renders for ~1s after a "Load X demo →" click. Two jobs:
//   1. Tell the user *something* is happening (one-click flows feel broken
//      without feedback when the route swap is fast).
//   2. Give the tenant-change event a beat to propagate (300-500ms) so
//      listeners in app-shell, api.js, useTenantState, etc. settle BEFORE
//      the dashboard mounts and starts fetching with the new tenant id.
function PresetLoadingOverlay({ label, color }) {
  const _overlayStyle = {
    position: "fixed", inset: 0, zIndex: 9999,
    display: "grid", placeItems: "center",
    background: "color-mix(in oklch, var(--bg-0, oklch(0.99 0.003 85)) 92%, transparent)",
    backdropFilter: "blur(4px)",
    WebkitBackdropFilter: "blur(4px)",
  };
  const _cardStyle = {
    display: "flex", flexDirection: "column", alignItems: "center", gap: 14,
    padding: "26px 38px", borderRadius: 12,
    border: `1px solid color-mix(in oklch,${color} 35%,var(--line))`,
    background: "var(--bg-1)",
    boxShadow: `0 18px 48px color-mix(in oklch,${color} 18%,transparent)`,
  };
  const _spinnerStyle = {
    width: 28, height: 28, borderRadius: "50%",
    border: `2px solid color-mix(in oklch,${color} 18%,transparent)`,
    borderTopColor: color,
    animation: "forge-preset-spin .8s linear infinite",
  };
  return (
    <div style={_overlayStyle} aria-live="polite" aria-busy="true">
      <style>{`@keyframes forge-preset-spin { to { transform: rotate(360deg); } }`}</style>
      <div style={_cardStyle}>
        <div style={_spinnerStyle}/>
        <div className="mono" style={{ fontSize: 12, letterSpacing: ".08em", textTransform: "uppercase", color: "var(--ink-3)" }}>
          Loading {label}…
        </div>
      </div>
    </div>
  );
}

// ─── Main ScreenOnboarding ────────────────────────────────────────────────
function ScreenOnboarding({ setToast, onComplete }) {
  const [vertId, setVertId] = uSOB(null);
  const [step,   setStep]   = uSOB(0);
  const [form,   setForm]   = uSOB({});
  const [mods,   setMods]   = uSOB({});
  // { tenantId, label, color } while a preset is mid-transition, else null.
  const [loading, setLoading] = uSOB(null);

  // go(tenant, path) — Wave 8I bypass helper.
  // Sequence: set tenant → wait ~350ms so the tenant-change event reaches
  // listeners (app-shell tenant switcher, api.js cache reset, useTenantState
  // bumps) → navigate. The visible overlay covers the gap so the user never
  // sees a flash of the old tenant's content on /forge/dashboard.
  const go = (tenant, path) => {
    if (typeof setActiveTenant === "function") setActiveTenant(tenant);
    setTimeout(() => {
      if (typeof window !== "undefined" && typeof window.navigate === "function") {
        window.navigate(path);
      } else if (typeof window !== "undefined") {
        window.location.hash = path;
      }
      // Hold the overlay ~650ms past navigation so the dashboard's first
      // paint happens behind it; total visible time ≈ 1.0s.
      setTimeout(() => setLoading(null), 650);
    }, 350);
  };

  const pickVert = (id) => {
    // Demo bypass map: card id → { tenantId, label, color } for overlay.
    const bypassMap = {
      "tritan-pump":         { tenantId: "tritan",      label: "Tritan",      color: TRITAN_DEMO_VERT.color },
      "aetherion-space":     { tenantId: "aetherion",   label: "Aetherion",   color: AETHERION_DEMO_VERT.color },
      "mittelstand-machine": { tenantId: "mittelstand", label: "Mittelstand", color: MITTELSTAND_DEMO_VERT.color },
    };
    const bypass = bypassMap[id];
    if (bypass) {
      // Guard against double-clicks while the overlay is up.
      if (loading) return;
      setLoading(bypass);
      go(bypass.tenantId, "/forge/dashboard");
      return;
    }
    setVertId(id);
    setStep(0);
    setForm({});
    const cfg = VERTICALS[id];
    setMods(Object.fromEntries(MODULE_CATALOG.map(m => [m.id, cfg.defaultModules.includes(m.id)])));
  };

  if (!vertId) return (
    <>
      <VertPicker onPick={pickVert}/>
      {loading && <PresetLoadingOverlay label={loading.label} color={loading.color}/>}
    </>
  );

  const cfg = VERTICALS[vertId];

  const finish = () => {
    const payload = {
      vertId,
      vertLabel: cfg.label,
      mods: Object.entries(mods).reduce((acc, [k, v]) => { if (v) acc.push(k); return acc; }, []),
      form,
      ts: new Date().toISOString(),
    };
    if (onComplete) onComplete(payload);
    else if (setToast) setToast("✓ Forge configured — welcome aboard");
  };

  return (
    <div style={{ display: "grid", gridTemplateColumns: "220px 1fr 280px", gap: 14, padding: 14, height: "100%", minHeight: 0 }}>
      <StepperCol cfg={cfg} step={step} setStep={setStep} onReset={() => { setVertId(null); setStep(0); }}/>
      <FormArea cfg={cfg} step={step} setStep={setStep} form={form} setForm={setForm} mods={mods} setMods={setMods} setToast={setToast} onFinish={finish}/>
      <PreviewCol cfg={cfg} step={step} form={form} mods={mods}/>
    </div>
  );
}

Object.assign(window, { ScreenOnboarding });
