/* DOMINANCE — Page: Intake (Client Intelligence Onboarding).
   Lives at hash route #/intake. Multi-section, one-question-at-a-time premium
   intake. Extends the apply-flow design language with richer input types
   (textarea / chips / upload / link) and a section-segmented progress rail.

   Save & resume via localStorage. Submit POSTs to /api/intake (stubbed —
   currently logs + falls through to a thank-you state). Token / gated access
   to be added in Phase 2.

   Reads window.INTAKE_SECTIONS from intake-questions.js. */

const INTAKE_LS_KEY_PREFIX = "dominance_intake_v2_"; // per-token

function readTokenFromHash() {
  // hash routes look like "#/intake?t=abc123" — extract t after ?
  const h = (window.location.hash || "").replace(/^#/, "");
  const qIdx = h.indexOf("?");
  if (qIdx < 0) return "";
  const params = new URLSearchParams(h.slice(qIdx + 1));
  return params.get("t") || "";
}

function IntakePage({ navigate }) {
  const SECTIONS = window.INTAKE_SECTIONS || [];

  // ---------- token gating ----------
  const [token] = React.useState(readTokenFromHash);
  const [tokenState, setTokenState] = React.useState({ status: "checking", clientName: "", niche: "" });
  // tokenState.status: 'checking' | 'valid' | 'invalid' | 'submitted'

  React.useEffect(() => {
    if (!token) { setTokenState({ status: "invalid", reason: "missing" }); return; }
    fetch(`/api/intake-token?t=${encodeURIComponent(token)}`)
      .then((r) => r.json())
      .then((j) => {
        if (!j.ok) { setTokenState({ status: "invalid", reason: j.error || "unknown" }); return; }
        if (j.status === "submitted") { setTokenState({ status: "submitted" }); return; }
        setTokenState({ status: "valid", clientName: j.clientName || "", niche: j.niche || "" });
      })
      .catch((err) => setTokenState({ status: "invalid", reason: String(err) }));
  }, [token]);

  const LS_KEY = `${INTAKE_LS_KEY_PREFIX}${token || "anon"}`;

  // ---------- state ----------
  const [sIdx, setSIdx] = React.useState(0); // current section index
  const [qIdx, setQIdx] = React.useState(0); // current question index WITHIN visible questions
  const [answers, setAnswers] = React.useState({});
  const [files, setFiles] = React.useState({}); // {qId: [File,...]}  — kept in memory only until submit
  const [direction, setDirection] = React.useState(1);
  const [submitting, setSubmitting] = React.useState(false);
  // phase: 'idle' → 'compiling' → 'done'
  const [phase, setPhase] = React.useState("idle");

  // ---------- load from localStorage (per-token) ----------
  React.useEffect(() => {
    try {
      const raw = localStorage.getItem(LS_KEY);
      if (raw) {
        const saved = JSON.parse(raw);
        if (saved.answers) setAnswers(saved.answers);
        if (typeof saved.sIdx === "number") setSIdx(saved.sIdx);
        if (typeof saved.qIdx === "number") setQIdx(saved.qIdx);
      }
    } catch {}
  }, [LS_KEY]);

  // ---------- save to localStorage on change ----------
  React.useEffect(() => {
    try {
      localStorage.setItem(
        LS_KEY,
        JSON.stringify({ answers, sIdx, qIdx, savedAt: Date.now() }),
      );
    } catch {}
  }, [answers, sIdx, qIdx, LS_KEY]);

  // ---------- derived ----------
  const section = SECTIONS[sIdx] || SECTIONS[0];
  // questions visible in this section under current answers (showIf)
  const visibleQs = React.useMemo(
    () => section.questions.filter((q) => !q.showIf || q.showIf(answers)),
    [section, answers],
  );
  const safeQIdx = Math.min(qIdx, Math.max(visibleQs.length - 1, 0));
  const currentQ = visibleQs[safeQIdx];

  // ---------- section progress (answered required / total required, capped at 1) ----------
  const sectionProgress = (s) => {
    const visible = s.questions.filter((q) => !q.showIf || q.showIf(answers));
    const req = visible.filter((q) => q.required);
    if (req.length === 0) return 1; // no required = full once entered
    const answered = req.filter((q) => isAnswered(answers, files, q)).length;
    return Math.min(1, answered / req.length);
  };

  const totalRequired = SECTIONS.reduce(
    (acc, s) => acc + s.questions.filter((q) => (!q.showIf || q.showIf(answers)) && q.required).length,
    0,
  );
  const totalAnswered = SECTIONS.reduce(
    (acc, s) =>
      acc +
      s.questions.filter(
        (q) => (!q.showIf || q.showIf(answers)) && q.required && isAnswered(answers, files, q),
      ).length,
    0,
  );
  const totalQuestions = SECTIONS.reduce(
    (acc, s) => acc + s.questions.filter((q) => !q.showIf || q.showIf(answers)).length,
    0,
  );
  const totalAnsweredAny = SECTIONS.reduce(
    (acc, s) =>
      acc +
      s.questions.filter(
        (q) => (!q.showIf || q.showIf(answers)) && isAnswered(answers, files, q),
      ).length,
    0,
  );

  // ---------- nav ----------
  const goNext = () => {
    if (currentQ && currentQ.required && !isAnswered(answers, files, currentQ)) return;
    setDirection(1);
    if (safeQIdx < visibleQs.length - 1) {
      setQIdx(safeQIdx + 1);
    } else if (sIdx < SECTIONS.length - 1) {
      setSIdx(sIdx + 1);
      setQIdx(0);
    } else {
      handleSubmit();
    }
  };
  const goBack = () => {
    setDirection(-1);
    if (safeQIdx > 0) {
      setQIdx(safeQIdx - 1);
    } else if (sIdx > 0) {
      const prev = SECTIONS[sIdx - 1];
      const prevVisible = prev.questions.filter((q) => !q.showIf || q.showIf(answers));
      setSIdx(sIdx - 1);
      setQIdx(Math.max(prevVisible.length - 1, 0));
    } else {
      navigate("/");
    }
  };

  // ---------- keyboard ----------
  React.useEffect(() => {
    const onKey = (e) => {
      if (e.key === "Escape") return; // don't leave on Esc — intake is gated work
      const tag = (e.target && e.target.tagName) || "";
      const inField = tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT";
      if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
        e.preventDefault();
        goNext();
        return;
      }
      if (inField) return;
      if (e.key === "ArrowLeft") goBack();
      if (e.key === "ArrowRight") goNext();
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [safeQIdx, sIdx, answers]);

  // ---------- submit ----------
  // Flow:
  //   1. Switch to compiling phase IMMEDIATELY — animation runs while we work.
  //   2. Upload every attached file to Vercel Blob → collect URLs per qId.
  //   3. Build qMeta with answers + fileUrls in the schema order/labels.
  //   4. POST /api/intake → Brain Dump assembled server-side, Slack fired,
  //      Drive upload via Apps Script.
  //   5. Clear localStorage. The compiling component flips to Done on its own
  //      timer; on submit failure we still let it finish (don't yank the UX).
  const handleSubmit = async () => {
    setSubmitting(true);
    setPhase("compiling");

    // 2. Upload files in parallel per question
    const fileUrls = {};
    const allUploads = [];
    for (const [qId, list] of Object.entries(files)) {
      if (!list || !list.length) continue;
      fileUrls[qId] = [];
      list.forEach((file) => {
        const url = `/api/intake-upload?token=${encodeURIComponent(token)}&qId=${encodeURIComponent(qId)}&fname=${encodeURIComponent(file.name)}`;
        allUploads.push(
          fetch(url, {
            method: "POST",
            headers: { "Content-Type": file.type || "application/octet-stream" },
            body: file,
          })
            .then((r) => r.json())
            .then((j) => { if (j.ok && j.url) fileUrls[qId].push(j.url); })
            .catch((err) => console.error("[intake] upload failed", file.name, err)),
        );
      });
    }
    if (allUploads.length) await Promise.all(allUploads);

    // 3. Build qMeta from visible questions only
    const qMeta = [];
    SECTIONS.forEach((s) => {
      s.questions.forEach((q) => {
        if (q.showIf && !q.showIf(answers)) return;
        qMeta.push({
          id: q.id,
          sectionId: s.id,
          section: s.label,
          label: q.label,
          type: q.type,
          required: !!q.required,
          value: answers[q.id] != null ? answers[q.id] : (q.type === "chips" ? [] : ""),
          fileUrls: fileUrls[q.id] || [],
        });
      });
    });

    const totalsPayload = {
      requiredAnswered: totalAnswered,
      requiredTotal: totalRequired,
      totalAnswered: totalAnsweredAny,
      total: totalQuestions,
    };

    // 4. POST to /api/intake
    try {
      await fetch("/api/intake", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ token, qMeta, totals: totalsPayload }),
      });
    } catch (err) {
      console.error("[intake] submit failed:", err);
    }

    try { localStorage.removeItem(LS_KEY); } catch {}
    setSubmitting(false);
    // phase stays 'compiling'; IntakeCompiling triggers onDone → 'done'
  };

  // ---------- handlers per field ----------
  const setAnswer = (id, val) => setAnswers((p) => ({ ...p, [id]: val }));
  const addChip = (id, val) => {
    const v = String(val || "").trim();
    if (!v) return;
    setAnswers((p) => {
      const cur = Array.isArray(p[id]) ? p[id] : [];
      if (cur.includes(v)) return p;
      return { ...p, [id]: [...cur, v] };
    });
  };
  const removeChip = (id, idx) =>
    setAnswers((p) => {
      const cur = Array.isArray(p[id]) ? p[id] : [];
      return { ...p, [id]: cur.filter((_, i) => i !== idx) };
    });
  const addFiles = (id, list) =>
    setFiles((p) => ({ ...p, [id]: [...(p[id] || []), ...Array.from(list)] }));
  const removeFile = (id, idx) =>
    setFiles((p) => ({ ...p, [id]: (p[id] || []).filter((_, i) => i !== idx) }));

  // ---------- TOKEN GATE ----------
  if (tokenState.status === "checking") return <IntakeChecking />;
  if (tokenState.status === "invalid")  return <IntakeInvalid reason={tokenState.reason} />;
  if (tokenState.status === "submitted") return <IntakeAlreadySubmitted />;

  // ---------- COMPILING / DONE screens ----------
  if (phase === "compiling") {
    return <IntakeCompiling sections={SECTIONS} onDone={() => setPhase("done")} />;
  }
  if (phase === "done") {
    return <IntakeDone clientName={tokenState.clientName} />;
  }

  // ---------- RENDER ----------
  const stepNumber = `${String(sIdx + 1).padStart(2, "0")}`;
  const stepTotal = `${String(SECTIONS.length).padStart(2, "0")}`;

  return (
    <main className="intake-page">
      <div className="intake-container">
        {/* Section progress rail (top) */}
        <div className="intake-progress" role="presentation">
          {SECTIONS.map((s, i) => {
            const p = sectionProgress(s);
            const cls =
              i < sIdx ? "done" :
              i === sIdx ? "active" : "future";
            return (
              <div key={s.id} className={`intake-seg ${cls}`}>
                <div className="intake-seg-bar">
                  <div
                    className="intake-seg-fill"
                    style={{ width: `${(i < sIdx ? 1 : i === sIdx ? p : 0) * 100}%` }}
                  />
                </div>
                <div className="intake-seg-label">
                  <span className="intake-seg-num">{String(i + 1).padStart(2, "0")}</span>
                  <span className="intake-seg-name">{s.label}</span>
                </div>
              </div>
            );
          })}
        </div>

        {/* Header bar */}
        <header className="intake-head">
          <div className="intake-head-label">
            <img src="assets/dominance-d-white.png" alt="" className="intake-d" />
            <span>
              Client Intelligence Intake
              {tokenState.clientName ? <em className="intake-head-client"> · {tokenState.clientName}</em> : null}
            </span>
          </div>
          <span className="intake-step-count">
            <b>{stepNumber}</b>
            <span className="sep">/</span>
            <span className="of">{stepTotal}</span>
          </span>
          <div className="intake-save">
            <span className="intake-save-dot" />
            Saved
          </div>
        </header>

        {/* Body — glass panel */}
        <section className="intake-body">
          <div className={`intake-panel ${direction > 0 ? "in-fwd" : "in-back"}`} key={`${sIdx}-${safeQIdx}`}>
            {/* Section eyebrow + name (only on first Q of section) */}
            {safeQIdx === 0 && (
              <div className="intake-section-eyebrow">
                <div className="intake-section-mono">{section.mono}</div>
                <h2 className="intake-section-title">{section.label}</h2>
                <p className="intake-section-intro">{section.intro}</p>
                <div className="intake-rule" />
              </div>
            )}

            {currentQ && (
              <div className="intake-q">
                <div className="intake-q-section-tag">
                  <span className="intake-q-section-num">{String(sIdx + 1).padStart(2, "0")}</span>
                  <span className="intake-q-section-name">{section.label}</span>
                </div>
                <div className="intake-q-meta">
                  <span className="intake-q-dot" />
                  Question {String(safeQIdx + 1).padStart(2, "0")}
                  <span className="intake-q-of">of {String(visibleQs.length).padStart(2, "0")}</span>
                  {currentQ.required ? (
                    <span className="intake-q-req">REQUIRED</span>
                  ) : (
                    <span className="intake-q-opt">OPTIONAL</span>
                  )}
                </div>

                <h3 className="intake-q-label">{currentQ.label}</h3>

                {currentQ.hint && (
                  <div className="intake-q-hint">
                    <p className="intake-q-hint-lead">{currentQ.hint.lead}</p>
                    <p className="intake-q-hint-body">{currentQ.hint.body}</p>
                    <div className="intake-q-hint-stat">
                      <span className="intake-q-hint-dot" />
                      {currentQ.hint.stat}
                    </div>
                  </div>
                )}

                <div className="intake-q-input">
                  <FieldRouter
                    q={currentQ}
                    value={answers[currentQ.id]}
                    files={files[currentQ.id] || []}
                    onText={(v) => setAnswer(currentQ.id, v)}
                    onAddChip={(v) => addChip(currentQ.id, v)}
                    onRemoveChip={(i) => removeChip(currentQ.id, i)}
                    onAddFiles={(list) => addFiles(currentQ.id, list)}
                    onRemoveFile={(i) => removeFile(currentQ.id, i)}
                  />
                </div>
              </div>
            )}
          </div>
        </section>

        {/* Footer */}
        <footer className="intake-foot">
          <button className="btn-ghost intake-back" onClick={goBack} type="button">
            <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M19 12H5 M11 19l-7-7 7-7" /></svg>
            Back
          </button>
          <div className="intake-foot-meter">
            <span className="intake-foot-meter-mono">
              {totalAnswered} / {totalRequired} REQUIRED
              <span className="intake-foot-meter-total"> · {totalAnsweredAny} / {totalQuestions} TOTAL</span>
            </span>
            <div className="intake-foot-meter-bar">
              <div
                className="intake-foot-meter-fill"
                style={{ width: `${totalRequired ? (totalAnswered / totalRequired) * 100 : 0}%` }}
              />
            </div>
          </div>
          <button
            className="btn intake-next"
            onClick={goNext}
            disabled={submitting || (currentQ && currentQ.required && !isAnswered(answers, files, currentQ))}
            type="button"
          >
            <span className="glint" />
            <span>
              {submitting
                ? "Sending…"
                : sIdx === SECTIONS.length - 1 && safeQIdx === visibleQs.length - 1
                ? "Submit intake"
                : "Continue"}
            </span>
            <span className="arrow">→</span>
          </button>
        </footer>
      </div>
    </main>
  );
}

// ---------- helpers ----------
function isAnswered(answers, files, q) {
  const v = answers[q.id];
  if (q.type === "chips") return Array.isArray(v) && v.length > 0;
  if (q.type === "upload") {
    const list = files[q.id] || [];
    return list.length > 0;
  }
  if (q.type === "link") return typeof v === "string" && /^https?:\/\/\S+/.test(v.trim());
  return typeof v === "string" && v.trim().length > 0;
}

// ---------- field router ----------
function FieldRouter({ q, value, files, onText, onAddChip, onRemoveChip, onAddFiles, onRemoveFile }) {
  if (q.type === "text" || q.type === "link") {
    return (
      <input
        className="intake-input"
        type={q.type === "link" ? "url" : "text"}
        value={value || ""}
        placeholder={q.placeholder}
        onChange={(e) => onText(e.target.value)}
        autoFocus
      />
    );
  }
  if (q.type === "textarea") {
    return (
      <>
        <textarea
          className="intake-textarea"
          rows={6}
          value={value || ""}
          placeholder={q.placeholder}
          onChange={(e) => onText(e.target.value)}
          autoFocus
        />
        {q.attach && (
          <AttachStrip
            label={q.attach.label}
            files={files}
            onAddFiles={onAddFiles}
            onRemoveFile={onRemoveFile}
          />
        )}
      </>
    );
  }
  if (q.type === "chips") return <ChipsField q={q} value={value || []} onAdd={onAddChip} onRemove={onRemoveChip} />;
  if (q.type === "upload") return <UploadField q={q} files={files} onAddFiles={onAddFiles} onRemoveFile={onRemoveFile} />;
  if (q.type === "select") {
    return (
      <div className="intake-select">
        {(q.options || []).map((opt) => (
          <button
            key={opt}
            className={`intake-select-opt${value === opt ? " selected" : ""}`}
            onClick={() => onText(opt)}
            type="button"
          >
            {opt}
          </button>
        ))}
      </div>
    );
  }
  return null;
}

// ---------- chips ----------
function ChipsField({ q, value, onAdd, onRemove }) {
  const [draft, setDraft] = React.useState("");
  const commit = () => {
    if (!draft.trim()) return;
    // split on comma so "a, b, c" also works
    draft.split(",").forEach((v) => onAdd(v.trim()));
    setDraft("");
  };
  return (
    <div className="intake-chips">
      <div className="intake-chip-list">
        {value.map((v, i) => (
          <span key={i} className="intake-chip">
            {v}
            <button className="intake-chip-x" onClick={() => onRemove(i)} type="button" aria-label="Remove">
              ×
            </button>
          </span>
        ))}
      </div>
      <div className="intake-chip-input-row">
        <input
          className="intake-input"
          value={draft}
          placeholder={q.placeholder}
          onChange={(e) => setDraft(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === "Enter") {
              e.preventDefault();
              commit();
            }
          }}
          autoFocus
        />
        <button className="btn-ghost intake-chip-add" onClick={commit} type="button">
          + Add
        </button>
      </div>
      <div className="intake-hint-line">Press Enter or comma to add. Click × to remove.</div>
    </div>
  );
}

// ---------- attach strip (paperclip under textarea) ----------
function AttachStrip({ label, files, onAddFiles, onRemoveFile }) {
  const inputRef = React.useRef(null);
  const [dragOver, setDragOver] = React.useState(false);
  return (
    <div
      className={`intake-attach${dragOver ? " drag-over" : ""}${files.length > 0 ? " has-files" : ""}`}
      onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
      onDragLeave={() => setDragOver(false)}
      onDrop={(e) => {
        e.preventDefault();
        setDragOver(false);
        if (e.dataTransfer.files && e.dataTransfer.files.length) onAddFiles(e.dataTransfer.files);
      }}
    >
      <button
        type="button"
        className="intake-attach-row"
        onClick={() => inputRef.current && inputRef.current.click()}
      >
        <svg className="intake-attach-clip" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
          <path d="M21.44 11.05 12.25 20.24a6 6 0 0 1-8.49-8.49L13.95 1.56a4 4 0 0 1 5.66 5.66L9.41 17.41a2 2 0 1 1-2.83-2.83l8.49-8.48" />
        </svg>
        <span className="intake-attach-label">{label}</span>
        <span className="intake-attach-cta">+ Browse</span>
      </button>
      <input
        ref={inputRef}
        type="file"
        multiple
        style={{ display: "none" }}
        onChange={(e) => e.target.files && onAddFiles(e.target.files)}
      />
      {files.length > 0 && (
        <div className="intake-attach-list">
          {files.map((f, i) => (
            <div key={i} className="intake-attach-item">
              <svg viewBox="0 0 24 24" width="11" height="11" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
                <path d="M21.44 11.05 12.25 20.24a6 6 0 0 1-8.49-8.49L13.95 1.56a4 4 0 0 1 5.66 5.66L9.41 17.41a2 2 0 1 1-2.83-2.83l8.49-8.48" />
              </svg>
              <span className="intake-attach-item-name">{f.name}</span>
              <span className="intake-attach-item-size">{Math.round(f.size / 1024)} KB</span>
              <button type="button" className="intake-attach-item-x" onClick={() => onRemoveFile(i)}>×</button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ---------- upload ----------
function UploadField({ q, files, onAddFiles, onRemoveFile }) {
  const inputRef = React.useRef(null);
  const [dragOver, setDragOver] = React.useState(false);
  return (
    <div
      className={`intake-upload${dragOver ? " drag-over" : ""}`}
      onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
      onDragLeave={() => setDragOver(false)}
      onDrop={(e) => {
        e.preventDefault();
        setDragOver(false);
        if (e.dataTransfer.files && e.dataTransfer.files.length) onAddFiles(e.dataTransfer.files);
      }}
    >
      <div className="intake-upload-icon">
        <svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
          <path d="M12 3v12 M7 8l5-5 5 5 M5 21h14" />
        </svg>
      </div>
      <div className="intake-upload-prompt">
        <b>Drop files here</b> or{" "}
        <button className="intake-upload-browse" onClick={() => inputRef.current && inputRef.current.click()} type="button">
          browse
        </button>
      </div>
      <div className="intake-upload-sub">{q.placeholder}</div>
      <input
        ref={inputRef}
        type="file"
        multiple
        style={{ display: "none" }}
        onChange={(e) => e.target.files && onAddFiles(e.target.files)}
      />
      {files.length > 0 && (
        <div className="intake-upload-list">
          {files.map((f, i) => (
            <div key={i} className="intake-upload-item">
              <span className="intake-upload-item-name">{f.name}</span>
              <span className="intake-upload-item-size">{Math.round(f.size / 1024)} KB</span>
              <button className="intake-upload-item-x" onClick={() => onRemoveFile(i)} type="button">×</button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ---------- compiling interstitial (between Submit and Done) ----------
function IntakeCompiling({ sections, onDone }) {
  const [step, setStep] = React.useState(0); // 0..sections.length+1
  React.useEffect(() => {
    const timers = [];
    sections.forEach((_, i) => {
      timers.push(setTimeout(() => setStep(i + 1), 360 + i * 260));
    });
    const lockAt = 360 + sections.length * 260 + 240;
    timers.push(setTimeout(() => setStep(sections.length + 1), lockAt));
    timers.push(setTimeout(() => onDone(), lockAt + 1100));
    return () => timers.forEach(clearTimeout);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  const locked = step >= sections.length + 1;
  return (
    <main className="intake-page">
      <div className={`intake-container intake-compiling${locked ? " locked" : ""}`}>
        <div className="intake-compiling-mono">
          <span className="intake-compiling-mono-dot" />
          {locked ? "FILE LOCKED · ENCRYPTED" : "COMPILING INTELLIGENCE FILE"}
        </div>
        <h2 className="intake-compiling-title">
          {locked ? "Sealed." : "Finalizing your file."}
        </h2>
        <ul className="intake-compiling-list">
          {sections.map((s, i) => {
            const done = step > i;
            const active = step === i + 1 && !done;
            return (
              <li
                key={s.id}
                className={`intake-compiling-item${done ? " done" : ""}${step >= i + 1 ? " active" : ""}`}
              >
                <span className="intake-compiling-check">
                  {done ? (
                    <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
                      <path d="M5 12l5 5L20 7" />
                    </svg>
                  ) : (
                    <span className="intake-compiling-pip" />
                  )}
                </span>
                <span className="intake-compiling-num">{String(i + 1).padStart(2, "0")}</span>
                <span className="intake-compiling-name">{s.label}</span>
                <span className="intake-compiling-status">
                  {done ? "SAVED" : step >= i + 1 ? "WRITING…" : "QUEUED"}
                </span>
              </li>
            );
          })}
        </ul>
        <div className={`intake-compiling-lockbar${locked ? " active" : ""}`}>
          <div className="intake-compiling-lockbar-fill" />
        </div>
      </div>
    </main>
  );
}

// ---------- done screen ----------
function IntakeDone({ clientName }) {
  return (
    <main className="intake-page">
      <div className="intake-container intake-done">
        <div className="intake-done-mono">INTAKE LOCKED · 100%</div>
        <h1 className="intake-done-title">
          {clientName ? `Thank you, ${clientName}.` : "Your intelligence file is locked."}
          <br />We start building.
        </h1>
        <p className="intake-done-sub">
          You'll hear from us within one business day with the first ICP draft, your dedicated sending domain plan, and the warmup schedule. No further action needed from you today.
        </p>
        <div className="intake-rule" />
        <div className="intake-done-meta">
          <div><span className="mono">NEXT</span> ICP confirmation · 24h</div>
          <div><span className="mono">THEN</span> 14-day warmup · sending begins day 15</div>
          <div><span className="mono">GUARANTEE</span> 5 qualified calls in the first 30 days post-warmup</div>
        </div>
      </div>
    </main>
  );
}

// ---------- token-gate screens ----------
function IntakeChecking() {
  return (
    <main className="intake-page">
      <div className="intake-container intake-gate">
        <div className="intake-gate-mono">
          <span className="intake-compiling-mono-dot" />
          VERIFYING LINK
        </div>
        <h1 className="intake-gate-title">Authenticating your intake link…</h1>
        <p className="intake-gate-sub">One moment.</p>
      </div>
    </main>
  );
}

function IntakeInvalid({ reason }) {
  return (
    <main className="intake-page">
      <div className="intake-container intake-gate intake-gate-error">
        <div className="intake-gate-mono">LINK NOT ACTIVE</div>
        <h1 className="intake-gate-title">This intake link isn't active.</h1>
        <p className="intake-gate-sub">
          Either it expired, was already used, or was mis-copied. Reply to the email it
          came in and we'll send a fresh one within the hour.
        </p>
        {reason && <div className="intake-gate-meta">Reference: <code>{reason}</code></div>}
      </div>
    </main>
  );
}

function IntakeAlreadySubmitted() {
  return (
    <main className="intake-page">
      <div className="intake-container intake-gate">
        <div className="intake-gate-mono">FILE LOCKED · 100%</div>
        <h1 className="intake-gate-title">Your intake is already in our system.</h1>
        <p className="intake-gate-sub">
          Nothing more to do here. We're already building. You'll hear from us within
          one business day if you haven't already.
        </p>
      </div>
    </main>
  );
}

window.IntakePage = IntakePage;
