﻿// ============================================================
// Scroll reveal - IntersectionObserver wires up [data-reveal]
// ============================================================
function useScrollReveal() {
  useEffect(() => {
    const els = document.querySelectorAll("[data-reveal]");
    if (!("IntersectionObserver" in window)) {
      els.forEach(el => el.classList.add("in-view"));
      return;
    }
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add("in-view");
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12, rootMargin: "0px 0px -60px 0px" });
    els.forEach(el => io.observe(el));
    return () => io.disconnect();
  }, []);
}

/* global React, ReactDOM */
const { useState, useEffect, useRef } = React;

// ============================================================
// HERO MOCK - matches original onboarding form animation
// ============================================================
function HeroMock() {
  const fields = [
    { label: "Legal business name", value: "Hendricks Consulting LLC" },
    { label: "Primary contact email", value: "billing@hendricks.co" },
    { label: "Business address", value: "240 Oak St, Portland OR" },
    { label: "Tax questionnaire", value: "Submitted" },
  ];

  const [activeIdx, setActiveIdx] = useState(0);
  const [typedMap, setTypedMap] = useState({});
  const [completed, setCompleted] = useState([]);
  const [pressedIdx, setPressedIdx] = useState(-1);
  const [toast, setToast] = useState(null);

  useEffect(() => {
    let cancelled = false;
    const run = async () => {
      const wait = (ms) => new Promise(r => setTimeout(r, ms));
      while (!cancelled) {
        for (let i = 0; i < fields.length; i++) {
          if (cancelled) return;
          setActiveIdx(i);
          await wait(700);
          const target = fields[i].value;
          for (let c = 1; c <= target.length; c++) {
            if (cancelled) return;
            setTypedMap(prev => ({ ...prev, [i]: target.slice(0, c) }));
            await wait(45 + Math.random() * 35);
          }
          await wait(550);
          setPressedIdx(i);
          await wait(220);
          setPressedIdx(-1);
          await wait(120);
          setCompleted(prev => prev.includes(i) ? prev : [...prev, i]);
          setToast({ id: Date.now(), label: fields[i].label });
          await wait(1600);
          setToast(null);
          await wait(200);
        }
        await wait(1200);
        setCompleted([]);
        setTypedMap({});
      }
    };
    run();
    return () => { cancelled = true; };
  }, []);

  const doneCount = completed.length;
  const pct = Math.round((doneCount / fields.length) * 100);

  return (
    <div className="mock-frame">
      {toast && (
        <div className="mock-toast" key={toast.id}>
          <span className="mock-toast-dot"></span>
          <div>
            <strong>Field received</strong>
            <span>{toast.label}</span>
          </div>
        </div>
      )}
      <div className="mock-chrome">
        <span className="dot"></span>
        <span className="dot"></span>
        <span className="dot"></span>
      </div>
      <div className="mock-body">
        <aside className="mock-side">
          <div className="mock-side-h">
            <strong style={{ display: "block", fontFamily: "var(--sans)", fontSize: 13, color: "var(--ink)", letterSpacing: 0, textTransform: "none", marginBottom: 2 }}>Progress</strong>
            <span style={{ fontSize: 11, color: "var(--muted)", textTransform: "none", letterSpacing: 0 }}>Client Onboarding</span>
          </div>
          <div className="mock-side-section">Request</div>
          <div className="mock-side-active">
            <span>1. Onboarding</span>
            <em>{doneCount}/{fields.length}</em>
          </div>
          <ul className="mock-side-list">
            {fields.map((f, i) => {
              const isDone = completed.includes(i);
              const isActive = i === activeIdx && !isDone;
              return (
                <li key={i} className={(isDone ? "is-done " : "") + (isActive ? "is-active" : "")} style={{ transitionDelay: `${i * 40}ms` }}>
                  <span className="check"></span>
                  <span className="lbl">{f.label}</span>
                </li>
              );
            })}
          </ul>
        </aside>
        <div className="mock-main">
          <div className="mock-main-head">
            <h6>Business Details</h6>
            <span className="meta">{pct}%</span>
          </div>
          <div className="mock-progress"><i style={{ width: pct + "%" }}></i></div>

          <div className="mock-q-viewport">
            <div className="mock-q-track" style={{ transform: `translateY(calc((-1 * var(--card-h) - var(--card-gap)) * ${activeIdx}))` }}>
              {fields.map((f, i) => {
                const isActive = i === activeIdx;
                const isDone = completed.includes(i);
                const typed = typedMap[i] || "";
                return (
                  <div key={i} className={"mock-q-card " + (isActive ? "is-active" : "is-inactive")}>
                    <label className="mock-q-label">
                      {f.label} <em>*</em>
                    </label>
                    <div className="mock-input">
                      <span className="mock-typing">{typed}</span>
                      {isActive && !isDone && <span className="mock-caret"></span>}
                    </div>
                    <div className="mock-warn">
                      <i className="mock-warn-icon" aria-hidden="true"></i>
                      <span>Required to complete this request.</span>
                    </div>
                    <div className="mock-card-footer">
                      <span className="mock-link">Continue</span>
                      <span className={"mock-button " + (pressedIdx === i ? "is-pressed" : "")}>
                        Submit
                        {pressedIdx === i && <span className="mock-click-ring" aria-hidden="true"></span>}
                      </span>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// RUNTIME CONFIG (injected from Razor)
// ============================================================
const CONFIG = window.ClearBinderConfig || {};
const HOME_URL = CONFIG.homeUrl || "/";
const LOGIN_URL = CONFIG.loginUrl || "/Identity/Account/Login";
const PRIVACY_URL = CONFIG.privacyUrl || "/Home/Privacy";
const TERMS_URL = CONFIG.termsUrl || "/Home/Terms";
const DPA_URL = CONFIG.dpaUrl || "/Home/Dpa";
const REGISTER_URL_BASE = CONFIG.registerUrlBase || "/Identity/Account/Register";
const DEFAULT_PLAN_KEY = CONFIG.defaultPlanKey || "";
const DEFAULT_TRIAL_DAYS = Number(CONFIG.defaultTrialDays || 14);
const CONFIG_PLANS = Array.isArray(CONFIG.plans) ? CONFIG.plans : [];

function buildTrialUrl(planKey, mode = "monthly") {
  const url = new URL(REGISTER_URL_BASE, window.location.origin);
  if (planKey) {
    url.searchParams.set("plan", planKey);
  }
  url.searchParams.set("billingInterval", mode === "yearly" ? "Yearly" : "Monthly");
  return url.pathname + url.search;
}

async function scrollSectionToViewportCenter(hash) {
  if (!hash || !hash.startsWith("#")) return;
  const id = decodeURIComponent(hash.slice(1));
  if (!id) return;
  const target = document.getElementById(id);
  if (!target) return;

  window.history.replaceState(null, "", hash);

  // Wait for fonts to finish loading before we measure or scroll. The single
  // biggest cause of "smooth scroll lands on wrong section" on the very
  // first nav click after a hard reload is the font swap: Inter loads,
  // every block of text reflows, the target's true position shifts by
  // hundreds of pixels mid-animation, and the locked-in smooth scroll
  // destination is no longer where the target sits. Awaiting fonts.ready
  // takes ~0ms on subsequent clicks (already resolved) and a short delay
  // on the first click before everything else has loaded.
  if (document.fonts && document.fonts.ready) {
    try { await document.fonts.ready; } catch (_) { /* fall through */ }
  }

  // Capture the target's absolute top BEFORE we scroll so we can detect
  // whether it shifts during the smooth animation.
  const initialAbsoluteTop = window.scrollY + target.getBoundingClientRect().top;

  target.scrollIntoView({ behavior: "smooth", block: "center" });

  // If the target's absolute position shifts by more than 80px during the
  // smooth animation (image decoded above it, late React content mounted,
  // etc.) the user lands on the wrong section. Re-aim ONCE — smoothly —
  // toward the now-settled position. We cap this at one corrective re-aim
  // so the user never sees a bouncing back-and-forth motion. Skip the
  // re-aim if the user has scrolled manually in the meantime.
  let userScrolled = false;
  function markUserScrolled() { userScrolled = true; }
  window.addEventListener("wheel", markUserScrolled, { passive: true, once: true });
  window.addEventListener("touchstart", markUserScrolled, { passive: true, once: true });

  setTimeout(() => {
    if (userScrolled) return;
    const currentAbsoluteTop = window.scrollY + target.getBoundingClientRect().top;
    if (Math.abs(currentAbsoluteTop - initialAbsoluteTop) > 80) {
      target.scrollIntoView({ behavior: "smooth", block: "center" });
    }
  }, 700);
}

// ============================================================
// PRICING - monthly/yearly toggle
// ============================================================
const PLANS = CONFIG_PLANS;

function Pricing() {
  const [mode, setMode] = useState("monthly");
  const hasPlans = Array.isArray(PLANS) && PLANS.length > 0;
  const isSingle = hasPlans && PLANS.length === 1;
  return (
    <>
      <div className={"pricing-head" + (isSingle ? " pricing-head--centered" : "")}>
        <span className="eyebrow">Pricing</span>
        <h2 className="display display--lg">Choose the plan that fits your firm.</h2>
        <p className="pricing-meta">
          {hasPlans
            ? <>No credit card required <span style={{ margin: "0 6px" }}>·</span> Setup in under 2 minutes <span style={{ margin: "0 6px" }}>·</span> <a href="/compare">How we compare</a></>
            : <>No plans published yet. Configure plans from Admin Dashboard.</>}
        </p>
        <div className="pricing-switch" role="tablist" style={!hasPlans ? { opacity: 0.45, pointerEvents: "none" } : undefined}>
          <button
            className={mode === "monthly" ? "is-active" : ""}
            onClick={() => setMode("monthly")}
          >Monthly</button>
          <button
            className={mode === "yearly" ? "is-active" : ""}
            onClick={() => setMode("yearly")}
          >Yearly</button>
        </div>
      </div>
      <div className={"pricing-grid" + (PLANS.length === 1 ? " pricing-grid--single" : "")}>
        {!hasPlans && (
          <div className="plan">
            <div className="plan-name">Plans not configured</div>
            <p className="plan-blurb">Add at least one active plan in Admin before showing pricing.</p>
          </div>
        )}
        {PLANS.map(p => {
          const hasFeatures = Array.isArray(p.features) && p.features.length > 0;
          return (
            <div key={p.key} className={"plan " + (p.featured ? "is-featured" : "")}>
              <div className="plan-name">
                <span>{p.name}</span>
                {p.tag && <span className="plan-tag">{p.tag}</span>}
              </div>
              <div className="plan-price">
                <span className="cur">$</span>
                <span className="amt">{mode === "monthly" ? p.monthly : p.yearly}</span>
                <span className="plan-cadence">/{mode === "monthly" ? "month" : "month, billed yearly"}</span>
              </div>
              <p className="plan-blurb">{p.blurb}</p>
              {hasFeatures && (
                <ul className="plan-features">
                  {p.features.map((f, i) => <li key={i}>{f}</li>)}
                </ul>
              )}
              <div className="plan-footer">
                <a className="btn btn--primary" href={buildTrialUrl(p.key, mode)}>Start free trial <span className="arrow">→</span></a>
                <p className="plan-reassurance">Cancel anytime. No commitment.</p>
              </div>
            </div>
          );
        })}
      </div>
    </>
  );
}

// ============================================================
// INDUSTRIES - active pill
// ============================================================
function Industries() {
  const verticals = ["Accounting", "Bookkeeping", "Agencies", "Consulting", "Tax"];
  const useCases = [
    "Monthly reconciliation packets",
    "Client onboarding and entity setup",
    "Tax document collection",
    "Receipt and invoice capture",
    "Missing information follow-ups",
  ];
  const [active, setActive] = useState(0);
  return (
    <div className="industries-grid">
      <div className="industries-head">
        <span className="eyebrow">Built for accounting workflows</span>
        <h2 className="display display--lg">The same shape, every month.</h2>
        <p className="lede">Recurring document collection looks the same across most firms. Define it once, run it on every client.</p>
        <ul className="pill-row" role="tablist" aria-label="Verticals">
          {verticals.map((v, i) => (
            <li
              key={v}
              className={i === active ? "is-active" : ""}
              onClick={() => setActive(i)}
              role="tab"
            >{v}</li>
          ))}
        </ul>
        <ul className="usecase-list" aria-label="Use cases">
          {useCases.map((u, i) => <li key={i}>{u}</li>)}
        </ul>
      </div>
      <div className="flow" aria-hidden="true">
        <div className="flow-row is-active"><strong>Secure link sent</strong><span>Client opens checklist</span></div>
        <div className="flow-row"><strong>Files uploaded</strong><span>Answers submitted</span></div>
        <div className="flow-row"><strong>Review queue</strong><span>Approve or request update</span></div>
        <div className="flow-row"><strong>Completed request</strong><span>Tracked in one timeline</span></div>
      </div>
    </div>
  );
}

// ============================================================
// FAQ accordion - original texts
// ============================================================
function FAQ() {
  const qs = [
    { q: "Is there a free trial?", a: `Yes. ${DEFAULT_TRIAL_DAYS} days. No credit card required.` },
    { q: "Do my clients need an account?", a: "No. They open one secure link. No password, no signup. You control how access is handled per workflow." },
    { q: "Can I request files and answers in one place?", a: "Yes. Uploads, text fields, checklists, signatures, and structured form fields, all in one request." },
    { q: "Is this only for accountants?", a: "The product is optimised for accounting and bookkeeping workflows, but any team with structured document collection can use it." },
    { q: "What happens after the trial?", a: "You can continue on the paid plan you choose to keep using your active workflows and history. Or stop. No commitment." },
    { q: "Can I reuse templates?", a: "Yes. Save any request structure as a template and send it to the next client in seconds." },
    { q: "How is client data kept secure?", a: "Workflows run through controlled access links and tracked submission history, so collection stays structured and auditable." },
  ];
  const [open, setOpen] = useState(0);
  return (
    <div className="faq-grid">
      <div className="faq-copy">
        <span className="eyebrow">Common questions</span>
        <h2 className="display display--lg">Answers, not surprises.</h2>
      </div>
      <div className="faq-list">
        {qs.map((item, i) => (
          <div key={i} className={"faq-item " + (i === open ? "is-open" : "")}>
            <button className="faq-q" onClick={() => setOpen(i === open ? -1 : i)}>
              <span>{item.q}</span>
              <span className="plus" aria-hidden="true"></span>
            </button>
            <div className="faq-a"><div><p>{item.a}</p></div></div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ============================================================
// Tweaks
// ============================================================
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "displayFont": "Inter Tight",
  "heroVariant": "split"
}/*EDITMODE-END*/;

function TweakControls() {
  const [t, setTweak] = window.useTweaks(TWEAK_DEFAULTS);

  useEffect(() => {
    document.documentElement.style.setProperty("--serif",
      `"${t.displayFont}", Georgia, serif`
    );
    document.querySelectorAll(".hero-grid").forEach(el => {
      el.setAttribute("data-variant", t.heroVariant);
    });
  }, [t.displayFont, t.heroVariant]);

  const { TweaksPanel, TweakSection, TweakRadio } = window;

  return (
    <TweaksPanel title="Tweaks">
      <TweakSection title="Display font">
        <TweakRadio
          value={t.displayFont}
          onChange={v => setTweak("displayFont", v)}
          options={["Instrument Serif", "Newsreader", "Inter Tight"]}
        />
      </TweakSection>
      <TweakSection title="Hero layout">
        <TweakRadio
          value={t.heroVariant}
          onChange={v => setTweak("heroVariant", v)}
          options={[
            { label: "Split", value: "split" },
            { label: "Asym", value: "asym" },
            { label: "Stack", value: "stack" },
          ]}
        />
      </TweakSection>
    </TweaksPanel>
  );
}

// ============================================================
// Nav
// ============================================================
function Nav() {
  const [scrolled, setScrolled] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);
  const handleSectionLinkClick = (e) => {
    const hash = e.currentTarget.getAttribute("href");
    if (!hash || !hash.startsWith("#")) return;
    e.preventDefault();
    scrollSectionToViewportCenter(hash);
    setMenuOpen(false);
  };

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 8);
    const onResize = () => {
      if (window.innerWidth > 900) {
        setMenuOpen(false);
      }
    };

    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onResize);
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onResize);
    };
  }, []);

  useEffect(() => {
    if (!menuOpen) return;
    const onKeyDown = (event) => {
      if (event.key === "Escape") {
        setMenuOpen(false);
      }
    };
    window.addEventListener("keydown", onKeyDown);
    return () => window.removeEventListener("keydown", onKeyDown);
  }, [menuOpen]);

  return (
    <nav className={"nav " + (scrolled ? "is-scrolled" : "")}>
      <div className="shell nav-inner">
        <a className="brand" href={HOME_URL}>
          <img className="brand-mark" src="/redesign/logo.png" alt="" aria-hidden="true" width="459" height="444" decoding="async" />
          <span className="brand-word">
            <span className="brand-word__clear">Clear</span><span className="brand-word__binder">Binder</span>
          </span>
        </a>

        <button
          type="button"
          className={"nav-toggle " + (menuOpen ? "is-open" : "")}
          aria-label={menuOpen ? "Close navigation menu" : "Open navigation menu"}
          aria-controls="siteNavMenu"
          aria-expanded={menuOpen ? "true" : "false"}
          onClick={() => setMenuOpen((prev) => !prev)}
        >
          <span></span>
          <span></span>
          <span></span>
        </button>

        <div id="siteNavMenu" className={"nav-collapse " + (menuOpen ? "is-open" : "")}>
          <ul className="nav-links">
            <li><a href="#features" onClick={handleSectionLinkClick}>Features</a></li>
            <li><a href="#how-it-works" onClick={handleSectionLinkClick}>How it works</a></li>
            <li><a href="#pricing" onClick={handleSectionLinkClick}>Pricing</a></li>
            <li><a href="#faq" onClick={handleSectionLinkClick}>FAQ</a></li>
          </ul>
          <div className="nav-actions">
            <a className="login" href={LOGIN_URL}>Login</a>
            <a className="btn btn--primary" href={buildTrialUrl(DEFAULT_PLAN_KEY, "monthly")}>Start free trial</a>
          </div>
        </div>
      </div>
    </nav>
  );
}

function ShotFrame({ imageSrc, label, alt, width, height, onOpen }) {
  const [imageFailed, setImageFailed] = useState(false);
  const showImage = !!imageSrc && !imageFailed;
  const resolvedAlt = alt || label;

  return (
    <div className={"shot " + (showImage ? "has-image" : "")}>
      <div className="shot-chrome">
        <span className="dot"></span><span className="dot"></span><span className="dot"></span>
      </div>
      {showImage ? (
        <button
          type="button"
          className="shot-image-button"
          onClick={() => onOpen && onOpen({ src: imageSrc, alt: resolvedAlt })}
          aria-label={"Expand preview: " + resolvedAlt}
        >
          <img
            className="shot-image"
            src={imageSrc}
            alt={resolvedAlt}
            width={width}
            height={height}
            loading="lazy"
            decoding="async"
            onError={() => setImageFailed(true)}
          />
          <span className="shot-expand-icon" aria-hidden="true">
            <svg viewBox="0 0 24 24" focusable="false">
              <path d="M14 4h6v6M20 4l-8 8M10 20H4v-6M4 20l8-8" />
            </svg>
          </span>
        </button>
      ) : (
        <span className="shot-label">{label}</span>
      )}
    </div>
  );
}

function ShotLightbox({ preview, onClose }) {
  useEffect(() => {
    if (!preview) return;

    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";

    const handleKeyDown = (event) => {
      if (event.key === "Escape") {
        onClose();
      }
    };

    window.addEventListener("keydown", handleKeyDown);
    return () => {
      window.removeEventListener("keydown", handleKeyDown);
      document.body.style.overflow = previousOverflow;
    };
  }, [preview, onClose]);

  if (!preview) return null;

  return (
    <div
      className="shot-lightbox"
      role="dialog"
      aria-modal="true"
      aria-label="Expanded screenshot preview"
      onClick={onClose}
    >
      <button
        type="button"
        className="shot-lightbox-close"
        aria-label="Close preview"
        onClick={onClose}
      >
        ×
      </button>
      <div className="shot-lightbox-frame" onClick={(event) => event.stopPropagation()}>
        <img
          className="shot-lightbox-image"
          src={preview.src}
          alt={preview.alt}
          loading="eager"
        />
      </div>
    </div>
  );
}

// ============================================================
// MAIN APP - original copy from IndexV2
// ============================================================
function App() {
  useScrollReveal();
  const [preview, setPreview] = useState(null);
  const handleSectionLinkClick = (e) => {
    const hash = e.currentTarget.getAttribute("href");
    if (!hash || !hash.startsWith("#")) return;
    e.preventDefault();
    scrollSectionToViewportCenter(hash);
  };

  return (
    <>
      <Nav />

      {/* 1. HERO */}
      <header className="hero" data-screen-label="01 Hero">
        <div className="shell">
          <div className="hero-grid" data-variant="split">
            <div className="hero-copy" data-reveal="left">
              <span className="eyebrow">For accountants and bookkeepers</span>
              <h1 className="display display--hero hero-headline">
                Stop chasing clients for documents.
              </h1>
              <p className="lede">
                Send one link. Get everything back. The chase becomes a checklist.
              </p>
              <div className="hero-actions">
                <a className="btn btn--primary" href={buildTrialUrl(DEFAULT_PLAN_KEY, "monthly")}>Start free trial</a>
                <a className="btn btn--ghost" href="#how-it-works" onClick={handleSectionLinkClick}>See how it works <span className="arrow">→</span></a>
              </div>
              <ul className="hero-trust" aria-label="Trial details">
                <li>{DEFAULT_TRIAL_DAYS}-day free trial</li>
                <li>No credit card</li>
                <li>2-minute setup</li>
              </ul>
            </div>
            <div className="hero-visual" aria-hidden="true" data-reveal="right" style={{ "--reveal-delay": "120ms" }}>
              <HeroMock />
            </div>
          </div>
        </div>
      </header>

      {/* 2. AUDIENCE */}
      <section className="audience" data-screen-label="02 Audience">
        <div className="shell">
          <div className="audience-grid">
            <div data-reveal>
              <span className="eyebrow">Who this is for</span>
              <h2 className="display display--lg" style={{ marginTop: 16 }}>Anyone still chasing clients every month for the same documents.</h2>
            </div>
            <ul className="role-row" aria-label="Roles" data-reveal style={{ "--reveal-delay": "120ms" }}>
              <li>Accountants</li>
              <li>Bookkeepers</li>
              <li className="accent">Small firms</li>
              <li>Tax preparers</li>
              <li>Audit teams</li>
            </ul>
          </div>
        </div>
      </section>

      {/* 3. PROBLEM */}
      <section className="section" id="problem" data-screen-label="03 Problem">
        <div className="shell">
          <div className="problem-grid">
            <div className="problem-head" data-reveal>
              <span className="eyebrow">The problem</span>
              <h2 className="display display--xl">Email is where document collection breaks.</h2>
              <p className="lede">It works for messages. It fails for repeatable collection and follow-up. Built to replace email threads and shared folders.</p>
            </div>
            <ul className="pain-list" aria-label="Pain points" data-reveal="right" style={{ "--reveal-delay": "120ms" }}>
              <li><span className="num">01</span><span className="pain">Files get buried in long threads.</span></li>
              <li><span className="num">02</span><span className="pain">Clients send the wrong items.</span></li>
              <li><span className="num">03</span><span className="pain">Missing documents are discovered too late.</span></li>
              <li><span className="num">04</span><span className="pain">Nobody has a clear view of progress.</span></li>
            </ul>
          </div>
        </div>
      </section>

      {/* 4. STATEMENT */}
      <section className="section statement" data-screen-label="04 Statement">
        <div className="shell statement-inner" data-reveal>
          <span className="eyebrow">Why not email or folders</span>
          <h2 className="display display--xl statement-lines">
            <span>Drive stores files.</span>
            <span>Email sends messages.</span>
            <span className="emph">Neither runs the collection.</span>
          </h2>
          <p className="statement-sub">No view of what is missing. No reminders. No clean review flow. The chase stays manual.</p>
        </div>
      </section>

      {/* 5. PRODUCT PREVIEW */}
      <section className="section" data-screen-label="05 Product preview">
        <div className="shell">
          <div className="preview-head" data-reveal>
            <span className="eyebrow">Product preview</span>
            <h2 className="display display--xl">See the workflow before you send it.</h2>
            <p className="lede">Create the request, send one secure link, track what is missing. Without digging through email.</p>
          </div>
          <div className="preview-stack">
            <article className="preview-row">
              <div className="preview-text">
                <span className="step">Step 01</span>
                <h3>Build the request</h3>
                <p>Pick a template or use the wizard. Combine files, text fields, signatures, and structured questions in one request.</p>
              </div>
              <ShotFrame
                imageSrc="/redesign/images/builder.png"
                label="REQUEST BUILDER · WIZARD"
                alt="ClearBinder request builder for accountants — add file uploads, structured fields, signatures, and questions to a single client document request"
                width={1619}
                height={799}
                onOpen={(payload) => setPreview(payload)}
              />
            </article>
            <article className="preview-row reverse">
              <div className="preview-text">
                <span className="step">Step 02</span>
                <h3>Client opens one secure link</h3>
                <p>Your client opens the link on whatever device is to hand. They see a clear checklist of exactly what's needed and where to put it.</p>
              </div>
              <ShotFrame
                imageSrc="/redesign/images/client-checklist.png"
                label="CLIENT CHECKLIST VIEW"
                alt="Client-facing ClearBinder checklist showing pending uploads and completed items, opened from a magic link with no account or password required"
                width={1079}
                height={644}
                onOpen={(payload) => setPreview(payload)}
              />
            </article>
            <article className="preview-row">
              <div className="preview-text">
                <span className="step">Step 03</span>
                <h3>Track and review</h3>
                <p>See what's outstanding at a glance. Approve submissions or request changes without losing context. Reminders chase the gaps automatically.</p>
              </div>
              <ShotFrame
                imageSrc="/redesign/images/review-queue.png"
                label="DASHBOARD · REVIEW QUEUE"
                alt="ClearBinder accountant dashboard review queue listing outstanding client document submissions with status badges and inline approve or request-changes actions"
                width={1230}
                height={589}
                onOpen={(payload) => setPreview(payload)}
              />
            </article>
          </div>
        </div>
      </section>

      {/* 6. HOW IT WORKS */}
      <section className="section section--tight" id="how-it-works" data-screen-label="06 How it works">
        <div className="shell">
          <div className="timeline-head" data-reveal>
            <span className="eyebrow">How it works</span>
            <h2 className="display display--lg">Four steps, one link, every document.</h2>
          </div>
          <ol className="timeline">
            <li>
              <span className="num">01</span>
              <h4>Create the request</h4>
              <p>Pick a template or use the wizard to ask for exactly what you need.</p>
            </li>
            <li>
              <span className="num">02</span>
              <h4>Send one secure link</h4>
              <p>Your client opens one magic link, no account required.</p>
            </li>
            <li>
              <span className="num">03</span>
              <h4>Client completes the checklist</h4>
              <p>Clients upload files, answer questions, and see what is still missing.</p>
            </li>
            <li>
              <span className="num">04</span>
              <h4>Review and request updates</h4>
              <p>Approve submissions or ask for changes without losing context.</p>
            </li>
          </ol>
        </div>
      </section>

      {/* 7. FEATURES */}
      <section className="section" id="features" data-screen-label="07 Features">
        <div className="shell">
          <div className="features-grid">
            <div className="features-head" data-reveal>
              <span className="eyebrow">Features</span>
              <h2 className="display display--lg">Everything you need to stop chasing.</h2>
            </div>
            <ul className="features-list" data-reveal="right" style={{ "--reveal-delay": "120ms" }}>
              <li>Send structured requests instead of messy emails.</li>
              <li>Clients know exactly what to provide.</li>
              <li>See missing items instantly.</li>
              <li>Files and answers, all in one place.</li>
              <li>Reuse templates for recurring requests.</li>
              <li>Track activity history for review and accountability.</li>
              <li>Automatic reminders until the request is complete.</li>
              <li>Approve or request updates inline.</li>
            </ul>
          </div>
        </div>
      </section>

      {/* 8. PRICING */}
      <section className="section pricing-bg" id="pricing" data-screen-label="08 Pricing">
        <div className="shell">
          <Pricing />
        </div>
      </section>

      {/* 9. BEFORE / AFTER */}
      <section className="section" data-screen-label="09 Before / after">
        <div className="shell">
          <div className="compare-head" data-reveal>
            <span className="eyebrow">Before vs after</span>
            <h2 className="display display--lg">From chasing to controlled collection.</h2>
          </div>
          <div className="compare" data-reveal="scale" style={{ "--reveal-delay": "100ms" }}>
            <div className="compare-col before">
              <h4>Before</h4>
              <ul>
                <li>Email threads everywhere.</li>
                <li>Manual follow-ups.</li>
                <li>Missing documents at deadline.</li>
                <li>Unclear request status.</li>
              </ul>
            </div>
            <div className="compare-col after">
              <h4>After</h4>
              <ul>
                <li>One request link per client.</li>
                <li>Automatic reminders.</li>
                <li>Clear missing/completed tracking.</li>
                <li>Review everything in one place.</li>
              </ul>
            </div>
          </div>
        </div>
      </section>

      {/* 10. INDUSTRIES */}
      <section className="section" data-screen-label="10 Industries">
        <div className="shell">
          <Industries />
        </div>
      </section>

      {/* 11. TRUST */}
      <section className="section pricing-bg" data-screen-label="11 Trust">
        <div className="shell">
          <div className="trust-grid">
            <div className="trust-head" data-reveal>
              <span className="eyebrow">Trust and security</span>
              <h2 className="display display--lg">Built for sensitive client workflows.</h2>
              <p className="lede">Designed for the kind of accounting work where audit trail and access control are not optional.</p>
            </div>
            <ul className="trust-points" data-reveal="right" style={{ "--reveal-delay": "120ms" }}>
              <li>
                <span className="ico"></span>
                <div>
                  <strong>Secure client links.</strong>
                  <p>Tokenised, scoped per request. No shared passwords.</p>
                </div>
              </li>
              <li>
                <span className="ico"></span>
                <div>
                  <strong>No file sharing over email.</strong>
                  <p>Everything stays in one controlled workflow.</p>
                </div>
              </li>
              <li>
                <span className="ico"></span>
                <div>
                  <strong>Access-controlled portal.</strong>
                  <p>You decide who sees what, when.</p>
                </div>
              </li>
              <li>
                <span className="ico"></span>
                <div>
                  <strong>Audit-friendly history.</strong>
                  <p>Every action timestamped, every change tracked.</p>
                </div>
              </li>
              <li>
                <span className="ico"></span>
                <div>
                  <strong>Designed for accounting.</strong>
                  <p>Built around how firms actually close periods.</p>
                </div>
              </li>
            </ul>
          </div>
        </div>
      </section>

      {/* 13. FAQ */}
      <section className="section" id="faq" data-screen-label="12 FAQ">
        <div className="shell">
          <FAQ />
        </div>
      </section>

      {/* 14. FINAL CTA */}
      <section className="section final" data-screen-label="13 Final CTA">
        <div className="shell final-inner" data-reveal>
          <h2 className="display display--hero">Ready to stop chasing clients?</h2>
          <a className="btn btn--light" href={buildTrialUrl(DEFAULT_PLAN_KEY, "monthly")}>Start free trial</a>
          <p className="fine">{DEFAULT_TRIAL_DAYS}-day free trial. No credit card.</p>
        </div>
      </section>

      {/* Footer lives in the shared _RedesignFooter.cshtml partial, rendered
          by IndexV2.cshtml AFTER this React mount. Same markup powers the
          legal pages via _RedesignLayout.cshtml — one source of truth, no
          drift between homepage and legal chrome. */}

      <TweakControls />
      <ShotLightbox preview={preview} onClose={() => setPreview(null)} />
    </>
  );
}

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


