/* =========================================================================
   Shared primitive components for the MEL Toolkit
   ========================================================================= */

const { useState, useEffect, useRef, useMemo, useCallback } = React;

/* ---------- Icons (inline SVG; lightweight, on-brand) ---------- */
function Icon({ name, size = 16, ...rest }) {
  const stroke = "currentColor";
  const sw = 1.7;
  const common = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke, strokeWidth: sw, strokeLinecap: "round", strokeLinejoin: "round", ...rest };
  switch (name) {
    case "check":  return <svg {...common}><path d="M20 6L9 17l-5-5" /></svg>;
    case "lock":   return <svg {...common}><rect x="5" y="11" width="14" height="9" rx="1.5" /><path d="M8 11V8a4 4 0 0 1 8 0v3" /></svg>;
    case "chev-r": return <svg {...common}><path d="M9 6l6 6-6 6" /></svg>;
    case "chev-l": return <svg {...common}><path d="M15 6l-9 6 9 6" /></svg>;
    case "arrow-r":return <svg {...common}><path d="M5 12h14M13 5l7 7-7 7" /></svg>;
    case "arrow-l":return <svg {...common}><path d="M19 12H5M11 5l-7 7 7 7" /></svg>;
    case "spark":  return <svg {...common}><path d="M12 3v4M12 17v4M3 12h4M17 12h4M6 6l2.5 2.5M15.5 15.5L18 18M6 18l2.5-2.5M15.5 8.5L18 6" /></svg>;
    case "doc":    return <svg {...common}><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z" /><path d="M14 3v6h6M9 13h6M9 17h6" /></svg>;
    case "menu":   return <svg {...common}><path d="M4 6h16M4 12h16M4 18h16" /></svg>;
    case "print":  return <svg {...common}><path d="M6 9V4h12v5M6 18h-2a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-2M6 14h12v8H6z" /></svg>;
    case "save":   return <svg {...common}><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" /><path d="M17 21v-8H7v8M7 3v5h8" /></svg>;
    case "info":   return <svg {...common}><circle cx="12" cy="12" r="9" /><path d="M12 8v.01M11 12h1v5h1" /></svg>;
    case "warn":   return <svg {...common}><path d="M12 3l10 18H2L12 3z" /><path d="M12 10v5M12 18v.01" /></svg>;
    case "pencil": return <svg {...common}><path d="M12 20h9M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" /></svg>;
    default: return null;
  }
}

/* ---------- Button ---------- */
function Btn({ children, variant = "primary", icon, iconRight, ...rest }) {
  return (
    <button className={`btn btn--${variant}`} {...rest}>
      {icon && <Icon name={icon} size={15} />}
      {children}
      {iconRight && <Icon name={iconRight} size={15} />}
    </button>
  );
}

/* =========================================================================
   Sidebar TOC — supports "full" (default), "sectioned" (lessons collapsed
   by default), and "rail" (slim 64px step circles only)
   ========================================================================= */
function Sidebar({ steps, flat, currentIdx, onJump, onOpenReport, projectName, mode = "full", onRename, onReset }) {
  // Expand the step that contains current lesson
  const currentStepId = flat[currentIdx]?.stepId;

  // Sectioned mode: only expand the step that contains the current lesson, by default
  const [expanded, setExpanded] = useState(() => {
    if (mode === "sectioned") return new Set([currentStepId]);
    return new Set(steps.map(s => s.id));
  });

  // Inline project name editing
  const [editing, setEditing] = useState(false);
  const [editVal, setEditVal] = useState("");
  const nameInputRef = useRef(null);

  const startEdit = () => {
    setEditVal(projectName || "");
    setEditing(true);
    requestAnimationFrame(() => nameInputRef.current?.select());
  };
  const commitEdit = () => {
    setEditing(false);
    const trimmed = editVal.trim();
    if (onRename) onRename(trimmed || projectName);
  };
  const onKeyDown = (e) => {
    if (e.key === "Enter")  { e.preventDefault(); commitEdit(); }
    if (e.key === "Escape") { setEditing(false); }
  };

  useEffect(() => {
    setExpanded(prev => {
      const next = new Set(prev);
      next.add(currentStepId);
      return next;
    });
  }, [currentStepId]);

  const toggle = (id) => {
    setExpanded(prev => {
      const n = new Set(prev);
      if (n.has(id)) n.delete(id); else n.add(id);
      return n;
    });
  };

  const completedCount = currentIdx;
  const totalCount = flat.length;
  const pct = Math.round((completedCount / totalCount) * 100);

  /* ----- Rail mode: tiny vertical strip of step circles ----- */
  if (mode === "rail") {
    return (
      <aside className="sidebar sidebar--rail">
        <div className="sidebar-rail__inner">
          {steps.map(step => {
            // Compute progress within this step
            const lessonsDone = step.lessons.filter(lsn => {
              const i = flat.findIndex(f => f.id === lsn.id);
              return i < currentIdx;
            }).length;
            const lessonsTotal = step.lessons.length;
            const stepPct = (lessonsDone / lessonsTotal) * 100;
            const isCurrent = step.id === currentStepId;
            // jump to first lesson of step
            const firstFlatIdx = flat.findIndex(f => f.stepId === step.id);
            return (
              <button
                key={step.id}
                className={`sidebar-rail__step ${isCurrent ? "sidebar-rail__step--current" : ""}`}
                onClick={() => onJump(firstFlatIdx)}
                title={`Step ${step.number} — ${step.title} · ${lessonsDone}/${lessonsTotal}`}
              >
                <svg className="sidebar-rail__ring" viewBox="0 0 40 40">
                  <circle cx="20" cy="20" r="17" fill="none" stroke="var(--border-soft)" strokeWidth="3" />
                  <circle
                    cx="20" cy="20" r="17"
                    fill="none"
                    stroke={step.colorHex}
                    strokeWidth="3"
                    strokeLinecap="round"
                    strokeDasharray={`${(stepPct * 106.8) / 100} 106.8`}
                    transform="rotate(-90 20 20)"
                  />
                </svg>
                <span className="sidebar-rail__num" style={{ background: step.colorHex }}>{step.number}</span>
                <span className="sidebar-rail__tip">
                  Step {step.number} · {step.title}
                  <span className="sidebar-rail__tip-prog">{lessonsDone}/{lessonsTotal}</span>
                </span>
              </button>
            );
          })}
          <button className="sidebar-rail__report" onClick={onOpenReport} title="View MEL report">
            <Icon name="doc" size={18} />
          </button>
        </div>
      </aside>
    );
  }

  /* ----- Full + Sectioned modes ----- */
  return (
    <aside className={`sidebar sidebar--${mode}`}>
      <div className="sidebar__intro">
        <div className="sidebar__heading">Your project</div>
        <div className="sidebar__project-row">
          {editing ? (
            <input
              ref={nameInputRef}
              className="sidebar__project-input"
              value={editVal}
              onChange={e => setEditVal(e.target.value)}
              onBlur={commitEdit}
              onKeyDown={onKeyDown}
              autoFocus
            />
          ) : (
            <>
              <span className="sidebar__project">{projectName || "Untitled MEL plan"}</span>
              <button className="sidebar__rename-btn" onClick={startEdit} title="Rename project">
                <Icon name="pencil" size={13} />
              </button>
            </>
          )}
        </div>
        <div className="sidebar__progressbar">
          <div className="sidebar__progressfill" style={{ width: `${pct}%` }} />
        </div>
        <div className="sidebar__progresstext">{completedCount} of {totalCount} sections complete · {pct}%</div>
      </div>

      {steps.map(step => {
        const isExp = expanded.has(step.id);
        const isIntroActive = flat[currentIdx]?.type === "section-intro" && flat[currentIdx]?.stepId === step.id;
        const lessonsDone = step.lessons.filter(lsn => {
          const i = flat.findIndex(f => f.id === lsn.id);
          return i < currentIdx;
        }).length;
        return (
          <div key={step.id} className={`step-block ${isExp ? "step-block--expanded" : ""} ${isIntroActive ? "step-block--intro-current" : ""}`}>
            <div className="step-block__head">
              <span
                className="step-block__num"
                style={{ background: step.colorHex, ...(isIntroActive && { boxShadow: `0 0 0 3px white, 0 0 0 5px ${step.colorHex}55` }) }}
                onClick={() => {
                  const introFlatIdx = step.sectionIntro ? flat.findIndex(f => f.id === `si-${step.id}`) : flat.findIndex(f => f.stepId === step.id);
                  if (introFlatIdx >= 0) onJump(introFlatIdx);
                }}
              >{step.number}</span>
              <span
                className="step-block__title"
                onClick={() => {
                  const introFlatIdx = step.sectionIntro ? flat.findIndex(f => f.id === `si-${step.id}`) : flat.findIndex(f => f.stepId === step.id);
                  if (introFlatIdx >= 0) onJump(introFlatIdx);
                }}
              >{step.title}</span>
              {mode === "sectioned" && (
                <span className="step-block__prog">{lessonsDone}/{step.lessons.length}</span>
              )}
              <span className="step-block__chev" onClick={() => toggle(step.id)}><Icon name="chev-r" size={12} /></span>
            </div>
            {isExp && (
              <div className="step-block__lessons">
                {step.lessons.map(lsn => {
                  const flatIdx = flat.findIndex(f => f.id === lsn.id);
                  const status =
                    flatIdx < currentIdx ? "done" :
                    flatIdx === currentIdx ? "current" : "upcoming";
                  return (
                    <button
                      key={lsn.id}
                      className={`lesson-row lesson-row--${status}`}
                      onClick={() => onJump(flatIdx)}
                    >
                      <span className="lesson-row__bullet">
                        {status === "done" ? <Icon name="check" size={11} /> :
                         status === "current" ? "" : ""}
                      </span>
                      <span className="lesson-row__num">{lsn.id}</span>
                      <span className="lesson-row__label">{lsn.title}</span>
                    </button>
                  );
                })}
              </div>
            )}
          </div>
        );
      })}

      <button className="sidebar__report-btn" onClick={onOpenReport}>
        <Icon name="doc" size={16} />
        Preview MEL report
        <span className="arr"><Icon name="arrow-r" size={14} /></span>
      </button>
      <a className="sidebar__pdf-link" href="assets/TTA Eval D1.2.pdf" target="_blank" rel="noopener noreferrer">
        <Icon name="doc" size={15} />
        <span className="sidebar__pdf-link-body">
          <span className="sidebar__pdf-link-label">Framework guide</span>
          <span className="sidebar__pdf-link-sub">ISD, 2025 · PDF</span>
        </span>
        <span className="arr">↗</span>
      </a>
      {onReset && (
        <button className="sidebar__reset-btn" onClick={() => {
          if (window.confirm("Clear all responses and start over? This cannot be undone.")) onReset();
        }}>
          Clear all responses
        </button>
      )}
    </aside>
  );
}

/* =========================================================================
   NavTabs — header-style nav (replaces sidebar in "tabs" mode)
   ========================================================================= */
function NavTabs({ steps, flat, currentIdx, onJump, tocLocked }) {
  const currentStepId = flat[currentIdx]?.stepId;

  return (
    <div className="nav-tabs">
      {steps.map(step => {
        const lessonsDone = step.lessons.filter(lsn => {
          const i = flat.findIndex(f => f.id === lsn.id);
          return i < currentIdx;
        }).length;
        const lessonsTotal = step.lessons.length;
        const isCurrent = step.id === currentStepId;
        const firstFlatIdx = flat.findIndex(f => f.stepId === step.id);
        const isLocked = tocLocked && step.number > 1;

        return (
          <button
            key={step.id}
            className={`nav-tab ${isCurrent ? "nav-tab--current" : ""} ${isLocked ? "nav-tab--locked" : ""}`}
            onClick={() => onJump(firstFlatIdx)}
            title={isLocked ? "Complete your Theory of Change to unlock this step" : ""}
          >
            <span className="nav-tab__num" style={{ background: step.colorHex }}>
              {isLocked ? <Icon name="lock" size={11} /> : step.number}
            </span>
            <span className="nav-tab__body">
              <span className="nav-tab__title">{step.title}</span>
              <span className="nav-tab__prog">{isLocked ? "Complete Step 1 first" : `${lessonsDone}/${lessonsTotal} sections`}</span>
            </span>
            {isCurrent && <span className="nav-tab__underline" style={{ background: step.colorHex }} />}
          </button>
        );
      })}
    </div>
  );
}

/* =========================================================================
   Minimap — floating bottom-right (replaces sidebar in "minimap" mode)
   ========================================================================= */
function Minimap({ steps, flat, currentIdx, onJump, onOpenReport, projectName }) {
  const pct = Math.round((currentIdx / flat.length) * 100);

  return (
    <div className="minimap">
      <div className="minimap__head">
        <div className="minimap__name">{projectName || "Untitled MEL plan"}</div>
        <div className="minimap__prog">{currentIdx} / {flat.length} · {pct}%</div>
      </div>
      <div className="minimap__lanes">
        {steps.map(step => (
          <div className="minimap__lane" key={step.id}>
            <span className="minimap__lane-label" style={{ color: step.colorHex }}>{step.number}</span>
            <div className="minimap__dots">
              {step.sectionIntro && (() => {
                const flatIdx = flat.findIndex(f => f.id === `si-${step.id}`);
                const status = flatIdx < currentIdx ? "done" : flatIdx === currentIdx ? "current" : "upcoming";
                return (
                  <button
                    key={`si-${step.id}`}
                    className={`minimap__dot minimap__dot--${status} minimap__dot--intro`}
                    style={status !== "upcoming" ? { background: step.colorHex } : null}
                    onClick={() => onJump(flatIdx)}
                    title={`Step ${step.number} — Introduction`}
                  />
                );
              })()}
              {step.lessons.map(lsn => {
                const flatIdx = flat.findIndex(f => f.id === lsn.id);
                const status =
                  flatIdx < currentIdx ? "done" :
                  flatIdx === currentIdx ? "current" : "upcoming";
                return (
                  <button
                    key={lsn.id}
                    className={`minimap__dot minimap__dot--${status}`}
                    style={status !== "upcoming" ? { background: step.colorHex } : null}
                    onClick={() => onJump(flatIdx)}
                    title={`${lsn.eyebrow} — ${lsn.title}`}
                  />
                );
              })}
            </div>
          </div>
        ))}
      </div>
      <button className="minimap__report" onClick={onOpenReport}>
        <Icon name="doc" size={13} />
        MEL Report
      </button>
    </div>
  );
}

/* =========================================================================
   Node card (small — completed or upcoming)
   ========================================================================= */
function NodeCard({ lesson, variant, colorHex, answer, onClick, nodeRef }) {
  // answer is a short preview snippet
  return (
    <div
      ref={nodeRef}
      className={`node node--${variant}`}
      onClick={onClick}
      title={variant === "complete" ? "Revisit this section" : "Click to jump here"}
    >
      <div className="node__topbar" style={{ background: colorHex }} />
      <div className="node__eyebrow">{lesson.eyebrow}</div>
      <div className="node__title">{lesson.title}</div>
      {variant === "complete" && answer && (
        <div className="node__answer" style={{ color: colorHex }}>{answer}</div>
      )}
      <div className="node__status">
        {variant === "complete" ? (
          <>
            <span className="node__check"><Icon name="check" size={10} /></span>
            Completed
          </>
        ) : (
          <>
            <span className="node__lock"><Icon name="lock" size={9} /></span>
            Upcoming
          </>
        )}
      </div>
    </div>
  );
}

/* =========================================================================
   Chain item — info button opens detail popup; timeframe chips open their own popup
   activeIdx: null = closed, -1 = item detail, ≥0 = subItem index
   ========================================================================= */
function ChainItem({ item, colorHex }) {
  const [activeIdx, setActiveIdx] = React.useState(null);
  const isSubitem = activeIdx !== null && activeIdx >= 0;
  const popupData = activeIdx === -1 ? item.detail : (isSubitem ? item.subItems[activeIdx] : null);

  return (
    <div className="chain-viz__item">
      <div className="chain-viz__item-head">
        <div className="chain-viz__label" style={{ color: colorHex }}>{item.label}</div>
        {item.detail && (
          <button className="chain-viz__info-btn" onClick={() => setActiveIdx(-1)} aria-label={`More about ${item.label}`}>
            <Icon name="info" size={13} />
          </button>
        )}
      </div>
      <div className="chain-viz__desc">{item.desc.split("\n").map((t, i, a) => <React.Fragment key={i}>{t}{i < a.length - 1 && <br />}</React.Fragment>)}</div>
      {item.subItems && (
        <div className="chain-viz__outcome-chips">
          {item.subItems.map((sub, i) => (
            <button key={i} className="chain-viz__outcome-chip" style={{ color: colorHex, borderColor: colorHex }} onClick={() => setActiveIdx(i)}>
              {sub.label}
            </button>
          ))}
        </div>
      )}
      {activeIdx !== null && popupData && (
        <div className="chain-viz__overlay" onClick={() => setActiveIdx(null)}>
          <div className="chain-viz__popup" onClick={e => e.stopPropagation()}>
            <button className="chain-viz__popup-close" onClick={() => setActiveIdx(null)}>✕</button>
            <div className="chain-viz__popup-label" style={{ color: colorHex }}>
              {isSubitem ? popupData.label : item.label}
            </div>
            {isSubitem ? (
              <>
                <div className="chain-viz__popup-tf">{popupData.timeframe}</div>
                <div className="chain-viz__popup-sections">
                  <div className="chain-viz__popup-section">
                    <div className="chain-viz__popup-section-head">Example</div>
                    <div className="chain-viz__popup-section-body">{popupData.desc}</div>
                  </div>
                </div>
              </>
            ) : (
              <div className="chain-viz__popup-sections">
                {popupData.include && (
                  <div className="chain-viz__popup-section">
                    <div className="chain-viz__popup-section-head">What to include</div>
                    <div className="chain-viz__popup-section-body">{popupData.include}</div>
                  </div>
                )}
                {popupData.evaluation && (
                  <div className="chain-viz__popup-section">
                    <div className="chain-viz__popup-section-head">How it's evaluated</div>
                    <div className="chain-viz__popup-section-body">{popupData.evaluation}</div>
                  </div>
                )}
                {popupData.example && (
                  <div className="chain-viz__popup-section">
                    <div className="chain-viz__popup-section-head">Example</div>
                    <div className="chain-viz__popup-section-body">{popupData.example}</div>
                  </div>
                )}
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   MethodTabs — horizontal tab strip for 3.2 method reference
   ========================================================================= */
function MethodTabs({ methods, colorHex }) {
  const [activeIdx, setActiveIdx] = React.useState(0);
  const activeColor = colorHex || "#E76863";
  const method = methods[activeIdx];

  return (
    <div className="method-tabs">
      <div className="method-tabs__bar" role="tablist">
        {methods.map((m, i) => {
          const on = i === activeIdx;
          return (
            <button
              key={i}
              role="tab"
              aria-selected={on}
              className={`method-tabs__tab ${on ? "method-tabs__tab--on" : ""}`}
              style={on ? { background: activeColor, borderColor: activeColor } : {}}
              onClick={() => setActiveIdx(i)}
            >
              {m.name}
            </button>
          );
        })}
      </div>

      <div className="method-tabs__panel" role="tabpanel">
        <div className="method-tabs__panel-name" style={{ color: activeColor }}>{method.name}</div>
        <p className="method-tabs__panel-intro">
          {Array.isArray(method.intro)
            ? method.intro.map((seg, i) => seg.href
                ? <a key={i} href={seg.href} target="_blank" rel="noopener noreferrer" style={{ color: activeColor }}>{seg.text}</a>
                : seg.text)
            : method.intro}
        </p>
        <LessonBody blocks={method.body || []} colorHex={activeColor} />
        {method.callout && <Callout data={method.callout} colorHex={activeColor} />}
      </div>
    </div>
  );
}

/* =========================================================================
   Lesson body renderer — handles different block types in content.js
   ========================================================================= */
function LessonBody({ blocks, colorHex }) {
  return (
    <div className="lesson-card__body">
      {blocks.map((b, i) => {
        switch (b.kind) {
          case "h3": return <h3 key={i}>{b.text}</h3>;
          case "p":  return <p key={i}>{b.text}</p>;
          case "p-rich": return <p key={i}>{b.segments.map((s, j) => s.bold ? <strong key={j}>{s.text}</strong> : s.text)}</p>;
          case "list": return (
            <ul key={i} style={{ color: colorHex }}>
              {b.items.map((it, j) => <li key={j} style={{ color: "var(--fg-2)" }}>{it}</li>)}
            </ul>
          );
          case "tiles": return (
            <div key={i} className="tiles">
              {b.items.map((t, j) => (
                <div className="tile" key={j}>
                  <div className="tile__title">{t.title}</div>
                  <div className="tile__text">{t.text}</div>
                </div>
              ))}
            </div>
          );
          case "chain": return (
            <div key={i} className="chain-viz">
              {b.items.map((c, j) => (
                <ChainItem key={j} item={c} colorHex={colorHex} />
              ))}
            </div>
          );
          case "callout": return <Callout key={i} data={{ kind: b.calloutKind || "tip", title: b.title, text: b.text }} colorHex={colorHex} />;
          case "method-wheel": return <MethodTabs key={i} methods={b.methods} colorHex={colorHex} />;
          case "cream": return (
            <div key={i} className="cream-grid">
              {[
                { l: "C", w: "Clear",      d: "Precise and unambiguous" },
                { l: "R", w: "Relevant",   d: "Appropriate to the subject" },
                { l: "E", w: "Economic",   d: "Available at reasonable cost" },
                { l: "A", w: "Adequate",   d: "Sufficient to assess performance" },
                { l: "M", w: "Monitorable",d: "Amenable to independent validation" }
              ].map((c, j) => (
                <div className="cream-cell" key={j}>
                  <div className="cream-cell__letter" style={{ color: colorHex }}>{c.l}</div>
                  <div className="cream-cell__word">{c.w}</div>
                  <div className="cream-cell__desc">{c.d}</div>
                </div>
              ))}
            </div>
          );
          default: return null;
        }
      })}
    </div>
  );
}

/* =========================================================================
   InfoTip — inline info icon with click-to-open popover
   ========================================================================= */
function InfoTip({ data }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);

  useEffect(() => {
    if (!open) return;
    const handler = (e) => {
      if (ref.current && !ref.current.contains(e.target)) setOpen(false);
    };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, [open]);

  return (
    <span className="info-tip" ref={ref}>
      <button className="info-tip__btn" type="button" onClick={() => setOpen(o => !o)} aria-label="More information">
        <Icon name="info" size={13} />
      </button>
      {open && (
        <div className="info-tip__popup">
          <div className="info-tip__title">{data.title}</div>
          <div className="info-tip__text">{data.text}</div>
        </div>
      )}
    </span>
  );
}

/* =========================================================================
   Callout block (tip / warn)
   ========================================================================= */
function Callout({ data, colorHex }) {
  const isTip = data.kind === "tip";
  const accentColor = colorHex || undefined;
  return (
    <div className={`callout callout--${data.kind}`} style={accentColor ? { color: accentColor } : undefined}>
      <span className="callout__icon">
        <Icon name={isTip ? "info" : "warn"} size={14} />
      </span>
      <div className="callout__body">
        <div className="callout__title">{data.title}</div>
        <div className="callout__text">{data.text}</div>
      </div>
    </div>
  );
}

/* =========================================================================
   Reflection block — the per-lesson "quiz" prompts
   ========================================================================= */
function Reflection({ lesson, answers, onChange, naState, onToggleNa, allAnswers }) {
  const isNa = lesson.allowsNotApplicable && naState && naState[lesson.id];

  if (isNa) {
    return (
      <div className="reflect reflect--na">
        <div className="reflect__na-msg">This method is marked as not applicable to your project.</div>
        <div className="reflect__na-sub">It will be omitted from your final MEL report.</div>
        <button
          className="na-toggle na-toggle--on"
          onClick={() => onToggleNa(lesson.id, false)}
        >
          <span className="na-toggle__dot" />
          Reinstate this section
        </button>
      </div>
    );
  }

  return (
    <div className="reflect">
      <div className="reflect__head">
        <span className="reflect__badge">
          <Icon name="pencil" size={10} /> Your project
        </span>
        <span className="reflect__hint">Your answers compile into your MEL report at the end.</span>
      </div>

      {lesson.prompts.map(p => {
        if (p.showIf) {
          const raw = answers[p.showIf.id];
          const actual = (raw && typeof raw === "object") ? raw.value : raw;
          if (actual !== p.showIf.value) return null;
        }
        return (
          <div className="reflect__field" key={p.id}>
            <label className="reflect__label" htmlFor={`q-${p.id}`}>
              {p.label}
              {p.info && <InfoTip data={p.info} />}
            </label>
            <PromptWidget
              prompt={p}
              value={answers[p.id]}
              onChange={(val) => onChange(p.id, val)}
              allAnswers={allAnswers}
            />
          </div>
        );
      })}

      {lesson.allowsNotApplicable && (
        <div className="na-toggle-row">
          <button
            className="na-toggle"
            onClick={() => onToggleNa(lesson.id, true)}
            title="Mark this section as not applicable to your project"
          >
            <span className="na-toggle__dot" />
            Mark as not applicable
          </button>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   Lesson Card — the big expanded current card
   ========================================================================= */
function LessonCard({ lesson, step, answers, onChange, cardRef, naState, onToggleNa }) {
  const isNa = lesson.allowsNotApplicable && naState && naState[lesson.id];

  const promptById = useMemo(() => {
    const map = {};
    (lesson.prompts || []).forEach(p => { map[p.id] = p; });
    return map;
  }, [lesson.prompts]);

  return (
    <div className="lesson-card" ref={cardRef}>
      <div className="lesson-card__topbar" style={{ background: step.colorHex }} />
      <div className="lesson-card__inner">
        <div className="lesson-card__eyebrow-row">
          <span className="lesson-card__stepbadge" style={{ background: step.colorHex }}>
            Step {step.number} · {step.title}
          </span>
          <span className="lesson-card__step-of">{lesson.eyebrow}</span>
          {isNa && (
            <span className="lesson-card__na-pill">Not applicable</span>
          )}
        </div>
        <h2 className="lesson-card__title">{lesson.title}</h2>
        {Array.isArray(lesson.intro) ? (
          <div className="lesson-card__intros">
            {lesson.intro.map((para, i) => (
              <p key={i} className={`lesson-card__intro${i === lesson.intro.length - 1 ? " lesson-card__intro--lead" : ""}`}>{para}</p>
            ))}
          </div>
        ) : (
          <p className="lesson-card__intro">{lesson.intro}</p>
        )}

        {lesson.sections ? (
          <>
            {lesson.sections.map((section, si) => (
              <React.Fragment key={si}>
                <LessonBody blocks={section.body || []} colorHex={step.colorHex} />
                <div className="reflect">
                  {si === 0 && (
                    <div className="reflect__head">
                      <span className="reflect__badge"><Icon name="pencil" size={10} /> Your project</span>
                      <span className="reflect__hint">Your answers compile into your MEL report at the end.</span>
                    </div>
                  )}
                  {(section.promptIds || []).map(pid => {
                    const p = promptById[pid];
                    if (!p) return null;
                    return (
                      <div className="reflect__field" key={p.id}>
                        <label className="reflect__label" htmlFor={`q-${p.id}`}>
                          {p.label}
                          {p.info && <InfoTip data={p.info} />}
                        </label>
                        <PromptWidget prompt={p} value={answers[p.id]} onChange={val => onChange(p.id, val)} allAnswers={answers} />
                      </div>
                    );
                  })}
                </div>
              </React.Fragment>
            ))}
            {lesson.callout && <Callout data={lesson.callout} colorHex={step.colorHex} />}
          </>
        ) : (
          <>
            <LessonBody blocks={lesson.body || []} colorHex={step.colorHex} />
            {lesson.callout && <Callout data={lesson.callout} colorHex={step.colorHex} />}
            {lesson.prompts && lesson.prompts.length > 0 && (
              <Reflection
                lesson={lesson}
                answers={answers}
                onChange={onChange}
                naState={naState}
                onToggleNa={onToggleNa}
                allAnswers={answers}
              />
            )}
          </>
        )}
      </div>
    </div>
  );
}

/* =========================================================================
   Section intro card — lesson-card shell for step transition screens
   ========================================================================= */
function SectionIntroCard({ step }) {
  const si = step.sectionIntro;
  const hasBody = si.detailA || si.detailB || si.bulletsTitle || si.callout;
  return (
    <div className="lesson-card sec-intro-card">
      <div className="sec-intro__hero" style={{ background: step.colorHex }}>
        <span className="sec-intro__hero-badge">
          Step {step.number} · {step.title}
        </span>
        <h2 className="sec-intro__hero-title">Introduction</h2>
        <p className="sec-intro__hero-body">{si.question ? `${si.question} ` : ""}{si.body}</p>
      </div>
      {hasBody && (
        <div className="sec-intro__detail-section">
          {si.detailA && <p>{si.detailA}</p>}
          {si.detailB && (
            <p>
              {si.detailB.map((seg, i) =>
                seg.href
                  ? <a key={i} href={seg.href} target="_blank" rel="noopener noreferrer">{seg.text}</a>
                  : seg.text
              )}
            </p>
          )}
          {si.bulletsTitle && (
            <div className="sec-intro__bullets">
              <p className="sec-intro__bullets-label">{si.bulletsTitle}</p>
              <ul>
                {si.bullets.map((b, i) => (
                  <li key={i}><strong>{b.term}:</strong> {b.def}</li>
                ))}
              </ul>
            </div>
          )}
          {si.callout && (
            <div className="callout callout--tip">
              <span className="callout__icon"><Icon name="info" size={14} /></span>
              <div className="callout__body">
                {si.calloutTitle && <div className="callout__title"><strong>{si.calloutTitle}</strong></div>}
                <div className="callout__text">{si.callout}</div>
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   Expose to global window scope for cross-script visibility
   ========================================================================= */
Object.assign(window, {
  Icon, Btn, Sidebar, NavTabs, Minimap, NodeCard, LessonCard,
  LessonBody, Callout, Reflection, InfoTip, MethodTabs, SectionIntroCard
});
