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

/* ============================================================
   CRM webhook
   ============================================================ */

const DEFAULT_CRM_WEBHOOK_URL =
  "http://localhost:3000/webhooks/workflows/1b236bd6-1c50-4796-9410-0f0fe40d84da/8a2dd7fd-2126-402c-89bc-c0deb78a8244";

function getCrmWebhookUrl() {
  return (window.APP_CONFIG && window.APP_CONFIG.CRM_WEBHOOK_URL) || DEFAULT_CRM_WEBHOOK_URL;
}

function splitName(fullName) {
  const trimmed = (fullName || "").trim();
  if (!trimmed) return { firstName: "", lastName: "NotProvided" };
  const parts = trimmed.split(/\s+/);
  const lastName = parts.length > 1 ? parts.slice(1).join(" ") : "NotProvided";
  return { firstName: parts[0], lastName };
}

function focusAndHighlightHeroForm() {
  const form = document.getElementById("hero-form");
  if (!form) return;
  const top = document.getElementById("top");
  if (top) top.scrollIntoView({ behavior: "smooth", block: "start" });

  form.classList.remove("form-highlight");
  void form.offsetWidth; // restart the animation if it's already mid-run
  form.classList.add("form-highlight");
  form.addEventListener(
    "animationend",
    () => form.classList.remove("form-highlight"),
    { once: true }
  );

  const firstInput = form.querySelector("input");
  if (firstInput) {
    setTimeout(() => firstInput.focus({ preventScroll: true }), 500);
  }
}

function postLeadToCrm(values) {
  const { firstName, lastName } = splitName(values.name);
  const contact = { firstName, lastName, email: values.email };
  if (values.phone && values.phone.trim()) {
    contact.phone = values.phone.trim();
  }
  if (values.business && values.business.trim()) {
    contact.businessName = values.business.trim();
  }
  fetch(getCrmWebhookUrl(), {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ source: "website", contact }),
  }).catch((err) => {
    console.warn("CRM webhook failed (non-blocking):", err);
  });
}

/* ============================================================
   Primitives
   ============================================================ */

function Eyebrow({ children }) {
  return <p className="eyebrow">{children}</p>;
}

function Button({ as = "button", variant = "primary", className = "", children, ...props }) {
  const Tag = as;
  return (
    <Tag className={`btn btn-${variant} ${className}`} {...props}>
      {children}
    </Tag>
  );
}

function Tag({ children }) {
  return <span className="tag">{children}</span>;
}

function Toast({ message, visible }) {
  return (
    <div className={`toast${visible ? " visible" : ""}`} role="status" aria-live="polite">
      {message}
    </div>
  );
}

/* ============================================================
   Lead form (shared shape, used in Hero + final CTA)
   ============================================================ */

function LeadForm({ id, compact = false, submitLabel, onSubmit }) {
  const [values, setValues] = useState({ name: "", email: "", business: "", phone: "" });
  const [submitted, setSubmitted] = useState(false);

  function update(field) {
    return (e) => {
      setValues((v) => ({ ...v, [field]: e.target.value }));
      // Editing the email invalidates the prior submission — re-arm the form.
      if (field === "email") setSubmitted(false);
    };
  }

  function handleSubmit(e) {
    e.preventDefault();
    if ((!compact && !values.name) || !values.email) return;
    onSubmit(values);
    setSubmitted(true);
  }

  return (
    <form className="lead-form" id={id} onSubmit={handleSubmit}>
      {!compact && (
        <div className="field-row">
          <label className="sr-only" htmlFor={`${id}-name`}>Name</label>
          <input
            id={`${id}-name`}
            type="text"
            placeholder="Your name"
            required
            value={values.name}
            onChange={update("name")}
          />
          <label className="sr-only" htmlFor={`${id}-business`}>Business name</label>
          <input
            id={`${id}-business`}
            type="text"
            placeholder="Business name"
            value={values.business}
            onChange={update("business")}
          />
        </div>
      )}
      <div className="field-row">
        <label className="sr-only" htmlFor={`${id}-email`}>Email</label>
        <input
          id={`${id}-email`}
          type="email"
          placeholder="you@business.com"
          required
          autoComplete="email"
          value={values.email}
          onChange={update("email")}
        />
        {!compact && (
          <>
            <label className="sr-only" htmlFor={`${id}-phone`}>Phone (optional)</label>
            <input
              id={`${id}-phone`}
              type="tel"
              placeholder="Phone (optional)"
              value={values.phone}
              onChange={update("phone")}
            />
          </>
        )}
      </div>
      <div className="form-submit-row">
        <Button type="submit" variant="primary" className="btn-block">
          {submitLabel}
        </Button>
        {submitted && (
          <span className="form-done" role="status">
            <span className="form-done-check" aria-hidden="true">✓</span> Done!
          </span>
        )}
      </div>
      <p className="form-note">No credit card required &middot; We give you free credits, you choose how to use them</p>
    </form>
  );
}

/* ============================================================
   Nav
   ============================================================ */

function Nav() {
  return (
    <header className="site-header">
      <div className="container header-inner">
        <a href="#top" className="logo">
          <img src="assets/logos/instant-studio-lockup.svg" alt="InstantStudio" className="logo-mark" />
          <span className="logo-sub">claude</span>
        </a>
        <div className="header-actions">
          <a
            href="#top"
            className="btn btn-primary"
            onClick={(e) => { e.preventDefault(); focusAndHighlightHeroForm(); }}
          >
            Start Generating Now
          </a>
        </div>
      </div>
    </header>
  );
}

/* ============================================================
   Hero
   ============================================================ */

function Hero({ onLeadCaptured }) {
  const videoRef = useRef(null);

  useEffect(() => {
    const el = videoRef.current;
    if (!el) return;
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) el.play().catch(() => {});
        else el.pause();
      },
      { threshold: 0.25 }
    );
    observer.observe(el);
    return () => observer.disconnect();
  }, []);

  return (
    <section className="hero" id="top">
      <div className="container hero-inner">
        <div>
          <Eyebrow>make videos with claude</Eyebrow>
          <h1 className="is-h1">
            Asking Claude for a video and getting back a script?
          </h1>
          <p className="hero-sub is-body-lg">
            The script is important, but did you know that now you <strong><em>can</em></strong> get
            the video result in the same conversation? Join here — and try it free.
          </p>

          <LeadForm
            id="hero-form"
            submitLabel="Set up free account"
            onSubmit={onLeadCaptured}
          />

          <div className="trust-strip">
            <span className="is-body-sm">Powered by InstantStudio — the AI video platform for creators and brands</span>
            <ul className="logo-row" aria-label="Where the connector works">
              <li>Claude on the web</li>
              <li>Claude Desktop</li>
              <li>Claude Code</li>
            </ul>
          </div>
        </div>

        <div className="hero-visual">
          <video
            ref={videoRef}
            src="assets/videos/demo-result-generated.mp4"
            poster="assets/images/demo-result-poster.webp"
            muted
            loop
            playsInline
            preload="metadata"
          />
        </div>
      </div>
    </section>
  );
}

/* ============================================================
   Trusted-by logo strip
   ============================================================ */

function TrustedBy() {
  return (
    <div className="trusted-by">
      <div className="container trusted-by-row">
        <span className="trusted-by-label">the same platform trusted by</span>
        <div className="trusted-by-logos">
          <img src="assets/logos/havas.png" alt="Havas" />
          <img src="assets/logos/maxus.webp" alt="Maxus" />
          <img src="assets/logos/kickers.webp" alt="Kickers" />
          <img src="assets/logos/sunlife-color.png" alt="Sun Life" />
          <img src="assets/logos/duvel.png" alt="Duvel" />
          <span className="trusted-by-more">+ more</span>
        </div>
      </div>
    </div>
  );
}

/* ============================================================
   How it works
   ============================================================ */

const STEPS = [
  {
    title: "Tell us about yourself",
    body: "Name, email, and business name — takes about ten seconds",
  },
  {
    title: "Get the invite",
    body: "We'll email you the invite link to InstantStudio. Click it and finish the basic profile setup",
  },
  {
    title: "Add the Connector",
    body: "We'll tell you exactly how to connect Claude to our platform in a couple simple steps",
  },
  {
    title: "Experiment",
    body: "Unleash your creativity!",
  },
];

function HowItWorks() {
  return (
    <section className="section section-alt" id="how-it-works">
      <div className="container">
        <div className="section-head">
          <Eyebrow>how it works</Eyebrow>
          <h2 className="is-h3">Tell Claude what you want and get a finished video.</h2>
          <p className="section-sub is-body">
            No timeline, no export settings — just the starting images and your guidance.
          </p>
        </div>
        <ol className="steps">
          {STEPS.map((step, i) => (
            <li className="step" key={step.title}>
              <span className="step-num">{String(i + 1).padStart(2, "0")}</span>
              <h3 className="is-h6">{step.title}</h3>
              <p className="is-body-sm">{step.body}</p>
            </li>
          ))}
        </ol>
      </div>
    </section>
  );
}

/* ============================================================
   Generation demo — the core interactive section
   ============================================================ */

const SAMPLE_BRIEF_PLACEHOLDER =
  "e.g. 15s vertical ad for Instagram Reels, energetic vibe — written just like you'd ask Claude";

function UploadStep({ lead, onGenerate }) {
  const [preview, setPreview] = useState(null);
  const [fileName, setFileName] = useState(null);
  const [brief, setBrief] = useState("");
  const [dragOver, setDragOver] = useState(false);
  const inputRef = useRef(null);

  const loadFile = useCallback((file) => {
    if (!file || !file.type.startsWith("image/")) return;
    const reader = new FileReader();
    reader.onload = () => setPreview(reader.result);
    reader.readAsDataURL(file);
    setFileName(file.name);
  }, []);

  function useSample() {
    setPreview("assets/images/demo-input-product.webp");
    setFileName("sample-product-photo.webp");
  }

  function handleDrop(e) {
    e.preventDefault();
    setDragOver(false);
    loadFile(e.dataTransfer.files[0]);
  }

  return (
    <div className="demo-card">
      <div
        className="demo-upload"
        onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
        onDragLeave={() => setDragOver(false)}
        onDrop={handleDrop}
        style={dragOver ? { borderColor: "var(--border-accent)" } : undefined}
      >
        {preview ? (
          <img src={preview} alt="Your uploaded product" />
        ) : (
          <p className="is-body-sm">Drag a product photo here, or</p>
        )}
        <input
          ref={inputRef}
          type="file"
          accept="image/*"
          className="sr-only"
          onChange={(e) => loadFile(e.target.files[0])}
        />
        <div style={{ display: "flex", gap: "12px", justifyContent: "center", marginTop: "12px", flexWrap: "wrap" }}>
          <Button variant="outline" type="button" onClick={() => inputRef.current.click()}>
            {fileName ? "Choose a different photo" : "Choose a photo"}
          </Button>
          {!preview && (
            <Button variant="ghost" type="button" onClick={useSample}>
              Use a sample photo instead
            </Button>
          )}
        </div>
        <label className="sr-only" htmlFor="demo-brief">Brief</label>
        <textarea
          id="demo-brief"
          className="demo-brief"
          placeholder={SAMPLE_BRIEF_PLACEHOLDER}
          value={brief}
          onChange={(e) => setBrief(e.target.value)}
        />
      </div>
      <div>
        <h3 className="is-h5">Ready when you are, {lead.name.split(" ")[0] || "there"}.</h3>
        <p className="is-body">
          One free 9:16, ~15-second video — the exact job the connector runs when you ask Claude.
          Upload a photo (or use the sample) and add a one-line brief.
        </p>
        <Button
          variant="primary"
          className="btn-block"
          disabled={!preview}
          onClick={() => onGenerate({ preview, fileName, brief })}
        >
          Generate my video
        </Button>
      </div>
    </div>
  );
}

function GeneratingStep() {
  const [pct, setPct] = useState(4);
  useEffect(() => {
    const start = Date.now();
    const duration = 2600;
    const id = setInterval(() => {
      const elapsed = Date.now() - start;
      const next = Math.min(96, Math.round((elapsed / duration) * 100));
      setPct(next);
      if (elapsed >= duration) clearInterval(id);
    }, 80);
    return () => clearInterval(id);
  }, []);

  return (
    <div className="demo-card">
      <div className="demo-progress" style={{ gridColumn: "1 / -1" }}>
        <Eyebrow>generating your video</Eyebrow>
        <h3 className="is-h5">Cutting, scoring, and pacing your 15-second ad…</h3>
        <div className="progress-track">
          <div className="progress-fill" style={{ width: `${pct}%` }} />
        </div>
        <p className="is-body-sm">{pct}% — this usually takes under a minute</p>
      </div>
    </div>
  );
}

function ResultStep({ onRestart }) {
  const [toast, setToast] = useState({ msg: "", visible: false });

  function showToast(msg) {
    setToast({ msg, visible: true });
    setTimeout(() => setToast((t) => ({ ...t, visible: false })), 2400);
  }

  return (
    <div className="demo-card">
      <div className="demo-result">
        <video
          src="assets/videos/demo-result-generated.mp4"
          poster="assets/images/demo-result-poster.webp"
          controls
          preload="metadata"
        />
        <p className="is-body-sm" style={{ textAlign: "center", marginTop: "8px" }}>
          Prototype preview — sample output shown until live generation is wired up.
        </p>
        <div className="demo-result-actions">
          <Button variant="outline" onClick={() => showToast("Download would start here")}>
            Download
          </Button>
          <Button variant="ghost" onClick={() => showToast("Share link copied")}>
            Share
          </Button>
        </div>
      </div>
      <div>
        <Eyebrow>your video is ready</Eyebrow>
        <h3 className="is-h5">Like what you see?</h3>
        <p className="is-body">
          With the connector installed, Claude hands this back right in your chat — for your
          whole catalog, in more formats and styles.
        </p>
        <Button as="a" href="#signup" variant="primary" className="btn-block">
          Sign up for a free trial
        </Button>
        <Button variant="ghost" className="btn-block" onClick={onRestart}>
          Start over
        </Button>
      </div>
    </div>
  );
}

function GenerationDemo({ lead }) {
  const [stage, setStage] = useState("upload"); // upload | generating | result
  const [job, setJob] = useState(null);

  function handleGenerate(jobInput) {
    setJob(jobInput);
    setStage("generating");
    setTimeout(() => setStage("result"), 2700);
  }

  return (
    <section className="section" id="demo">
      <div className="container">
        <div className="section-head center">
          <Eyebrow>try it free</Eyebrow>
          <h2 className="is-h3">Your product. A real video. Zero cost.</h2>
          <p className="section-sub is-body">
            {lead
              ? "Upload your product photo below — this is the same generation Claude triggers through the connector."
              : "Fill in your details above to unlock your free generation."}
          </p>
        </div>

        {!lead && (
          <div className="demo-card" style={{ justifyItems: "center", textAlign: "center" }}>
            <div style={{ gridColumn: "1 / -1" }}>
              <p className="is-body">Add your name and email up top to get started.</p>
              <Button as="a" href="#top" variant="primary">
                Go to the sign-up form
              </Button>
            </div>
          </div>
        )}

        {lead && stage === "upload" && (
          <UploadStep lead={lead} onGenerate={handleGenerate} />
        )}
        {lead && stage === "generating" && <GeneratingStep />}
        {lead && stage === "result" && (
          <ResultStep onRestart={() => setStage("upload")} />
        )}
      </div>
    </section>
  );
}

/* ============================================================
   Proof carousel (ported from instantclips.ai — same clip library,
   reused here as a stopgap until InstantStudio-Claude-Connector-
   specific footage exists)
   ============================================================ */

const PROOF_CLIPS = [
  "1.mp4", "2.mp4", "3.mp4", "4.mp4", "5.mp4", "6.mp4", "7.mp4", "8.mp4",
  "9.mp4", "10.mp4", "11.mp4", "12.mp4", "13.mp4", "14.mp4", "15.mp4", "16.mp4",
  // Second batch, shuffled so same-client clips (originally sequential) aren't adjacent.
  "23.mp4", "27.mp4", "18.mp4", "24.mp4", "26.mp4", "17.mp4", "31.mp4",
  "28.mp4", "25.mp4", "32.mp4", "29.mp4", "22.mp4", "20.mp4", "30.mp4", "19.mp4",
  "21.mp4",
];
const PROOF_VIDEO_DIR = "assets/videos/proof/";

function useLazyPlayOnVisible(containerRef, { root = null, deps = [] } = {}) {
  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;
    const vids = Array.from(container.querySelectorAll("video[data-src]"));
    const load = (v) => { if (!v.src) v.src = v.dataset.src; };

    if (!("IntersectionObserver" in window)) {
      vids.forEach((v) => { load(v); v.play().catch(() => {}); });
      return;
    }

    const loader = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) { load(e.target); loader.unobserve(e.target); }
        });
      },
      { root, rootMargin: "200px 300px 200px 300px" }
    );
    const player = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          const v = e.target;
          if (e.isIntersecting) { load(v); v.play().catch(() => {}); }
          else v.pause();
        });
      },
      { root, rootMargin: "0px", threshold: 0.1 }
    );
    vids.forEach((v) => { loader.observe(v); player.observe(v); });
    return () => { loader.disconnect(); player.disconnect(); };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, deps);
}

function ProofClip({ file, onOpen, duplicate }) {
  const src = PROOF_VIDEO_DIR + file;
  return (
    <div
      className="proof-cell"
      role="button"
      tabIndex={duplicate ? -1 : 0}
      aria-hidden={duplicate || undefined}
      aria-label="Watch this clip full-screen"
      onClick={() => onOpen(src)}
      onKeyDown={(e) => {
        if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onOpen(src); }
      }}
    >
      <video data-src={src} muted loop playsInline preload="none" />
    </div>
  );
}

function VideoModal({ src, onClose }) {
  const videoRef = useRef(null);

  useEffect(() => {
    document.body.style.overflow = "hidden";
    const v = videoRef.current;
    if (v) {
      v.volume = 1;
      v.muted = false;
      v.play().catch(() => { v.muted = true; v.play().catch(() => {}); });
    }
    function onKey(e) { if (e.key === "Escape") onClose(); }
    window.addEventListener("keydown", onKey);
    return () => {
      document.body.style.overflow = "";
      window.removeEventListener("keydown", onKey);
    };
  }, [onClose]);

  return (
    <div
      className="video-modal"
      role="dialog"
      aria-modal="true"
      aria-label="Video player"
      onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
    >
      <button className="video-modal-close" aria-label="Close video dialog" onClick={onClose}>
        &times;
      </button>
      <video
        ref={videoRef}
        src={src}
        controls
        loop
        playsInline
        preload="auto"
        className="video-modal-player"
      />
    </div>
  );
}

function ClipsGallery({ onOpen, onClose }) {
  const gridRef = useRef(null);
  useLazyPlayOnVisible(gridRef, { deps: [] });

  useEffect(() => {
    document.body.style.overflow = "hidden";
    function onKey(e) { if (e.key === "Escape") onClose(); }
    window.addEventListener("keydown", onKey);
    return () => {
      document.body.style.overflow = "";
      window.removeEventListener("keydown", onKey);
    };
  }, [onClose]);

  return (
    <div className="clips-gallery" role="dialog" aria-modal="true" aria-labelledby="clips-gallery-title">
      <div className="clips-gallery-header">
        <div>
          <Eyebrow>made by instantstudio</Eyebrow>
          <h2 id="clips-gallery-title" className="is-h6">InstantStudio made every clip from an image with clear and simple verbal directions</h2>
        </div>
        <button className="clips-gallery-close" aria-label="Close gallery" onClick={onClose}>
          &times;
        </button>
      </div>
      <div className="clips-gallery-grid" ref={gridRef}>
        {PROOF_CLIPS.map((file) => (
          <button
            key={file}
            type="button"
            className="clips-gallery-item"
            aria-label="Watch this clip full-screen"
            onClick={() => onOpen(PROOF_VIDEO_DIR + file)}
          >
            <video data-src={PROOF_VIDEO_DIR + file} muted loop playsInline preload="none" />
            <span className="clips-gallery-play" aria-hidden="true">&#9654;</span>
          </button>
        ))}
      </div>
    </div>
  );
}

function ProofCarousel() {
  const trackRef = useRef(null);
  const [modalSrc, setModalSrc] = useState(null);
  const [galleryOpen, setGalleryOpen] = useState(false);

  useLazyPlayOnVisible(trackRef, { deps: [] });

  const animationDuration = `${PROOF_CLIPS.length * 2.5}s`;

  return (
    <section className="section proof-section" aria-labelledby="proof-heading">
      <div className="container">
        <div className="proof-head">
          <Eyebrow>made by instantstudio</Eyebrow>
          <h2 id="proof-heading" className="is-h3">Every clip below started as one product photo.</h2>
          <p className="section-sub is-body-sm">
            Tap any clip to watch it full-screen.{" "}
            <button type="button" className="proof-view-all" onClick={() => setGalleryOpen(true)}>
              View all
            </button>
          </p>
        </div>
      </div>

      <div className="proof-viewport">
        <div className="proof-fade proof-fade-left" aria-hidden="true" />
        <div className="proof-fade proof-fade-right" aria-hidden="true" />
        <div className="proof-track" ref={trackRef} style={{ animationDuration }}>
          {[0, 1].map((copy) =>
            PROOF_CLIPS.map((file) => (
              <ProofClip key={`${copy}-${file}`} file={file} onOpen={setModalSrc} duplicate={copy === 1} />
            ))
          )}
        </div>
      </div>

      {modalSrc && <VideoModal src={modalSrc} onClose={() => setModalSrc(null)} />}
      {galleryOpen && <ClipsGallery onOpen={setModalSrc} onClose={() => setGalleryOpen(false)} />}
    </section>
  );
}

/* ============================================================
   FAQ
   ============================================================ */

const FAQS = [
  {
    q: "How exactly does Claude connect to InstantStudio?",
    a: [
      'By means of a "Connector" — a piece of code written with the open MCP standard for linking tools to AI agents — and a corresponding "Skill" that tells Claude how to use InstantStudio\'s video generation. You describe the video in chat, next InstantStudio generates the clip and lets Claude know when it\'s ready.',
    ],
  },
  {
    q: "Do I need a Claude subscription?",
    a: [
      "For having it connected to InstantStudio and generating videos, yes. Note, however, that the trial account you receive is not limited to Claude only! You are welcome to use the free credits any way you like.",
    ],
  },
  {
    q: "What happens to my starting images?",
    a: [
      "InstantStudio temporarily stores the photos and other images you use as starting images for a video.",
      "By default, they will be automatically discarded 14 days later. Should you upgrade your subscription, you will have an option to keep the images for further use.",
      "Without your permission we will never share any of your source images with others nor use them to train our or others' AI models.",
    ],
  },
  {
    q: "How long does generation take?",
    a: ["Usually a couple minutes for a 15-second video."],
  },
  {
    q: "What do I get after using the free credits?",
    a: [
      "Downloadable, watermark-free clips or other media that you generated with them, plus the option to upgrade your InstantStudio plan.",
    ],
  },
  {
    q: "Is there a catch?",
    a: [
      'No credit card required. A limited number of free credits per business which you are free to use however you like on the platform.', 
      'No spamming, no aggressive sales tactics — fully transparent "opt-in" upgrade available when you need it.',
    ],
  },
];

function Faq() {
  const [openIndex, setOpenIndex] = useState(0);
  return (
    <section className="section" id="faq">
      <div className="container">
        <div className="section-head">
          <Eyebrow>faq</Eyebrow>
          <h2 className="is-h3">Questions, answered</h2>
        </div>
        <div className="faq-list">
          {FAQS.map((item, i) => (
            <div className={`faq-item${openIndex === i ? " open" : ""}`} key={item.q}>
              <button
                className="faq-question"
                aria-expanded={openIndex === i}
                onClick={() => setOpenIndex(openIndex === i ? -1 : i)}
              >
                {item.q}
                <span className="faq-icon" aria-hidden="true">+</span>
              </button>
              <div className="faq-answer">
                {item.a.map((para, j) => (
                  <p key={j}>{para}</p>
                ))}
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ============================================================
   Final CTA
   ============================================================ */

function CtaBanner() {
  return (
    <section className="section section-inverse cta-banner" id="signup">
      <div className="container">
        <h2 className="is-h3">Your next video is one easy chat away</h2>
        <p>Free, no credit card - get credits and use InstantStudio with Claude</p>
        <Button
          variant="primary"
          className="cta-banner-button"
          onClick={(e) => { e.preventDefault(); focusAndHighlightHeroForm(); }}
        >
          Try it now
        </Button>
      </div>
    </section>
  );
}

/* ============================================================
   Footer
   ============================================================ */

function Footer() {
  return (
    <footer className="site-footer">
      <div className="container footer-inner">
        <div>
          <a href="#top" className="logo">
            <img src="assets/logos/instant-studio-lockup.svg" alt="InstantStudio" className="logo-mark" />
            <span className="logo-sub">claude</span>
          </a>
          <p className="is-body-sm" style={{ marginTop: "8px", maxWidth: "320px" }}>
            InstantStudio's connector for making videos with Claude.
          </p>
        </div>
        <nav className="footer-nav" aria-label="Footer">
          <a href="#how-it-works">How it works</a>
          <a href="#demo">Try it free</a>
          <a href="#faq">FAQ</a>
        </nav>
        <p className="footer-copy">&copy; 2026 InstantStudio. All rights reserved.</p>
      </div>
    </footer>
  );
}

/* ============================================================
   Thank-you modal (shown right after lead-form submission)
   ============================================================ */

function ThankYouModal({ name, onClose }) {
  useEffect(() => {
    document.body.style.overflow = "hidden";
    function onKey(e) { if (e.key === "Escape") onClose(); }
    window.addEventListener("keydown", onKey);
    return () => {
      document.body.style.overflow = "";
      window.removeEventListener("keydown", onKey);
    };
  }, [onClose]);

  const firstName = name && name.split(" ")[0];

  return (
    <div
      className="thanks-modal"
      role="dialog"
      aria-modal="true"
      aria-labelledby="thanks-modal-title"
      onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
    >
      <div className="thanks-modal-card">
        <button className="thanks-modal-close" aria-label="Close" onClick={onClose}>
          &times;
        </button>
        <span className="thanks-modal-icon" aria-hidden="true">{"✓"}</span>
        <h2 id="thanks-modal-title" className="is-h4">
          Thank you{firstName ? `, ${firstName}` : ""}!
        </h2>
        <p className="is-body">
          We are on it and will email your InstantStudio invite once it's ready.
        </p>
        <Button variant="primary" className="btn-block" onClick={onClose}>
          Got it
        </Button>
      </div>
    </div>
  );
}

/* ============================================================
   App
   ============================================================ */

function App() {
  const [lead, setLead] = useState(null);
  const [showThanks, setShowThanks] = useState(false);

  function handleLeadCaptured(values) {
    postLeadToCrm(values);
    setLead(values);
    setShowThanks(true);
  }

  return (
    <React.Fragment>
      <Nav />
      <main id="main">
        <Hero onLeadCaptured={handleLeadCaptured} />
        <TrustedBy />
        <HowItWorks />
        <GenerationDemo lead={lead} />
        <ProofCarousel />
        <Faq />
        <CtaBanner />
      </main>
      <Footer />
      {showThanks && (
        <ThankYouModal name={lead && lead.name} onClose={() => setShowThanks(false)} />
      )}
    </React.Fragment>
  );
}

const root = ReactDOM.createRoot(document.getElementById("app"));
root.render(<App />);
