// CaseStudy.jsx — Conversion Works case study: Subscription & Purchase Growth via A/B Testing
// Faithful rebrand of the Taurist case study into the Conversion Works system.
// Features: tabbed hero metrics, scroll-spy table of contents (sticky desktop rail
// + mobile dropdown), image-slots for user-supplied imagery, mobile sticky CTA
// dropdown, and an "other case studies" carousel.

const LANDING = "/conversion";

// ---- data ---------------------------------------------------------------
const SECTIONS = [
  { id: "client",         n: "Client & Context",          num: "01" },
  { id: "challenge",      n: "Challenge & Goals",         num: "02" },
  { id: "discovery",      n: "Discovery",                 num: "03" },
  { id: "solution",       n: "Solutions",                 num: "04" },
  { id: "implementation", n: "Implementation & Dev",      num: "05" },
  { id: "results",        n: "Results & Impact",          num: "06" },
  { id: "testimonial",    n: "Testimonials",              num: null },
];

const TABS = {
  "Results": [
    { v: "+26.41%", l: "PDP mobile conversion lift", up: true },
    { v: "+15.43%", l: "Cart subscription lift", up: true },
    { v: "+27.56%", l: "Collection subscription lift", up: true },
    { v: "$50M+", l: "Online sales reached", up: true },
  ],
  "Program": [
    { v: "2yr+", l: "Experimentation program", up: false },
    { v: "63", l: "Tests launched", up: true },
    { v: "42", l: "Winning tests", up: true },
    { v: "67%", l: "Win rate", up: true },
  ],
  "Featured Tests": [
    { v: "+26.41%", l: "PDP social proof (mobile)", up: true },
    { v: "+15.43%", l: "Cart subscription toggle", up: true },
    { v: "+27.56%", l: "Collection top fold", up: true },
    { v: "97%+", l: "Avg. test confidence", up: true },
  ],
};

const TESTS = [
  {
    badge: "Test 01",
    title: "Cart Drawer — Add Subscription Toggle (one-time → subscribe)",
    spec: [
      ["Problem", "Shoppers typically added one-time products to cart; switching to a subscription required extra steps and low-visibility messaging."],
      ["Hypothesis", "A clear subscription toggle inside the cart drawer will surface savings and make switching frictionless, increasing subscription conversion."],
      ["Primary KPI", "Subscription conversion rate."],
      ["Goal", "Increase the share of orders placed as subscriptions."],
      ["Guardrails", "Overall conversion rate, cart abandon, page performance."],
      ["Split", "50/50; ~17,231 visitors (control) vs ~17,194 (variant)."],
    ],
    result: ["+15.43% subscription conversion", "99.58% confidence", "Win"],
    note: "Kept users in-flow; messaging emphasized savings and flexibility.",
    before: "t1-before", after: "t1-after",
    beforeSrc: "assets/cs-t1-before.avif", afterSrc: "assets/cs-t1-after.avif",
    ratio: "545 / 1244",
    cap: "This cart-drawer change lifted subscription conversion by +15.43% at 99.58% confidence.",
  },
  {
    badge: "Test 02",
    title: "PDP (Mobile) — Add Testimonial Video Bubbles Above Image Gallery",
    spec: [
      ["Problem", "On mobile, users reached the gallery before seeing credible human proof, leading to hesitation."],
      ["Hypothesis", "Placing authentic video testimonials above the gallery will build trust faster and lift conversion."],
      ["Primary KPI", "Overall conversion rate."],
      ["Goal", "Increase mobile conversion by reducing early hesitation."],
      ["Guardrails", "Scroll engagement, performance, bounce."],
      ["Split", "50/50; ~14,834 visitors (control) vs ~14,929 (variant)."],
    ],
    result: ["+26.41% conversion", "99.73% confidence", "Win"],
    note: "Created a stronger emotional connection before product details.",
    before: "t2-before", after: "t2-after",
    beforeSrc: "assets/cs-t2-before.avif", afterSrc: "assets/cs-t2-after.avif",
    ratio: "541 / 1178",
    cap: "Adding testimonial videos above the mobile PDP gallery lifted conversion by +26.41% at 99.73% confidence.",
  },
  {
    badge: "Test 03",
    title: "Collection Page — Redesign the Top Fold (quiz + subs toggle + filters)",
    spec: [
      ["Problem", "The collection top fold didn't clearly guide users or communicate subscription savings. The client was sending traffic directly to this page."],
      ["Hypothesis", "A more informative, interactive top fold (value callouts, quiz/product finder, subscription pricing toggle, stronger filters) will improve engagement and subscription adoption."],
      ["Primary KPI", "Subscription conversion rate (collection visitors)."],
      ["Goal", "Increase subscription selection while improving browse efficiency."],
      ["Guardrails", "Overall CVR, exit rate, performance."],
      ["Split", "50/50; ~6,987 visitors (control) vs ~7,096 (variant)."],
    ],
    result: ["+27.56% subscription conversion", "97.28% confidence", "Win"],
    note: "Highlighted value, simplified discovery, and reduced pogo-sticking.",
    before: "t3-before", after: "t3-after",
    beforeSrc: "assets/cs-t3-before.avif", afterSrc: "assets/cs-t3-after.avif",
    ratio: "546 / 1185",
    cap: "Redesigning the collection top fold lifted subscription conversion by +27.56% at 97.28% confidence.",
  },
];

const OTHER = [
  { id: "other-annabella", name: "Annabella", img: "assets/cases/annabella.avif", href: "/conversion/case-study/dtc-baby-brand", desc: "Audit-led Shopify rebuild that doubled conversion in 60 days across PDP, cart, and checkout.", m: [["+113% conversion-rate increase", true], ["+234% add-to-cart increase", true]] },
  { id: "other-omnilux", name: "Omnilux", img: "assets/cases/omnilux.avif", desc: "High-ticket DTC proof moved closer to the buying decision across nav, PDP, and homepage.", m: [["+58% CVR lift — reviews in nav", true], ["+35% CVR lift — PDP testimonial video", true]] },
  { id: "other-juvenon", name: "Juvenon", img: "assets/cases/juvenon.avif", desc: "PDP purchase options made easier to act on, with a featured win measured to confidence.", m: [["+35.24% CVR lift — featured PDP win", true], ["99.18% statistical confidence", false]] },
  { id: "other-wigdealer", name: "WigDealer", img: "assets/cases/wigdealer.avif", desc: "Cart, collection, and PDP friction reduced across the funnel for compounding gains.", m: [["+10.74% RPV lift — cart simplification", true], ["+7.77% CVR lift — collection top-fold", true]] },
];

// ---- scroll-spy hook ----------------------------------------------------
function useScrollSpy(ids, offset = 130) {
  const [active, setActive] = useState(null);
  useEffect(() => {
    const onScroll = () => {
      let cur = null;
      for (const id of ids) {
        const el = document.getElementById(id);
        if (el && el.getBoundingClientRect().top <= offset) cur = id;
      }
      setActive(cur);
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return active;
}

// ---- shared atoms -------------------------------------------------------
function Slot({ id, placeholder, radius = 12, style, src }) {
  return React.createElement("image-slot", { id, placeholder, radius: String(radius), style, src: src ? assetUrl(src) : undefined });
}
function Stars({ n = 5, size = 13 }) {
  return <span className="csx-quote-stars" style={{ fontSize: size }}>{Array.from({ length: n }).map((_, i) => <i key={i} className="ri-star-fill" />)}</span>;
}

// ---- nav ----------------------------------------------------------------
function CaseNav() {
  const [scrolled, setScrolled] = useState(false);
  const [openIdx, setOpenIdx] = useState(-1);
  const [menuOpen, setMenuOpen] = useState(false);
  const [mCasesOpen, setMCasesOpen] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 24);
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  useEffect(() => {
    document.body.style.overflow = menuOpen ? "hidden" : "";
    document.body.classList.toggle("nav-menu-open", menuOpen);
    return () => { document.body.style.overflow = ""; document.body.classList.remove("nav-menu-open"); };
  }, [menuOpen]);
  const links = [
    { label: "The Audit", href: LANDING + "#convert" },
    { label: "Case Studies", href: LANDING + "#showcase", dropdown: [
      { label: "Her Fantasy Box", href: "#top", sub: "Subscription & purchase growth" },
      { label: "Annabella", href: "/conversion/case-study/dtc-baby-brand", sub: "Audit-led Shopify rebuild" },
    ] },
    { label: "How it works", href: LANDING + "#how" },
    { label: "FAQs", href: LANDING + "#faq" },
  ];
  const lstyle = { fontFamily: "var(--font-ui)", fontSize: 14, fontWeight: 500, color: "var(--fg2)", textDecoration: "none", transition: "color .15s" };
  return (
    <React.Fragment>
    <nav style={{
      position: "fixed", top: 0, left: 0, right: 0, zIndex: 50,
      transition: "background .3s, border-color .3s, backdrop-filter .3s",
      background: scrolled ? "rgba(2,3,13,0.74)" : "rgba(2,3,13,0.4)",
      backdropFilter: "blur(16px)", WebkitBackdropFilter: "blur(16px)",
      borderBottom: `1px solid ${scrolled ? "var(--border-subtle)" : "transparent"}`,
    }}>
      <div className="wrap" style={{ display: "flex", alignItems: "center", justifyContent: "space-between", height: 74 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <a href={LANDING} aria-label="Conversion Works home" style={{ display: "inline-flex", alignItems: "center", textDecoration: "none" }}>
            <Logo height={42} />
          </a>
          <a href="https://www.taurist.com/" className="nav-byline" style={{ fontFamily: "var(--font-ui)", fontSize: 11, fontWeight: 600, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--fg3)", paddingLeft: 12, borderLeft: "1px solid var(--border-default)", textDecoration: "none" }}>by Taurist</a>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 34 }} className="nav-links">
          {links.map((l, i) => {
            if (!l.dropdown) {
              return (
                <a key={l.label} href={l.href} style={lstyle}
                  onMouseEnter={(e) => (e.currentTarget.style.color = "var(--fg1)")}
                  onMouseLeave={(e) => (e.currentTarget.style.color = "var(--fg2)")}
                >{l.label}</a>
              );
            }
            const open = openIdx === i;
            return (
              <div key={l.label} style={{ position: "relative" }}
                onMouseEnter={() => setOpenIdx(i)} onMouseLeave={() => setOpenIdx(-1)}>
                <a href={l.href} style={{ ...lstyle, display: "inline-flex", alignItems: "center", gap: 5, color: open ? "var(--fg1)" : "var(--fg2)" }}>
                  {l.label}
                  <i className="ri-arrow-down-s-line" style={{ fontSize: 16, transition: "transform .2s", transform: open ? "rotate(180deg)" : "none" }} />
                </a>
                <div style={{ position: "absolute", top: "100%", left: -8, paddingTop: 14, opacity: open ? 1 : 0, transform: open ? "translateY(0)" : "translateY(-6px)", pointerEvents: open ? "auto" : "none", transition: "opacity .18s, transform .18s" }}>
                  <div style={{ minWidth: 248, padding: 7, borderRadius: 14, background: "rgba(11,16,32,0.96)", border: "1px solid var(--border-default)", backdropFilter: "blur(16px)", WebkitBackdropFilter: "blur(16px)", boxShadow: "0 18px 44px rgba(0,0,0,0.5)" }}>
                    {l.dropdown.map((d) => (
                      <a key={d.label} href={d.href} style={{ display: "block", padding: "10px 13px", borderRadius: 9, textDecoration: "none", transition: "background .15s" }}
                        onMouseEnter={(e) => (e.currentTarget.style.background = "rgba(255,255,255,0.05)")}
                        onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")}>
                        <span style={{ display: "block", fontFamily: "var(--font-ui)", fontSize: 14, fontWeight: 600, color: "var(--fg1)" }}>{d.label}</span>
                        <span style={{ display: "block", fontFamily: "var(--font-body)", fontWeight: 300, fontSize: 12.5, color: "var(--fg3)", marginTop: 2 }}>{d.sub}</span>
                      </a>
                    ))}
                  </div>
                </div>
              </div>
            );
          })}
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 12 }} className="nav-cta-group">
          <a href={LANDING + "#cta"} className="btn btn-primary btn-sm nav-primary-cta">Get 5 free fixes</a>
          <button type="button" className="nav-burger" aria-label="Open menu" onClick={() => setMenuOpen(true)}><i className="ri-menu-line" /></button>
        </div>
      </div>
    </nav>
    {menuOpen && (
      <div className="nav-mobile-menu">
        <div className="nmm-head">
          <div className="nmm-id">
            <a href={LANDING} aria-label="Conversion Works home" style={{ display: "inline-flex" }}>
              <Logo height={42} />
            </a>
            <a href="https://www.taurist.com/" className="nmm-byline" onClick={() => setMenuOpen(false)}>by Taurist</a>
          </div>
          <button type="button" className="nmm-close" aria-label="Close menu" onClick={() => setMenuOpen(false)}><i className="ri-close-line" /></button>
        </div>
        <nav className="nmm-links">
          {links.map((l) => l.dropdown ? (
            <div key={l.label} className="nmm-group">
              <button type="button" className="nmm-link nmm-link--btn" aria-expanded={mCasesOpen} onClick={() => setMCasesOpen((o) => !o)}>
                {l.label}
                <i className="ri-arrow-down-s-line" style={{ transition: "transform .2s", transform: mCasesOpen ? "rotate(180deg)" : "none" }} />
              </button>
              <div className={"nmm-cases-sub" + (mCasesOpen ? " open" : "")}>
                {l.dropdown.map((d) => (
                  <a key={d.label} href={d.href} className="nmm-sublink" onClick={() => setMenuOpen(false)}>
                    <b>{d.label}</b>{d.sub}
                  </a>
                ))}
              </div>
            </div>
          ) : (
            <a key={l.label} href={l.href} className="nmm-link" onClick={() => setMenuOpen(false)}>{l.label}</a>
          ))}
          <a href={LANDING + "#cta"} className="btn btn-primary nmm-cta" onClick={() => setMenuOpen(false)}>Get 5 free fixes</a>
        </nav>
        <div className="nmm-foot">
          <a href="https://www.taurist.com/" target="_blank" rel="noopener noreferrer">taurist</a>
          <span>|</span>
          <a href="https://www.taurist.com/siteworks" target="_blank" rel="noopener noreferrer">siteworks</a>
          <span>|</span>
          <a href="https://www.taurist.com/workers" target="_blank" rel="noopener noreferrer">workers</a>
        </div>
      </div>
    )}
    </React.Fragment>
  );
}

// ---- hero ---------------------------------------------------------------
function Hero() {
  const [tab, setTab] = useState("Results");
  return (
    <header className="csx-hero">
      <div className="haze-bloom" aria-hidden="true" />
      <div className="csx-wrap">
        <div className="csx-crumb">
          <a href={LANDING + "#showcase"}>Case Studies</a>
          <i className="ri-arrow-right-s-line" />
          <span className="csx-crumb-cur">Subscription &amp; Purchase Growth</span>
        </div>
        <div className="csx-hero-grid">
          <div className="csx-hero-text" style={{ position: "relative" }}>
            <span className="csx-hero-ghost" aria-hidden="true">Her Fantasy Box</span>
            <div className="eyebrow csx-hero-eyebrow"><span className="dot" />CRO Audit · A/B Testing · DTC Subscription</div>
            <h1 className="csx-hero-title">Subscription &amp; Purchase Growth <span className="gradient-text" style={{ background: "var(--grad-halo)", WebkitBackgroundClip: "text", backgroundClip: "text", WebkitTextFillColor: "transparent" }}>via A/B Testing</span></h1>
          </div>
          <div className="csx-hero-media">
            <Slot id="hero-featured" radius={20} src="assets/cs-cover-1920.avif" placeholder="Drop the hero / testimonial image" />
          </div>
          <div className="csx-hero-metrics">
            <div className="csx-tabs" role="tablist">
              {Object.keys(TABS).map((k) => (
                <button key={k} role="tab" aria-selected={tab === k} className={"csx-tab" + (tab === k ? " is-active" : "")} onClick={() => setTab(k)}>{k}</button>
              ))}
            </div>
            <div className="csx-stats">
              {TABS[tab].map((s, i) => (
                <div className="csx-stat" key={tab + i}>
                  <div className="csx-stat-num">{s.v}{s.up && <i className="ri-arrow-up-line csx-up" />}</div>
                  <div className="csx-stat-label">{s.l}</div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </header>
  );
}

// ---- meta band ----------------------------------------------------------
function MetaBand() {
  const services = [
    { i: "ri-focus-3-line", t: "CRO Audit" },
    { i: "ri-flask-line", t: "A/B Testing" },
    { i: "ri-pen-nib-line", t: "High-Converting Design" },
  ];
  const facts = [
    { i: "ri-store-2-line", t: "Industry", v: "DTC · Subscription store · Intimacy & Lifestyle" },
    { i: "ri-calendar-2-line", t: "Dates", v: "2-year+ program" },
    { i: "ri-stack-line", t: "Program", v: "20 launched in 90 days · 13 wins (active)" },
  ];
  return (
    <section className="csx-meta">
      <div className="csx-wrap">
        <div className="glass csx-meta-card">
          <div className="csx-meta-grid">
            <div>
              <div className="csx-label">Summary</div>
              <p className="csx-summary-text">Over a 2-year experimentation program, 63 tests were launched across PDPs, cart, and collection pages. 42 won, including major lifts from subscription toggles, mobile proof, and collection-page guidance.</p>
              <div className="csx-label">Services</div>
              <div className="csx-chips">
                {services.map((s) => <span className="csx-chip" key={s.t}><i className={s.i} />{s.t}</span>)}
              </div>
            </div>
            <div className="csx-meta-sub">
              <div className="csx-facts">
                {facts.map((f) => (
                  <div className="csx-fact" key={f.t}>
                    <span className="csx-fact-ic"><i className={f.i} /></span>
                    <div>
                      <p className="csx-fact-t">{f.t}</p>
                      <p className="csx-fact-v">{f.v}</p>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---- desktop sticky rail ------------------------------------------------
function Rail({ active }) {
  return (
    <aside className="csx-rail">
      <div>
        <div className="csx-toc-title"><i className="ri-list-unordered" />Table of Contents</div>
        <nav className="csx-toc">
          {SECTIONS.map((s) => (
            <a key={s.id} href={"#" + s.id} className={"csx-toc-link" + (active === s.id ? " is-active" : "")}>{s.n}</a>
          ))}
        </nav>
      </div>
      <div className="glass glass--featured csx-wins">
        <div className="csx-wins-h">Want to know what we would fix first?</div>
        <p className="csx-wins-p">Run a quick PDP scan for 5 visible fixes. If you like the fixes, connect with our founder and we will map a deeper CRO audit based on your data.</p>
        <a href={LANDING + "#cta"} className="btn btn-primary btn-sm">Get my 5 free PDP fixes <i className="ri-arrow-right-line" /></a>
        <div className="csx-wins-proof">
          <div className="csx-wins-badge">
            <span className="csx-wins-stars csx-wins-stars--tp"><i className="ri-star-fill" /><i className="ri-star-fill" /><i className="ri-star-fill" /><i className="ri-star-fill" /><i className="ri-star-fill" /></span>
            <img src={assetUrl("assets/trustpilot-wordmark.png")} alt="Trustpilot" />
          </div>
          <div className="csx-wins-badge">
            <span className="csx-wins-stars"><i className="ri-star-fill" /><i className="ri-star-fill" /><i className="ri-star-fill" /><i className="ri-star-fill" /><i className="ri-star-fill" /></span>
            <img src={assetUrl("assets/clutch-wordmark.png")} alt="Clutch" />
          </div>
        </div>
      </div>
    </aside>
  );
}

// ---- mobile TOC dropdown ------------------------------------------------
function MobileTOC({ active }) {
  const [open, setOpen] = useState(false);
  const cur = SECTIONS.find((s) => s.id === active);
  const label = cur ? cur.n : "Table of Contents";
  return (
    <div className={"csx-toc-mob" + (open ? " is-open" : "")}>
      <button className="csx-toc-mob-btn" onClick={() => setOpen(!open)} aria-expanded={open}>
        <span className="csx-toc-mob-cur"><i className="ri-list-unordered" />{label}</span>
        <i className="ri-arrow-down-s-line csx-toc-mob-chev" />
      </button>
      <div className="csx-toc-mob-panel">
        <div className="csx-toc-mob-list">
          <div className="csx-toc-mob-list-inner">
            {SECTIONS.map((s) => (
              <a key={s.id} href={"#" + s.id} className={active === s.id ? "is-active" : ""} onClick={() => setOpen(false)}>{s.n}</a>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

// ---- mobile sticky CTA dropdown -----------------------------------------
function MobileCTA() {
  const [open, setOpen] = useState(false);
  const [show, setShow] = useState(false);
  useEffect(() => {
    const onScroll = () => {
      const a = document.getElementById("client");
      const past = a ? a.getBoundingClientRect().top < window.innerHeight * 0.85 : false;
      setShow(past);
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  useEffect(() => {
    document.body.classList.toggle("csx-cta-on", show);
    return () => document.body.classList.remove("csx-cta-on");
  }, [show]);
  return (
    <div className={"csx-mobcta" + (open ? " is-open" : "") + (show ? " is-visible" : "")}>
      <button className="csx-mobcta-bar" onClick={() => setOpen(!open)} aria-expanded={open}>
        <span className="csx-mobcta-lead"><span className="csx-mobcta-dot" />Build visitor loyalty</span>
        <i className="ri-arrow-up-s-line csx-mobcta-chev" />
      </button>
      <div className="csx-mobcta-panel">
        <div className="csx-mobcta-inner">
          <div className="csx-mobcta-content">
            <div className="csx-mobcta-h">Turn browsers into repeat visitors.</div>
            <p className="csx-mobcta-p">Discover ways to guide visitors from first click to long-term engagement — starting with 5 free fixes for your store.</p>
            <a href={LANDING + "#cta"} className="btn btn-primary">Claim your free audit <i className="ri-arrow-right-line" /></a>
            <div className="csx-wins-proof csx-mobcta-proof">
              <div className="csx-wins-badge">
                <span className="csx-wins-stars csx-wins-stars--tp"><i className="ri-star-fill" /><i className="ri-star-fill" /><i className="ri-star-fill" /><i className="ri-star-fill" /><i className="ri-star-fill" /></span>
                <img src={assetUrl("assets/trustpilot-wordmark.png")} alt="Trustpilot" />
              </div>
              <div className="csx-wins-badge">
                <span className="csx-wins-stars"><i className="ri-star-fill" /><i className="ri-star-fill" /><i className="ri-star-fill" /><i className="ri-star-fill" /><i className="ri-star-fill" /></span>
                <img src={assetUrl("assets/clutch-wordmark.png")} alt="Clutch" />
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ---- test block ---------------------------------------------------------
function TestBlock({ t }) {
  return (
    <div className="csx-test">
      <div className="csx-test-head">
        <span className="csx-test-badge">{t.badge}</span>
        <h3 className="csx-test-title">{t.title}</h3>
      </div>
      <div className="csx-spec">
        {t.spec.map(([k, v], i) => (
          <React.Fragment key={k}>
            <div className="csx-spec-k">{k}</div>
            <div className="csx-spec-v">{v}</div>
          </React.Fragment>
        ))}
      </div>
      <div className="csx-result">
        <span className="csx-result-ic"><i className="ri-line-chart-line" /></span>
        <div className="csx-result-txt">Result: <strong>{t.result[0]}</strong> · {t.result[1]} → <strong>{t.result[2]}</strong>.</div>
      </div>
      <div className="csx-ba">
        <div className="csx-ba-col csx-ba-col--before">
          <span className="csx-ba-tag">Before</span>
          <Slot id={t.before} src={t.beforeSrc} style={t.ratio ? { aspectRatio: t.ratio } : undefined} placeholder="Drop the control screenshot" />
        </div>
        <div className="csx-ba-col csx-ba-col--after">
          <span className="csx-ba-tag">After</span>
          <Slot id={t.after} src={t.afterSrc} style={t.ratio ? { aspectRatio: t.ratio } : undefined} placeholder="Drop the variant screenshot" />
        </div>
      </div>
      <p className="csx-note">{t.note}</p>
      <p className="csx-figcap">{t.cap}</p>
    </div>
  );
}

// ---- article ------------------------------------------------------------
function H2({ id, num, children }) {
  return (
    <h2 className="csx-h2" id={id}>
      {num && <span className="csx-h2-num">{num}</span>}{children}
    </h2>
  );
}

function Article() {
  return (
    <article className="csx-article">
      {/* 01 — Client & Context */}
      <section className="csx-sec" id="client" data-screen-label="Client & Context" style={{ scrollMarginTop: 110 }}>
        <H2 num="01">Client &amp; Context</H2>
        <p className="csx-p">Her Fantasy Box is a fast-growing DTC subscription brand in the intimacy and lifestyle space. The brand reached <strong>$50M+</strong> in online sales within its first three years while working with us across UX, conversion experimentation, and subscription growth. The engagement focused on improving <strong>subscription adoption</strong>, browse-to-product flow, cart momentum, and revenue efficiency.</p>
      </section>

      {/* 02 — Challenge & Goals */}
      <section className="csx-sec" id="challenge" data-screen-label="Challenge & Goals">
        <H2 num="02">Challenge &amp; Goals</H2>
        <div className="csx-cols2">
          <div className="csx-subcard csx-subcard--neg">
            <p className="csx-subcard-h"><i className="ri-error-warning-line" />Challenges</p>
            <ul className="csx-list">
              <li>Shoppers discovered products, but <strong>subscription value</strong> was not visible at the right decision points.</li>
              <li>Mobile PDPs did not surface <strong>high-trust social proof</strong> early enough.</li>
              <li>Collection pages made it harder than necessary to find the <strong>right product or subscription path</strong>.</li>
            </ul>
          </div>
          <div className="csx-subcard csx-subcard--pos">
            <p className="csx-subcard-h"><i className="ri-focus-3-line" />Goals</p>
            <ul className="csx-list">
              <li>Increase <strong>subscription conversion</strong> without hurting one-time purchase conversion.</li>
              <li>Build trust earlier on <strong>mobile PDPs</strong>.</li>
              <li>Improve <strong>collection-level guidance</strong>, filtering, and product discovery.</li>
              <li>Maintain a clean testing cadence with clear guardrails.</li>
            </ul>
          </div>
        </div>
      </section>

      {/* 03 — Discovery */}
      <section className="csx-sec" id="discovery" data-screen-label="Discovery">
        <H2 num="03">Discovery</H2>
        <ul className="csx-list">
          <li>Reviewed the highest-impact pages: homepage, PDPs, collections, cart, and checkout flow.</li>
          <li>Analyzed funnel behavior, session recordings, and abandonment points.</li>
          <li>Studied competitive patterns for subscription framing, gallery structure, product discovery, and page flow.</li>
          <li>Prioritized the backlog using <strong>ICE</strong>: impact, confidence, and effort.</li>
        </ul>
        <div className="csx-figure">
          <Slot id="discovery-audit" radius={14} src="assets/cs-discovery.avif" placeholder="Drop the 91-page audit mockup" />
          <p className="csx-figcap">Cutout &amp; mockup of the 91-page audit</p>
        </div>
      </section>

      {/* 04 — Solutions */}
      <section className="csx-sec" id="solution" data-screen-label="Solutions">
        <H2 num="04">Solutions <span style={{ color: "var(--fg3)", fontWeight: 400, fontSize: 20 }}>(Featured test wins)</span></H2>
        <p className="csx-p">Three of the highest-impact wins from the program, each diagnosed in discovery, prioritized by ICE, shipped as a clean 50/50 experiment, and measured to confidence.</p>
        {TESTS.map((t) => <TestBlock key={t.badge} t={t} />)}
      </section>

      {/* 05 — Implementation */}
      <section className="csx-sec" id="implementation" data-screen-label="Implementation & Development">
        <H2 num="05">Implementation &amp; Development</H2>
        <div className="csx-spec" style={{ marginTop: 18 }}>
          <div className="csx-spec-k">Platform</div>
          <div className="csx-spec-v">Shopify</div>
          <div className="csx-spec-k">Experiments</div>
          <div className="csx-spec-v">Convert.com</div>
          <div className="csx-spec-k">Measurement</div>
          <div className="csx-spec-v">Subscription conversion, overall conversion, engagement, performance, and abandonment guardrails.</div>
          <div className="csx-spec-k">QA</div>
          <div className="csx-spec-v">Responsive behavior, accessibility basics, visual consistency, event tracking, and error handling.</div>
        </div>
      </section>

      {/* 06 — Results & Impact */}
      <section className="csx-sec" id="results" data-screen-label="Results & Impact">
        <H2 num="06">Results &amp; Impact</H2>
        <div className="csx-cols2">
          <div className="csx-subcard">
            <p className="csx-subcard-h" style={{ color: "var(--magenta-300)" }}><i className="ri-trophy-line" />Program to date</p>
            <ul className="csx-list">
              <li><strong>63 tests</strong> launched.</li>
              <li><strong>42 winning tests.</strong></li>
              <li><strong>67% win rate.</strong></li>
              <li>Active experimentation program with compounding gains across PDP, cart, and collection pages.</li>
            </ul>
          </div>
          <div className="csx-subcard">
            <p className="csx-subcard-h" style={{ color: "var(--violet-400)" }}><i className="ri-bar-chart-grouped-line" />Client-reported</p>
            <ul className="csx-list">
              <li><strong>$50M+</strong> in online sales reached within the brand's first three years.</li>
            </ul>
          </div>
        </div>
        <div className="glass csx-winbox">
          <p className="csx-winbox-h">Highlighted wins — 63 tests · 42 winners · 67% win rate</p>
          <div className="csx-winrow">
            <span className="csx-winrow-l">PDP mobile proof — conversion lift</span>
            <span className="csx-winrow-v">+26.41%</span>
          </div>
          <div className="csx-winrow">
            <span className="csx-winrow-l">Cart subscription toggle — subscription conversion lift</span>
            <span className="csx-winrow-v">+15.43%</span>
          </div>
          <div className="csx-winrow">
            <span className="csx-winrow-l">Collection top fold — subscription conversion lift</span>
            <span className="csx-winrow-v">+27.56%</span>
          </div>
        </div>
      </section>

      {/* Testimonial */}
      <section className="csx-sec" id="testimonial" data-screen-label="Testimonials">
        <div className="glass csx-quote">
          <div className="csx-quote-photo"><Slot id="quote-photo" src="assets/cs-testimonial.avif" placeholder="Photo" radius={999} /></div>
          <div>
            <Stars n={5} size={15} />
            <p className="csx-quote-txt">"Their work over the year has been instrumental to our growth. They were able to work with us with little to no direction. Throughout it we've gone through full website revamps, product launches, new applications, and they have been rock solid throughout the whole process."</p>
            <div className="csx-quote-by">
              <p className="csx-quote-name">Willie P.</p>
              <p className="csx-quote-role">Co-Founder &amp; CMO</p>
            </div>
          </div>
          <img className="csx-quote-logo" src={assetUrl("assets/ecom-logos/her-fantasy-box.avif")} alt="Her Fantasy Box" />
        </div>

        {/* Final CTA card */}
        <div className="glass glass--featured csx-cta">
          <div className="haze-bloom" aria-hidden="true" />
          <div className="csx-cta-inner">
            <h3 className="csx-cta-h">Ready to find the tests worth running on your store?</h3>
            <div className="csx-cta-checks">
              <div className="csx-cta-check"><i className="ri-check-line" />Review your Shopify funnel with the founder.</div>
              <div className="csx-cta-check"><i className="ri-check-line" />Pinpoint PDP, cart, collection, and subscription bottlenecks.</div>
              <div className="csx-cta-check"><i className="ri-check-line" />Leave with the next step toward a paid audit and 90-day CRO roadmap.</div>
            </div>
            <div className="csx-cta-actions">
              <a href={LANDING + "#cta"} className="btn btn-primary">Book a Shopify audit consult <i className="ri-arrow-right-line" /></a>
              <a href={LANDING + "#cta"} className="btn btn-secondary">Get 5 free PDP fixes</a>
            </div>
          </div>
        </div>
      </section>
    </article>
  );
}

// ---- other case studies -------------------------------------------------
function OtherCases() {
  const trackRef = useRef(null);
  const [idx, setIdx] = useState(0);
  const scrollTo = (i) => {
    const track = trackRef.current; if (!track) return;
    const card = track.children[i];
    if (card) track.scrollTo({ left: card.offsetLeft - track.offsetLeft, behavior: "smooth" });
  };
  const onScroll = () => {
    const track = trackRef.current; if (!track) return;
    let nearest = 0, best = Infinity;
    [...track.children].forEach((c, i) => {
      const d = Math.abs(c.offsetLeft - track.offsetLeft - track.scrollLeft);
      if (d < best) { best = d; nearest = i; }
    });
    setIdx(nearest);
  };
  const step = (dir) => scrollTo(Math.max(0, Math.min(OTHER.length - 1, idx + dir)));
  return (
    <section className="csx-other">
      <div className="csx-wrap">
        <div className="csx-other-head">
          <h2 className="csx-other-title">Other case studies</h2>
          <div className="csx-other-nav">
            <button className="csx-arrow" onClick={() => step(-1)} aria-label="Previous"><i className="ri-arrow-left-line" /></button>
            <button className="csx-arrow" onClick={() => step(1)} aria-label="Next"><i className="ri-arrow-right-line" /></button>
          </div>
        </div>
        <div className="csx-other-track" ref={trackRef} onScroll={onScroll}>
          {OTHER.map((c) => (
            <article className="csx-other-card" key={c.id}>
              <div className="csx-other-media"><img src={assetUrl(c.img)} alt={c.name} loading="lazy" /></div>
              <div className="csx-other-body">
                <p className="csx-other-desc">{c.desc}</p>
                <div className="csx-other-metrics">
                  {c.m.map(([txt, up], i) => (
                    <div className="csx-other-metric" key={i}>
                      <i className={up ? "ri-arrow-up-line" : "ri-timer-flash-line"} style={{ color: up ? "var(--success)" : "var(--violet-400)" }} />
                      <span>{txt}</span>
                    </div>
                  ))}
                </div>
                {c.href && <a href={c.href} className="csx-other-link">View case study <i className="ri-arrow-right-line" /></a>}
              </div>
            </article>
          ))}
        </div>
        <div className="csx-dots">
          {OTHER.map((c, i) => <button key={i} className={"csx-dot" + (idx === i ? " is-active" : "")} onClick={() => scrollTo(i)} aria-label={"Go to " + c.name} />)}
        </div>
      </div>
    </section>
  );
}

// ---- footer -------------------------------------------------------------
function CaseFooter() {
  const cols = [
    { head: "Conversion Works", links: [["The problem", LANDING + "#work"], ["What we build", LANDING + "#workers"], ["Process", LANDING + "#how"], ["Case studies", LANDING + "#showcase"], ["Pricing", LANDING + "#pricing"]] },
    { head: "Taurist", links: [["Taurist Technologies", "https://www.taurist.com/"], ["Siteworks", "https://www.taurist.com/siteworks"], ["Workers", "https://www.taurist.com/workers"], ["About", "https://www.taurist.com/about"], ["Notes", "https://www.taurist.com/notes"], ["Email Us", "mailto:hello@taurist.com"]] },
  ];
  const link = { fontFamily: "var(--font-body)", fontWeight: 300, fontSize: 14, color: "var(--fg3)", textDecoration: "none", transition: "color .15s", width: "fit-content" };
  const colHead = { fontFamily: "var(--font-ui)", fontSize: 12, fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--fg2)", marginBottom: 16 };
  return (
    <footer style={{ borderTop: "1px solid var(--border-subtle)", background: "var(--neutral-900)", paddingTop: 64, position: "relative" }}>
      <div className="streak" style={{ position: "absolute", top: 0, left: 0, right: 0, opacity: 0.4 }} />
      <div className="wrap">
        <div style={{ display: "grid", gap: 40, paddingBottom: 52, gridTemplateColumns: "1.6fr 1fr 1fr" }} className="footer-grid">
          <div>
            <div style={{ display: "flex", alignItems: "center", gap: 14, flexWrap: "wrap", rowGap: 8 }}>
              <Logo height={40} />
              <span style={{ width: 1, height: 20, background: "var(--border-default)" }} />
              <span style={{ fontFamily: "var(--font-ui)", fontSize: 12, fontWeight: 600, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--fg3)" }}>by Taurist Technologies Inc</span>
            </div>
            <p style={{ fontFamily: "var(--font-body)", fontWeight: 300, fontSize: 14, lineHeight: 1.6, color: "var(--fg2)", margin: "20px 0 0", maxWidth: 360 }}>
              Founder-led Shopify CRO. We find the friction, fix the flow, and measure what moved.
            </p>
            <a href={LANDING + "#cta"} className="btn btn-primary btn-sm" style={{ marginTop: 24 }}>Get my 5 free fixes <i className="ri-arrow-right-line" /></a>
          </div>
          {cols.map((c) => (
            <div key={c.head}>
              <div style={colHead}>{c.head}</div>
              <div style={{ display: "flex", flexDirection: "column", gap: 11 }}>
                {c.links.map(([t, h]) => (
                  <a key={t} href={h} style={link} {...(h.startsWith("http") ? { target: "_blank", rel: "noopener noreferrer" } : {})}
                    onMouseEnter={(e) => (e.currentTarget.style.color = "var(--magenta-300)")}
                    onMouseLeave={(e) => (e.currentTarget.style.color = "var(--fg3)")}>{t}</a>
                ))}
              </div>
            </div>
          ))}
        </div>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "22px 0", borderTop: "1px solid var(--border-subtle)", flexWrap: "wrap", gap: 16 }}>
          <span style={{ fontFamily: "var(--font-body)", fontSize: 13, color: "var(--fg3)" }}>© 2026 Taurist Technologies Inc. All rights reserved.</span>
          <a href="https://www.taurist.com/siteworks" target="_blank" rel="noopener noreferrer" style={{ display: "inline-flex", alignItems: "center", gap: 9, fontFamily: "var(--font-body)", fontSize: 13, color: "var(--fg3)", textDecoration: "none", transition: "color .15s" }}
            onMouseEnter={(e) => (e.currentTarget.style.color = "var(--fg1)")}
            onMouseLeave={(e) => (e.currentTarget.style.color = "var(--fg3)")}>
            Like this site? Built by
            <img src={assetUrl("assets/siteworks-mark.avif")} alt="" width="20" height="20" style={{ display: "block" }} />
            <span style={{ fontWeight: 600, color: "var(--fg1)" }}>Siteworks.</span>
          </a>
          <div style={{ display: "flex", alignItems: "center", gap: 22 }}>
            <a href="https://www.taurist.com/privacy-policy" style={{ fontFamily: "var(--font-body)", fontSize: 13, color: "var(--fg3)", textDecoration: "none" }}>Privacy Policy</a>
            <a href="https://www.taurist.com/terms-conditions" style={{ fontFamily: "var(--font-body)", fontSize: 13, color: "var(--fg3)", textDecoration: "none" }}>Terms of Service</a>
          </div>
        </div>
      </div>
    </footer>
  );
}

// ---- page ---------------------------------------------------------------
function CaseStudyPage() {
  const ids = SECTIONS.map((s) => s.id);
  const active = useScrollSpy(ids);
  const lens = useLensChat();
  // Any CTA on the page opens the Lens chat instead of navigating away.
  useEffect(() => {
    const onClick = (e) => {
      const a = e.target.closest('a[href$="#cta"]');
      if (a && lens && lens.openFullscreen) { e.preventDefault(); lens.openFullscreen(); }
    };
    document.addEventListener("click", onClick);
    return () => document.removeEventListener("click", onClick);
  }, [lens]);
  // cursor-following light on primary/secondary buttons (matches the rest of the site)
  useEffect(() => {
    const onMove = (e) => {
      const btn = e.target.closest(".btn-primary, .btn-secondary");
      if (btn) {
        const r = btn.getBoundingClientRect();
        btn.style.setProperty("--mx", `${((e.clientX - r.left) / r.width) * 100}%`);
        btn.style.setProperty("--my", `${((e.clientY - r.top) / r.height) * 100}%`);
      }
    };
    document.addEventListener("pointermove", onMove);
    return () => document.removeEventListener("pointermove", onMove);
  }, []);
  return (
    <div className="csx-page">
      <CaseNav />
      <Hero />
      <MetaBand />
      <div className="csx-wrap">
        <MobileTOC active={active} />
        <div className="csx-layout">
          <Rail active={active} />
          <Article />
        </div>
      </div>
      <OtherCases />
      <CaseFooter />
      <MobileCTA />
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(
  <LensChatProvider>
    <CaseStudyPage />
    <LensLauncher />
    <LensFullscreen />
  </LensChatProvider>
);
