// ═══════════════════════════════════════════════════════════════════
// WORKFLOW TEMPLATE — WFT-v2 (platform canonical · source of truth)
// The universal three-phase pipeline every class runs, plus each class's
// phase-02 research branch. PROJECT WORKFLOWS INSTANTIATE THIS TEMPLATE
// (WorkflowPage reads window.WORKFLOW_TEMPLATE; it never defines its own).
// Card→step coverage is DERIVED from the Report Schema — not duplicated.
// ═══════════════════════════════════════════════════════════════════
(function () {
  const RS = window.REPORT_SCHEMA;

  const PHASES = [
    {
      n: "01", name: "Parse & Comprehend",
      goal: "turn uploaded artifacts into a sourced Knowledge Base and a typed Knowledge Graph",
      steps: [
        { id: "parse",      name: "Parse documents",       agent: "parser-1",    desc: "OCR + structure recovery over every artifact in the Registry — text, tables, defined terms." },
        { id: "extract",    name: "Extract datapoints",    agent: "extractor-1", desc: "Typed memory keys with value, source and confidence — every datapoint cites exactly one artifact." },
        { id: "kb",         name: "Build Knowledge Base",  agent: "librarian-1", desc: "Dedupe, then classify every fact against the canonical datapoint register — 268 datapoints across four tiers, each typed and evidenced." },
        { id: "kg",         name: "Build Knowledge Graph", agent: "librarian-1", desc: "Entities and relationships typed to the ontology — Issuer → Project → Asset → Offering, bound by controlled vocabularies." },
        { id: "entity",     name: "Build Entity Registry", agent: "librarian-1", desc: "Resolve the typed graph nodes into the Entity Registry — the deal objects (Company · Project · Asset · Offering) as queryable, deduplicated records." },
      ],
    },
    {
      n: "02", name: "Deep Research",
      goal: "check the knowledge against the outside world before anything is written",
      steps: [
        { id: "background", name: "Entity background",   agent: "research-1", desc: "Registries, EDGAR, KYB, sanctions and adverse media on every entity in the graph." },
        { id: "crosscheck", name: "Fact cross-checks",   agent: "verifier-1", desc: "Material claims checked against external sources — disagreements land in the contradiction register." },
        { id: "market",     name: "Market research",     agent: "research-2", desc: "TAM, comparables and the regulatory landscape — classed assumption / hypothesis until evidence lands." },
        { id: "gaps",       name: "Gap analysis",        agent: "verifier-1", desc: "Synthesize the open evidence gaps from background, cross-checks and market research — each gap names the document that closes it (Report Schema RS-07)." },
      ],
    },
    {
      n: "03", name: "Build Intelligence Report",
      goal: "compose each delivered report from the Knowledge Base, gate on a human, publish versioned",
      steps: [
        { id: "compose_brief",     name: "Compose Executive Brief",     agent: "composer-1", composes: ["G1"],             desc: "Verdict, thesis, top findings, strengths/asks and the risk register — plus the change digest vs the last version. Generated from the Knowledge Base; nothing free-written." },
        { id: "compose_passport",  name: "Compose Product Passport",    agent: "composer-1", composes: ["G2", "G3", "G4"], desc: "The class-specific subject, instrument and model — the pricing, revenue, market and technology registries assembled for this asset class from the typed datapoints." },
        { id: "compose_intel",     name: "Compose Intelligence Report", agent: "composer-1", composes: ["G5", "G7", "G9"],       desc: "Verification, contradictions and open evidence gaps; the structural-relations read off the typed graph (load-bearing & at-risk edges); and the citation registry with source reliability, version lineage and page/section locators." },
        { id: "compose_strategic", name: "Compose Strategic Review",    agent: "composer-1", composes: ["G6", "G8"],       desc: "Readiness gates and ranked actions, plus the opportunity register — the forward upside, each item scored for confidence and strategic impact." },
        { id: "review",  name: "Human review",   agent: "human gate", gate: true, desc: "Analyst validates the schema-coverage matrix below — every required card filled or explicitly gapped — and signs off on the named gaps. Nothing publishes with a missing card." },
        { id: "publish", name: "Publish",        agent: "system",     desc: "Versioned into the Document Library and rendered live on the Intelligence page." },
      ],
    },
  ];

  const STEP_ARTIFACT = {
    parse:      { id: "WF-01", name: "Parsed Corpus",            from: "registry artifacts" },
    extract:    { id: "WF-02", name: "Datapoint Set",            from: "WF-01" },
    kb:         { id: "WF-03", name: "Knowledge Base",           from: "WF-02 · classified V/P/A/H/Q/U", to: "kb" },
    kg:         { id: "WF-04", name: "Entity Graph",             from: "WF-03 · typed to ontology", to: "graph" },
    entity:     { id: "WF-04b", name: "Entity Registry",          from: "WF-04 · graph nodes as typed deal objects", to: "entity" },
    background: { id: "WF-05", name: "Background Memos",         from: "WF-04 + external registries" },
    crosscheck: { id: "WF-06", name: "Verification Ledger",      from: "WF-03 + public sources" },
    market:     { id: "WF-07", name: "Market Research Memo",     from: "WF-03 + web research" },    gaps:       { id: "WF-08", name: "Evidence Gap Register",    from: "WF-05 + WF-06 + WF-07" },
    compose_brief:     { id: "WF-09a", name: "Executive Brief draft",     from: "WF-03 … WF-08 · verdict & thesis",      to: "report" },
    compose_passport:  { id: "WF-09b", name: "Product Passport draft",    from: "WF-02 … WF-07 · class sections",       to: "report" },
    compose_intel:     { id: "WF-09c", name: "Intelligence Report draft", from: "WF-05 … WF-08 · diligence & sources",   to: "report" },
    compose_strategic: { id: "WF-09d", name: "Strategic Review draft",    from: "WF-08 + KB · gates · actions · opps",   to: "report" },
    review:     { id: "WF-10", name: "Sign-off Record",          from: "WF-09 · section completeness validated" },
    publish:    { id: "WF-11", name: "Published Report",         from: "WF-09 + WF-10 · versioned", to: "library" },
  };

  const RESEARCH = {
    realEstate: [
      { id: "re_title",     name: "Title & entitlement check",       agent: "research-3", step: "background", desc: "Land control, title, zoning and entitlement status verified against county and planning records." },
      { id: "re_env",       name: "Environmental site assessment",   agent: "research-1", step: "background", desc: "Phase I ESA and contamination / flood / seismic exposure reviewed against site records." },
      { id: "re_lease",     name: "Rent roll & tenant verification", agent: "verifier-1", step: "crosscheck", desc: "Rent roll, lease terms and WALT confirmed against executed leases and tenant credit." },
      { id: "re_appraisal", name: "Appraisal & comparables",         agent: "research-2", step: "market",     desc: "Independent valuation and recent comparable sales / cap-rate evidence for the asset and submarket." },
    ],
    equity: [
      { id: "oc_corp",     name: "Corporate & cap-table diligence", agent: "research-3", step: "background", desc: "Incorporation, cap table, IP assignment and prior-financing terms confirmed against filings." },
      { id: "oc_ip",       name: "IP & technology verification",    agent: "verifier-1", step: "crosscheck", desc: "Ownership of core IP and product claims verified against registrations and technical review." },
      { id: "oc_customer", name: "Customer & reference checks",     agent: "research-2", step: "market",     desc: "Pipeline, retention and reference calls validating the traction narrative." },
    ],
    credit: [
      { id: "pc_borrower",   name: "Borrower credit & payment history", agent: "research-3", step: "background", desc: "Borrower financial condition, leverage and payment / default history verified against filings and bureaus." },
      { id: "pc_recovery",   name: "Covenant & recovery analysis",      agent: "verifier-1", step: "crosscheck", desc: "Covenant headroom and recovery / loss-given-default under the stress case." },
      { id: "pc_collateral", name: "Collateral valuation & lien check", agent: "research-2", step: "market",     desc: "Independent valuation and lien perfection across the collateral package." },
    ],
    fund: [
      { id: "fd_track", name: "Track-record audit",          agent: "research-3", step: "background", desc: "Realized & unrealized performance reconstructed and reconciled to administrator statements." },
      { id: "fd_nav",   name: "Portfolio mark / NAV check",  agent: "verifier-1", step: "crosscheck", desc: "Current holdings and marks verified against the administrator and the stated valuation policy." },
      { id: "fd_refs",  name: "Reference & LP checks",       agent: "research-2", step: "market",     desc: "GP background and LP reference calls across prior vintages." },
    ],
    commodity: [
      { id: "cm_resource", name: "Reserve & resource certification",        agent: "research-3", step: "background", desc: "Independent reserve / resource certification (competent person) and extraction-licence verification." },
      { id: "cm_env",      name: "Environmental & decommissioning liability", agent: "research-1", step: "background", desc: "ESG compliance, permits and end-of-life / decommissioning obligations assessed against the operator." },
      { id: "cm_operator", name: "Operator & offtake check",                agent: "verifier-1", step: "crosscheck", desc: "Operator track record and supply / offtake contracts verified with counterparties." },
      { id: "cm_price",    name: "Price deck & hedging review",             agent: "research-2", step: "market",     desc: "Forward price deck benchmarked to forward curves; hedging and basis risk reviewed." },
    ],
    infrastructure: [
      { id: "in_availability", name: "Capacity & availability audit",     agent: "research-3", step: "background", desc: "Independent engineering certification of capacity and historical availability / performance." },
      { id: "in_regulatory",   name: "Regulatory & interconnection review", agent: "research-1", step: "background", desc: "FERC / PUC / ISO interconnection, permits and rate exposure reviewed against the regime." },
      { id: "in_offtake",      name: "Offtake / PPA & counterparty credit", agent: "verifier-1", step: "crosscheck", desc: "PPA / offtake tenor and counterparty credit verified against the executed contracts." },
      { id: "in_tariff",       name: "Tariff & merchant-exposure benchmark", agent: "research-2", step: "market",     desc: "Contracted vs merchant revenue and tariff benchmarked to comparable assets." },
    ],
    collectible: [
      { id: "co_authenticity", name: "Authentication & attribution",   agent: "research-3", step: "background", desc: "Authenticity and attribution verified by a recognised authority / catalogue raisonné." },
      { id: "co_condition",    name: "Condition & conservation report", agent: "research-1", step: "background", desc: "Independent condition grading, restoration history and conservation needs." },
      { id: "co_provenance",   name: "Provenance & title chain",        agent: "verifier-1", step: "crosscheck", desc: "Unbroken ownership history and clear title verified against registries and prior sales." },
      { id: "co_comps",        name: "Appraisal & comparables",         agent: "research-2", step: "market",     desc: "Independent appraisal and comparable auction / private-sale records." },
    ],
  };

  // ── helpers ────────────────────────────────────────────────────────
  const branchFor = (classId) => RESEARCH[classId] || [];
  // per (class, step) → the report cards that step fills, derived from the
  // Report Schema (the source of truth for report cards). No duplication.
  const cardsByStep = (classId) => {
    const out = {};
    ((RS && RS.groupsForClass && RS.groupsForClass(classId)) || []).forEach((g) =>
      g.subs.forEach((sub) => sub.cards.forEach(([type, def, step]) => {
        (out[step] = out[step] || []).push({ group: g.label, classSpecific: !!g.classSpecific, type, def });
      })));
    return out;
  };
  const researchByStep = (classId) => {
    const out = {};
    branchFor(classId).forEach((r) => { (out[r.step] = out[r.step] || []).push(r); });
    return out;
  };
  const STEP_LABEL = { parse: "01 · Parse", extract: "01 · Extract", kb: "01 · Knowledge Base", kg: "01 · Knowledge Graph", entity: "01 · Entity Registry", background: "02 · Background", crosscheck: "02 · Cross-check", market: "02 · Market", gaps: "02 · Gaps", compose: "03 · Compose", compose_brief: "03 · Executive Brief", compose_passport: "03 · Product Passport", compose_intel: "03 · Intelligence Report", compose_strategic: "03 · Strategic Review", review: "03 · Review", publish: "03 · Publish" };

  window.WORKFLOW_TEMPLATE = { id: "WFT-v2", PHASES, STEP_ARTIFACT, RESEARCH, branchFor, cardsByStep, researchByStep, STEP_LABEL };

  // ═══ platform page: the canonical templates ═══════════════════════
  function WorkflowTemplatesPage({ proj, go }) {
    const RSx = window.REPORT_SCHEMA;
    const CLASSES = (window.ONTOLOGY && window.ONTOLOGY.ASSET_CLASSES) || [];
    const AClass = window.AssetClass;
    const def = (proj && AClass) ? AClass.of(proj) : (CLASSES[0] && CLASSES[0].id);
    const [sel, setSel] = React.useState(def);
    const cls = CLASSES.find((c) => c.id === sel) || CLASSES[0];
    const projs = ((window.INTEL && window.INTEL.PROJECTS) || []).filter((p) => AClass && AClass.of(p) === (cls && cls.id));
    const cbs = cardsByStep(cls.id);
    const totalSteps = PHASES.reduce((n, p) => n + p.steps.length, 0);
    const mono = (s, x) => <span style={{ fontFamily: "var(--mono)", fontSize: "8.5px", letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--ink-4)", ...x }}>{s}</span>;
    const linkBtn = { border: "1px solid var(--accent-bd)", background: "var(--accent-bg)", color: "var(--accent-lo)", borderRadius: "var(--r-1)", padding: "4px 9px", cursor: "pointer", fontFamily: "var(--mono)", fontSize: "8.5px", fontWeight: 600, letterSpacing: "0.06em", textTransform: "uppercase" };

    return (
      <div>
        <window.PageHead eyebrow="Platform · Source of truth" title="Workflow Templates"
          sub="The canonical pipeline every project workflow instantiates — three dedicated phases (Parse & Comprehend · Deep Research · Build) shared by all classes, plus each class's phase-02 research branch. A project's Workflow is an INSTANCE of this template carrying run state; what each step must produce is derived from the Report Schema, never re-declared here."
          right={<div style={{ textAlign: "right" }}>
            {mono("WFT-v2 · 3 phases · " + totalSteps + " steps", { display: "block", marginBottom: 4, color: "var(--accent-lo)" })}
            {mono(CLASSES.length + " class branches")}
          </div>}>
        </window.PageHead>

        <window.SectionHead sub="class-agnostic — every project runs these three phases in order; each step emits a named artifact">Universal Pipeline</window.SectionHead>
        <div style={{ display: "grid", gap: 12, marginBottom: 24 }}>
          {PHASES.map((p) => (
            <div key={p.n} style={{ border: "1px solid var(--rule-hard)", borderRadius: "var(--r-3)", overflow: "hidden", background: "var(--bg)" }}>
              <div style={{ background: "var(--bg-dark)", color: "#fff", padding: "10px 15px", display: "flex", alignItems: "baseline", gap: 10, flexWrap: "wrap" }}>
                <span style={{ fontFamily: "var(--mono)", fontSize: "10px", fontWeight: 600, color: "var(--accent-hi)" }}>{p.n}</span>
                <span style={{ fontFamily: "var(--ui-display)", fontWeight: 600, fontSize: "var(--fs-sm)" }}>{p.name}</span>
                <span style={{ fontSize: "var(--fs-xs)", color: "#aab4d4" }}>{p.goal}</span>
              </div>
              <div style={{ padding: "2px 14px 8px" }}>
                {p.steps.map((s, i) => {
                  const art = STEP_ARTIFACT[s.id];
                  return (
                    <div key={s.id} style={{ borderTop: i ? "1px solid var(--rule-soft)" : "none", padding: "9px 0", display: "grid", gridTemplateColumns: "176px 1fr 168px", gap: 12, alignItems: "baseline" }}>
                      <div style={{ display: "flex", alignItems: "center", gap: 7 }}>
                        <span style={{ fontFamily: "var(--ui-display)", fontWeight: 600, fontSize: "var(--fs-sm)", color: "var(--ink)" }}>{s.name}</span>
                        {s.gate && <window.Pill tone="warn">gate</window.Pill>}
                      </div>
                      <span style={{ fontSize: "var(--fs-xs)", color: "var(--ink-3)", lineHeight: 1.5 }}>{s.desc}</span>
                      <span style={{ display: "inline-flex", flexDirection: "column", gap: 2 }}>
                        {art && <span style={{ fontFamily: "var(--mono)", fontSize: "8.5px", color: "var(--accent-lo)" }}>⧉ {art.id} · {art.name}</span>}
                        <span style={{ fontFamily: "var(--mono)", fontSize: "8px", color: "var(--ink-4)" }}>{s.agent}</span>
                      </span>
                    </div>
                  );
                })}
              </div>
            </div>
          ))}
        </div>

        <window.SectionHead sub="how a workflow step becomes part of a delivered report — reverse of the hierarchy Report › Group (RS) › Section › Card">Build Chain — step to report</window.SectionHead>
        <div style={{ border: "1px solid var(--rule-hard)", borderRadius: "var(--r-3)", background: "var(--bg-2)", padding: "14px 16px", marginBottom: 24 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 7, flexWrap: "wrap" }}>
            {[["Workflow Step", "fills from KB", "var(--ink-4)"], ["Card", "the leaf archetype", "var(--accent)"], ["Section", "sub-section", "var(--accent)"], ["Group · RS", "G1–G9", "var(--ink-4)"], ["Report", "by cadence", "var(--ink)"]].map(([label, sub, col], i) => (
              <React.Fragment key={label}>
                {i > 0 && <span style={{ fontFamily: "var(--mono)", fontSize: "12px", color: "var(--ink-4)" }}>→</span>}
                <span style={{ display: "inline-flex", flexDirection: "column", gap: 2, border: "1px solid var(--rule-hard)", borderTop: "2px solid " + col, borderRadius: "var(--r-2)", background: "var(--bg)", padding: "6px 11px" }}>
                  <span style={{ fontFamily: "var(--ui-display)", fontWeight: 600, fontSize: "11px", color: "var(--ink)" }}>{label}</span>
                  <span style={{ fontFamily: "var(--mono)", fontSize: "7.5px", letterSpacing: "0.04em", color: "var(--ink-4)" }}>{sub}</span>
                </span>
              </React.Fragment>
            ))}
          </div>
          <p style={{ margin: "11px 0 12px", fontFamily: "var(--mono)", fontSize: "8.5px", letterSpacing: "0.04em", color: "var(--ink-4)", lineHeight: 1.6 }}>
            Below: the inverse, derived from the Report Schema (RPT-v3) — step → the RS sections it emits.
          </p>
          {(() => {
            const SECS = (RSx && RSx.SECTIONS) || [];
            const ORDER = ["parse", "extract", "kb", "kg", "entity", "background", "crosscheck", "market", "gaps", "compose", "review", "publish"];
            const rows = ORDER.map((st) => [st, SECS.filter((s) => s.step === st)]).filter(([, ss]) => ss.length);
            return (
              <div style={{ border: "1px solid var(--rule-hard)", borderRadius: "var(--r-2)", overflow: "hidden", background: "var(--bg)" }}>
                <div style={{ display: "grid", gridTemplateColumns: "180px 1fr", gap: 1, background: "var(--rule)" }}>
                  {["Workflow step", "Emits sections (RS)"].map((h) => (
                    <div key={h} style={{ background: "var(--bg-2)", padding: "6px 11px" }}><window.MonoLabel>{h}</window.MonoLabel></div>
                  ))}
                  {rows.map(([st, ss]) => (
                    <React.Fragment key={st}>
                      <div style={{ background: "var(--bg)", padding: "7px 11px", fontFamily: "var(--mono)", fontSize: "9px", color: "var(--ink-2)" }}>{STEP_LABEL[st] || st}</div>
                      <div style={{ background: "var(--bg)", padding: "7px 11px", display: "flex", gap: 5, flexWrap: "wrap" }}>
                        {ss.map((s) => (
                          <span key={s.id} title={s.name} style={{ fontFamily: "var(--mono)", fontSize: "8.5px", letterSpacing: "0.04em", color: s.req ? "var(--accent-lo)" : "var(--ink-4)", border: "1px solid " + (s.req ? "var(--accent-bd)" : "var(--rule-hard)"), background: s.req ? "var(--accent-bg)" : "var(--bg-2)", borderRadius: "999px", padding: "1px 7px" }}>{s.id}</span>
                        ))}
                      </div>
                    </React.Fragment>
                  ))}
                </div>
              </div>
            );
          })()}
        </div>

        <window.SectionHead sub="select a class — its phase-02 research branch, then the steps that produce its class-specific report cards (the cards are owned by the Report Schema)">Per-class Specialization</window.SectionHead>
        <div style={{ display: "inline-flex", flexWrap: "wrap", border: "1px solid var(--rule-hard)", borderRadius: "var(--r-2)", overflow: "hidden", background: "var(--bg)", marginBottom: 14 }}>
          {CLASSES.map((c, i) => (
            <button key={c.id} onClick={() => setSel(c.id)} style={{ display: "inline-flex", alignItems: "center", gap: 6, border: "none", borderLeft: i ? "1px solid var(--rule-hard)" : "none", background: sel === c.id ? "var(--bg-dark)" : "transparent", color: sel === c.id ? "#fff" : "var(--ink-3)", padding: "7px 13px", cursor: "pointer", fontFamily: "var(--mono)", fontSize: "9.5px", letterSpacing: "0.04em", textTransform: "uppercase", fontWeight: 600 }}>
              <span style={{ fontSize: 11 }}>{c.glyph}</span>{c.name}
            </button>
          ))}
        </div>

        <div style={{ border: "1px solid var(--rule-hard)", borderRadius: "var(--r-3)", overflow: "hidden", marginBottom: 14 }}>
          <div style={{ background: "var(--bg-2)", padding: "9px 14px", borderBottom: "1px solid var(--rule-soft)", display: "flex", alignItems: "center", gap: 9 }}>
            <span style={{ fontSize: 13, color: "var(--accent-lo)" }}>{cls.glyph}</span>
            <span style={{ fontFamily: "var(--ui-display)", fontWeight: 600, fontSize: "var(--fs-sm)", color: "var(--ink)" }}>{cls.name}</span>
            <span style={{ fontFamily: "var(--mono)", fontSize: "8.5px", color: "var(--ink-4)" }}>phase-02 research branch · {branchFor(cls.id).length} tasks</span>
          </div>
          <div style={{ padding: "10px 14px", display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(280px, 1fr))", gap: 8 }}>
            {branchFor(cls.id).map((r) => (
              <div key={r.id} style={{ border: "1px solid var(--rule-hard)", borderRadius: "var(--r-2)", background: "var(--bg)", padding: "9px 12px" }}>
                <div style={{ display: "flex", alignItems: "center", gap: 7, marginBottom: 4 }}>
                  <span style={{ fontFamily: "var(--ui-display)", fontWeight: 600, fontSize: "var(--fs-sm)", color: "var(--ink)" }}>{r.name}</span>
                  <span style={{ marginLeft: "auto", display: "inline-flex", gap: 5 }}>
                    <span style={{ fontFamily: "var(--mono)", fontSize: "8px", color: "var(--ink-4)", border: "1px solid var(--rule)", borderRadius: "var(--r-1)", padding: "1px 5px", whiteSpace: "nowrap" }}>{STEP_LABEL[r.step] || r.step}</span>
                    <span style={{ fontFamily: "var(--mono)", fontSize: "8px", color: "var(--accent-lo)", border: "1px solid var(--accent-bd)", background: "var(--accent-bg)", borderRadius: "var(--r-1)", padding: "1px 6px", whiteSpace: "nowrap" }}>{r.agent}</span>
                  </span>
                </div>
                <p style={{ margin: 0, fontSize: "var(--fs-xs)", color: "var(--ink-3)", lineHeight: 1.45 }}>{r.desc}</p>
              </div>
            ))}
          </div>
        </div>

        <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap", border: "1px dashed var(--rule-hard)", borderRadius: "var(--r-2)", background: "var(--bg-2)", padding: "10px 14px", marginBottom: 18 }}>
          <span style={{ fontSize: "var(--fs-xs)", color: "var(--ink-3)", lineHeight: 1.5, flex: 1, minWidth: 260 }}>
            What each step must <span style={{ fontStyle: "italic" }}>produce</span> for {cls.name} — the report cards — is owned by the Report Schema, not this template. Every card names the step that fills it; the run validates coverage against it.
          </span>
          <button onClick={() => go("rptref")} style={linkBtn}>Report Schema ↗</button>
        </div>

        <window.SectionHead sub="project workflows that instantiate this template for the selected class">Instantiated By</window.SectionHead>
        <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
          {projs.length ? projs.map((p) => (
            <span key={p.id} style={{ display: "inline-flex", alignItems: "center", gap: 8, border: "1px solid var(--rule-hard)", borderRadius: "var(--r-2)", background: "var(--bg)", padding: "7px 12px" }}>
              <span style={{ fontFamily: "var(--ui-display)", fontWeight: 600, fontSize: "var(--fs-sm)", color: "var(--ink)" }}>{p.name}</span>
              <window.Pill tone="ok">instance</window.Pill>
            </span>
          )) : <span style={{ fontFamily: "var(--mono)", fontSize: "9px", color: "var(--ink-4)" }}>No project bound to this class yet — template available.</span>}
        </div>

        <p style={{ margin: "16px 0 0", fontFamily: "var(--mono)", fontSize: "9px", letterSpacing: "0.06em", color: "var(--ink-4)", lineHeight: 1.7 }}>
          WFT-v2 is the single source of truth for the pipeline. Project workflows read it and add run state; the per-class report cards above are derived from the Report Schema (RPT-v3). Editing the template propagates to every project workflow that instantiates it.
        </p>
      </div>
    );
  }
  window.WorkflowTemplatesPage = WorkflowTemplatesPage;
})();
