// Showcase.jsx — "Selected website work": immersive proof wall of website previews.
// Each card renders a synthetic, brand-tinted homepage "screenshot"; on hover a glass
// "Siteworks Lens" slides up with standardized business context.

const SW_BRANDS = {
  ezraider: {
    name: "EZ-Raider", cat: "DTC · Mobility", acc: "#2BA8E0", logoKey: "ezraider", featured: true, variant: "split",
    url: "ezraider-usa.com", navCta: "Find a dealer",
    heroEy: "All-terrain electric", headline: "Go further. Anywhere off-road.", heroCta: "Explore models",
    sub: "Foldable all-terrain electric vehicles for work, rescue, and the trail.",
    lens: { type: "DTC mobility storefront", job: "Make a high-ticket vehicle feel safe to buy", path: "Explore models → request quote → dealer call", proof: "Demo video, owner reviews, dealer network" },
  },
  powerchord: {
    name: "PowerChord", cat: "B2B · SaaS", acc: "#F26422", logoKey: "powerchord", variant: "left",
    url: "powerchord.com", navCta: "Book a demo",
    heroEy: "Local marketing platform", headline: "Local marketing at national scale.", heroCta: "Book a demo",
    sub: "One platform to power every local dealer and franchise location.",
    lens: { type: "B2B SaaS marketing site", job: "Explain a complex platform to enterprise buyers", path: "Read use case → book demo → sales call", proof: "Client logos, case studies, ROI metrics" },
  },
  impala: {
    name: "Impala", cat: "API · Hospitality", acc: "#1FB57A", logoKey: "impala", variant: "left",
    url: "impala.digital", navCta: "Start for Free",
    heroEy: "Hospitality API", headline: "One API for the entire hotel stack.", heroCta: "Read the docs",
    sub: "Connect to hotel inventory, rates, and bookings in minutes.",
    lens: { type: "Philanthropy data platform", job: "Help foundations and nonprofits make smarter data-backed decisions", path: "Explore solutions → start for free → use platform", proof: "Customer quotes, product modules, funder/nonprofit workflows" },
  },
  doubleai: {
    name: "doubleAI", cat: "AI · Platform", acc: "#8C6BF0", logoKey: "doubleai", variant: "center",
    url: "doubleai.com", navCta: "Read Research",
    heroEy: "AI build platform", headline: "Ship AI products with confidence.", heroCta: "Start building",
    sub: "Test, evaluate, and deploy AI features your team can trust.",
    lens: { type: "AI research company", job: "Build credibility around expert-level AI for science and technology", path: "Read artifact → view research → explore GitHub", proof: "Technical posts, WarpSpeed artifact, GitHub repo, investor logos" },
  },
  bluegrid: {
    name: "Bluegrid", cat: "Cleantech · Energy", acc: "#2E8FE6", logoKey: "bluegrid", variant: "left",
    url: "bluegrid.ai", navCta: "Get in Touch",
    heroEy: "Smart energy", headline: "Power the grid of tomorrow.", heroCta: "Explore solutions",
    sub: "Intelligent storage and distribution for a cleaner grid.",
    lens: { type: "Protected connectivity and intelligence", job: "Explain below-surface infrastructure for telecom, utilities, and security", path: "Choose solution → get in touch → assessment", proof: "Solution paths, case studies, patents, R&D credibility" },
  },
  viola: {
    name: "Viola", cat: "Venture Capital", acc: "#B84FD0", logoKey: "violaventures", variant: "center",
    url: "viola.vc", navCta: "Pitch us",
    heroEy: "Venture capital", headline: "Backing founders who build the future.", heroCta: "Meet the team",
    sub: "Partnering with category-defining companies from seed to scale.",
    lens: { type: "Venture capital site", job: "Attract strong founders and LPs", path: "Read thesis → meet the team → pitch", proof: "Portfolio, exits, partner bios" },
  },
  icostore: {
    name: "iCoStore", cat: "Ecommerce", acc: "#F26422", logoKey: null, featured: true, variant: "split",
    url: "icostore.com", navCta: "Request a Demo",
    heroEy: "Premium tech retail", headline: "Premium tech, delivered fast.", heroCta: "Shop the range",
    sub: "Curated electronics and accessories with next-day shipping.",
    lens: { type: "B2B company store platform", job: "Centralize branded merch, uniforms, print, and fulfillment", path: "Explore programs → request demo → custom quote", proof: "No minimums, no inventory, on-demand production, integrations" },
  },
  vimi: {
    name: "Vimi", cat: "Premium · DTC", acc: "#D99A4E", logoKey: "vimi", variant: "left",
    url: "heyvimi.com", navCta: "Download the App",
    heroEy: "Designed to last", headline: "Furniture made for a lifetime.", heroCta: "View collection",
    sub: "Solid-wood pieces, built by hand and made to be kept.",
    lens: { type: "AI math tutor app", job: "Make personalized math help feel simple, fun, and trustworthy", path: "Learn benefits → download app → start tutoring", proof: "Curriculum alignment, adaptive path, tutor comparison, FAQs" },
  },
  ldr: {
    name: "LDR Site Services", cat: "Local · Service", acc: "#E0552A", logoKey: null, variant: "left",
    url: "ldrsiteservices.com", navCta: "Request a Quote",
    heroEy: "Dumpsters & site services", headline: "Site services, on time.", heroCta: "Get a price",
    sub: "Roll-off dumpsters and portable toilets, booked in minutes.",
    lens: { type: "Nationwide site services", job: "Make urgent jobsite equipment needs feel reliable and easy to quote", path: "Request quote → call → project coordination", proof: "Nationwide vendor network, 10,000+ projects/year, 24/7 availability" },
  },
  hastings: {
    name: "Hastings Bath Collection", cat: "Luxury · Retail", acc: "#B79256", logoKey: "hastings", variant: "center",
    url: "hastingstilebath.com", navCta: "Find a showroom",
    heroEy: "Italian bathware", headline: "Bathware for the considered home.", heroCta: "Browse collection",
    sub: "Curated fixtures and finishes for designers and trade.",
    lens: { type: "Luxury retail catalog", job: "Present premium bathware to designers and trade", path: "Browse collection → find showroom → inquire", proof: "Showrooms, finishes, design press" },
  },
  enso: {
    name: "Enso Brands", cat: "Brand · House", acc: "#4FB890", logoKey: "enso", variant: "left",
    url: "ensobrands.com", navCta: "Partner with us",
    heroEy: "Consumer brand house", headline: "Building brands people love.", heroCta: "See the brands",
    sub: "Acquiring and scaling beloved consumer products.",
    lens: { type: "Brand house / corporate site", job: "Position a multi-brand operator to partners", path: "See brands → contact → partnership", proof: "Brand portfolio, growth, press" },
  },
  moonshot: {
    name: "Moonshot AI", cat: "AI · Research", acc: "#9B6BFF", logoKey: "moonshot", variant: "center",
    url: "moonshot.ai", navCta: "Try the model",
    heroEy: "Frontier intelligence", headline: "Frontier intelligence for everyone.", heroCta: "Try the model",
    sub: "Research-grade models, ready for real products.",
    lens: { type: "AI research / product site", job: "Communicate frontier capability with credibility", path: "Try model → read research → contact", proof: "Benchmarks, research, customer logos" },
  },
  airtop: {
    name: "Airtop", cat: "Dev · Infra", acc: "#27B6C4", logoKey: "airtop", variant: "left",
    url: "airtop.ai", navCta: "Start free",
    heroEy: "Cloud browsers", headline: "Cloud browsers for AI agents.", heroCta: "Read the docs",
    sub: "Give your agents a real browser, hosted and at scale.",
    lens: { type: "Developer infrastructure site", job: "Sell cloud browsers to AI builders", path: "Read docs → start free → upgrade", proof: "Docs, SDKs, live status page" },
  },
  majestic: {
    name: "Majestic Smoothie", cat: "Local · F&B", acc: "#E14C7E", logoKey: null, variant: "left",
    url: "majesticsmoothie.com", navCta: "View Menu",
    heroEy: "Smoothies & juice bar", headline: "Fresh smoothies, made to order.", heroCta: "View menu",
    sub: "Cold-pressed juices and blends in Maplewood.",
    lens: { type: "Local smoothie and juice bar", job: "Turn local interest into menu views, visits, and online orders", path: "View menu → order online → visit Maplewood location", proof: "Fresh ingredients, menu variety, hours, location, contact details" },
  },
};

const SW_FOCUS = [
  { k: "ezraider", col: "1 / 8", row: "1 / 3", si: 0 },
  { k: "impala", col: "8 / 13", row: "1", si: 3 },
  { k: "hastings", col: "8 / 13", row: "2", si: 4 },
  { k: "doubleai", col: "1 / 5", row: "3", si: 1 },
  { k: "majestic", col: "5 / 9", row: "3", si: 2 },
  { k: "powerchord", col: "9 / 13", row: "3", si: 5 },
];
const SW_ASIDE_L = ["bluegrid", "viola", "icostore", "vimi"];
const SW_ASIDE_R = ["ldr", "enso", "moonshot", "airtop"];

// sites that have a recorded clip (everyone except LDR), and those with a mobile clip
const SW_CLIP = new Set(["ezraider","impala","doubleai","powerchord","hastings","vimi","icostore","bluegrid","majestic","enso","airtop","viola","moonshot","ldr"]);
const SW_MOBILE = new Set(["ezraider","impala","doubleai","powerchord","hastings","vimi","icostore","bluegrid"]);

// EZ-Raider auto-plays while the section is on screen; hovering any OTHER card pauses it.
let ezInView = false, ezHoverPaused = false;
function swIsMobile(){ return window.matchMedia && window.matchMedia("(max-width: 760px)").matches; }
function ezVideos(){ const ez = document.querySelector(".sw-fc--ez"); return ez ? ez.querySelectorAll("video") : []; }
function setEz(play){ ezVideos().forEach((v) => { if (play) { const p = v.play(); if (p && p.catch) p.catch(() => {}); } else { v.pause(); } }); }
function ezOnScreen(){
  const ez = document.querySelector(".sw-fc--ez");
  if (!ez) return false;
  const r = ez.getBoundingClientRect();
  const vh = window.innerHeight || document.documentElement.clientHeight;
  return r.bottom > vh * 0.15 && r.top < vh * 0.85;
}
// on phones the "centred card" logic (below) owns playback, so skip the desktop autoplay
function syncEz(){ if (swIsMobile()) return; ezInView = ezOnScreen(); if (ezHoverPaused) return; setEz(ezInView); }

// hover plays every <video> in the card; leaving pauses and rewinds to the poster frame
function playCard(e){
  const card = e.currentTarget;
  card.querySelectorAll("video").forEach((v) => { const p = v.play(); if (p && p.catch) p.catch(() => {}); });
  if (!card.classList.contains("sw-fc--ez")) { ezHoverPaused = true; setEz(false); }
}
function stopCard(e){
  const card = e.currentTarget;
  if (card.classList.contains("sw-fc--ez")) {
    if (!ezOnScreen()) card.querySelectorAll("video").forEach((v) => { v.pause(); try { v.currentTime = 0; } catch (_) {} });
    return;
  }
  card.querySelectorAll("video").forEach((v) => { v.pause(); try { v.currentTime = 0; } catch (_) {} });
  ezHoverPaused = false;
  if (ezOnScreen()) setEz(true);
}

function Desktop({ b }) {
  return (
    <React.Fragment>
      <div className="sw-chrome">
        <span className="sw-dot" /><span className="sw-dot" /><span className="sw-dot" />
        <span className="sw-url"><i className="ri-lock-line" />{b.url}</span>
      </div>
      <div className="sw-site">
        <span className="sw-grid" aria-hidden="true" />
        <span className="sw-bloom" aria-hidden="true" />
        <div className={"sw-frame sw-frame--" + b.variant}>
          <div className="sw-nav">
            {b.logoKey
              ? <img className="sw-logo" src={assetUrl(`assets/clients/${b.logoKey}.png`)} alt="" />
              : <span className="sw-logo-txt">{b.name}</span>}
            <div className="sw-nav-items">
              <span className="sw-nav-link" /><span className="sw-nav-link" /><span className="sw-nav-link" />
              <span className="sw-nav-cta">{b.navCta}</span>
            </div>
          </div>
          <div className="sw-stage">
            <div className="sw-hero">
              <span className="sw-eybr">{b.heroEy}</span>
              <div className="sw-h">{b.headline}</div>
              <p className="sw-sub">{b.sub}</p>
              <span className="sw-cta-pill">{b.heroCta} <i className="ri-arrow-right-line" /></span>
            </div>
            {b.variant === "split" && (
              <div className="sw-panel" aria-hidden="true">
                <span className="sw-panel-dot" />
                <span className="sw-bar w70" /><span className="sw-bar w90" /><span className="sw-bar w55" /><span className="sw-bar w80" />
              </div>
            )}
          </div>
          <span className="sw-horizon" aria-hidden="true" />
        </div>
      </div>
    </React.Fragment>
  );
}

function Phone({ b }) {
  return (
    <div className="sw-phone" aria-hidden="true">
      <div className="sw-phone-scr">
        <span className="sw-bloom" aria-hidden="true" />
        <div className="sw-phone-top">
          {b.logoKey
            ? <img className="sw-phone-logo" src={assetUrl(`assets/clients/${b.logoKey}.png`)} alt="" />
            : <span className="sw-phone-name">{b.name}</span>}
          <span className="sw-phone-burger"><i className="ri-menu-line" /></span>
        </div>
        <div className="sw-phone-hero">
          <span className="sw-eybr">{b.heroEy}</span>
          <div className="sw-ph-h">{b.headline}</div>
          <span className="sw-ph-cta">{b.heroCta}</span>
        </div>
      </div>
    </div>
  );
}

function Lens({ b }) {
  return (
    <div className="sw-lens">
      <div className="sw-lens-head">
        <span className="sw-lens-brand">{b.name}</span>
        <span className="sw-lens-tag">Siteworks Lens</span>
      </div>
      <div className="sw-lens-grid">
        <span className="sw-lens-k">Site type</span><span className="sw-lens-v">{b.lens.type}</span>
        <span className="sw-lens-k">Primary job</span><span className="sw-lens-v">{b.lens.job}</span>
        <span className="sw-lens-k">Conversion path</span><span className="sw-lens-v">{b.lens.path}</span>
        <span className="sw-lens-k">Proof system</span><span className="sw-lens-v">{b.lens.proof}</span>
      </div>
    </div>
  );
}

function DeskVid({ keyName, b, eager }) {
  return (
    <React.Fragment>
      <div className="sw-chrome">
        <span className="sw-dot" /><span className="sw-dot" /><span className="sw-dot" />
        <span className="sw-url"><i className="ri-lock-line" />{b.url}</span>
      </div>
      <video className="sw-vid" muted loop playsInline preload={eager ? "auto" : "none"}
        poster={assetUrl(`assets/clips/${keyName}-desktop.png`)}
        src={assetUrl(`assets/clips/${keyName}-desktop.mp4`)} />
    </React.Fragment>
  );
}

function PhoneVid({ keyName, eager }) {
  return (
    <div className="sw-phone">
      <video className="sw-vid" muted loop playsInline preload={eager ? "auto" : "none"}
        poster={assetUrl(`assets/clips/${keyName}-mobile.png`)}
        src={assetUrl(`assets/clips/${keyName}-mobile.mp4`)} />
    </div>
  );
}

function About({ b, open }) {
  return (
    <details className="sw-about" open={open}>
      <summary className="sw-about-sum">
        <span className="sw-about-tag">About this site</span>
        <i className="ri-arrow-down-s-line sw-about-chev" />
      </summary>
      <div className="sw-about-grid">
        <span className="sw-lens-k">Site type</span><span className="sw-lens-v">{b.lens.type}</span>
        <span className="sw-lens-k">Primary job</span><span className="sw-lens-v">{b.lens.job}</span>
        <span className="sw-lens-k">Conversion path</span><span className="sw-lens-v">{b.lens.path}</span>
        <span className="sw-lens-k">Proof system</span><span className="sw-lens-v">{b.lens.proof}</span>
      </div>
    </details>
  );
}

function FocusCard({ keyName, col, row, idx, si }) {
  const b = SW_BRANDS[keyName];
  const ez = keyName === "ezraider";
  const clip = SW_CLIP.has(keyName);
  const mob = SW_MOBILE.has(keyName);
  return (
    <div className={"sw-card sw-card--focus card-mat" + (ez ? " sw-fc--ez" : "") + (mob && !ez ? " sw-fc--mob" : "")}
         style={{ "--acc": b.acc, "--bi": idx, "--si": si, gridColumn: col, gridRow: row }}
         tabIndex={0} onMouseEnter={playCard} onMouseLeave={stopCard} onFocus={playCard} onBlur={stopCard}>
      <div className="sw-shot sw-shot--device">
        <div className="sw-scene">
          <div className="sw-desktop">{clip ? <DeskVid keyName={keyName} b={b} eager={ez} /> : <Desktop b={b} />}</div>
          {mob && <PhoneVid keyName={keyName} eager={ez} />}
        </div>
      </div>
      <div className="sw-meta">
        <span className="sw-name">{b.name}</span>
        <span className="sw-cat">{b.cat}</span>
      </div>
      <About b={b} open={ez} />
    </div>
  );
}

function AsideCard({ keyName, si }) {
  const b = SW_BRANDS[keyName];
  const clip = SW_CLIP.has(keyName);
  return (
    <div className="sw-card sw-aside-card" style={{ "--acc": b.acc, "--si": si }}
         tabIndex={0} onMouseEnter={playCard} onMouseLeave={stopCard} onFocus={playCard} onBlur={stopCard}>
      <div className="sw-shot">
        <div className="sw-desktop">{clip ? <DeskVid keyName={keyName} b={b} /> : <Desktop b={b} />}</div>
      </div>
      <div className="sw-meta">
        <span className="sw-name">{b.name}</span>
        <span className="sw-cat">{b.cat}</span>
      </div>
    </div>
  );
}

function Showcase() {
  const headRef = useReveal();
  const bandRef = useReveal();
  const ctaRef = useReveal();

  // EZ-Raider plays automatically whenever the showcase is on screen. Uses scroll + a timeout
  // safety net in addition to IntersectionObserver, so it still works where IO is throttled.
  useEffect(() => {
    syncEz();
    const onScroll = () => syncEz();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    const timers = [setTimeout(syncEz, 400), setTimeout(syncEz, 1200), setTimeout(syncEz, 2400)];
    let io;
    if ("IntersectionObserver" in window) {
      const ez = document.querySelector(".sw-fc--ez");
      if (ez) { io = new IntersectionObserver(syncEz, { threshold: [0, 0.25, 0.5] }); io.observe(ez); }
    }
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
      timers.forEach(clearTimeout);
      if (io) io.disconnect();
    };
  }, []);

  // On phones there is no hover, so the video of whichever card sits nearest the
  // vertical centre of the viewport plays; the rest pause + rewind. EZ-Raider is
  // first, so it starts and loops, then each site plays as it scrolls to centre.
  useEffect(() => {
    const focus = document.querySelector(".sw-focus");
    if (!focus) return;
    const cards = Array.from(focus.querySelectorAll(".sw-card"));
    let current = null, raf = 0;
    const playVids = (c) => c && c.querySelectorAll("video").forEach((v) => { const p = v.play(); if (p && p.catch) p.catch(() => {}); });
    const stopVids = (c) => c && c.querySelectorAll("video").forEach((v) => { v.pause(); try { v.currentTime = 0; } catch (_) {} });
    const pick = () => {
      raf = 0;
      if (!swIsMobile()) return; // desktop keeps its hover behaviour
      const vh = window.innerHeight || document.documentElement.clientHeight;
      const mid = vh / 2;
      let best = null, bestD = Infinity;
      cards.forEach((c) => {
        const r = c.getBoundingClientRect();
        if (r.bottom < vh * 0.1 || r.top > vh * 0.9) return; // not meaningfully on screen
        const d = Math.abs((r.top + r.height / 2) - mid);
        if (d < bestD) { bestD = d; best = c; }
      });
      if (best !== current) { stopVids(current); current = best; playVids(current); }
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(pick); };
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    const timers = [setTimeout(pick, 300), setTimeout(pick, 1000)];
    pick();
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
      timers.forEach(clearTimeout);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  // subtle scroll-driven parallax: each card's screenshot drifts vertically at a
  // slightly different rate as the band moves through the viewport, so the work
  // feels alive without distracting from it.
  useEffect(() => {
    const reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduce) return;
    const band = document.querySelector(".sw-band");
    if (!band) return;
    const cards = Array.from(band.querySelectorAll(".sw-card"));
    // depth factor (px of travel): focus cards stay gentle and alternate so
    // neighbours separate; aside columns drift a touch more for layered depth.
    cards.forEach((c, i) => {
      const aside = c.classList.contains("sw-aside-card");
      c.dataset.par = aside ? (i % 2 ? 46 : 34) : (i % 2 ? 30 : 18);
    });
    let raf = 0;
    const apply = () => {
      raf = 0;
      const mid = window.innerHeight / 2;
      cards.forEach((c) => {
        const r = c.getBoundingClientRect();
        if (r.bottom < -200 || r.top > window.innerHeight + 200) return;
        const center = r.top + r.height / 2;
        const progress = (center - mid) / window.innerHeight; // ~ -0.5 .. 0.5
        const f = parseFloat(c.dataset.par) || 0;
        c.style.setProperty("--par", (progress * f).toFixed(2) + "px");
      });
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(apply); };
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    apply();
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);
  return (
    <section id="showcase" className="section showcase-sec">
      <div className="haze-bloom" aria-hidden="true" />
      <div className="wrap">
        <div ref={headRef} className="reveal sw-head">
          <div>
            <div className="eyebrow"><span className="dot" />Our Work</div>
            <h2 className="h-section" style={{ maxWidth: 640 }}>
              Real websites for businesses that need to look as good as they are.
            </h2>
            <p className="p-lead">
              Siteworks is built on years of Taurist website, UX, and conversion work. We have helped businesses turn unclear, outdated, or underbuilt websites into sharper digital surfaces that explain the offer, build trust, and make the next step easier to take.
            </p>
          </div>
          <div className="sw-head-aside">
            <div className="sw-stat">
              <div className="sw-stat__num"><CountUp to={127} /><span>+</span></div>
              <div className="sw-stat__lbl">Websites and pages launched</div>
            </div>
            <div className="sw-stat">
              <div className="sw-stat__num"><CountUp to={7} /><span> years</span></div>
              <div className="sw-stat__lbl">Website and conversion experience</div>
            </div>
            <div className="sw-stat">
              <div className="sw-stat__num"><CountUp to={5} /><span>-star</span></div>
              <div className="sw-stat__lbl">Reviewed by clients</div>
            </div>
            <div className="sw-stat">
              <div className="sw-stat__num"><CountUp to={24} /><span> hours</span></div>
              <div className="sw-stat__lbl">First-page design before we meet</div>
            </div>
          </div>
        </div>

      </div>

      <div className="sw-band" ref={bandRef}>
        <div className="sw-aside sw-aside--left">
          <div className="sw-aside-inner"><div className="sw-aside-track">
            {SW_ASIDE_L.map((k, i) => <AsideCard key={k} keyName={k} si={i} />)}
          </div></div>
        </div>
        <div className="sw-aside sw-aside--right">
          <div className="sw-aside-inner"><div className="sw-aside-track">
            {SW_ASIDE_R.map((k, i) => <AsideCard key={k} keyName={k} si={i + 4} />)}
          </div></div>
        </div>
        <div className="wrap">
          <div className="sw-focus">
            {SW_FOCUS.map((f, i) => <FocusCard key={f.k} keyName={f.k} col={f.col} row={f.row} idx={i} si={f.si} />)}
          </div>
        </div>
      </div>

      <div className="wrap">
        <div ref={ctaRef} className="reveal sw-foot-cta">
          <h3 className="sw-foot-h">Your turn — send your site and see what your homepage can be in <span className="gradient-text">24 hours.</span></h3>
          <div className="sw-foot-actions">
            <a href="#cta" className="btn btn-primary">Get my homepage prototype <i className="ri-arrow-right-line" /></a>
            <a href="#review" className="btn btn-secondary">See pricing</a>
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { Showcase });
