// MostlyRender — competitor comparison pages. One reusable, data-driven page that
// powers /Compare (vs Bannerbear, the flagship) plus a per-competitor "<X> alternative"
// page at /Compare/<slug>. The Plausible move: concede each competitor's genuine
// strengths, then anchor every difference in a measurable fact. SEO: each page targets
// the high-intent "<competitor> alternative" query; the others are cross-linked at the
// bottom so the set reinforces itself. Facts sourced from draft/bannerbear competitor
// analysis (9 June 2026) — keep in sync with billing.config / seo.config.
const { Button: BtnCM, Badge: BadgeCM, Card: CardCM, CardBody: CardBodyCM } = MR_F;

// Display order for the "More comparisons" grid + the route slugs (= COMPETITORS keys).
const COMPARE_ORDER = ["bannerbear", "placid", "apitemplate", "htmlcsstoimage", "robolly", "templated", "abyssale"];

const COMPETITORS = {
  bannerbear: {
    name: "Bannerbear", logo: "B", route: "compare",
    tagline: "10× the renders at $49 — and no hard cap.",
    lead: "Bannerbear is a genuinely good product — mature, well-documented, trusted by thousands. Here’s where we differ, stated as facts, so you can decide for your own workload.",
    strong: "It’s been refining its editor since 2020, ships a large library of presets, and has years of edge cases ironed out. If you want the most mature template editor on the market today, that’s Bannerbear — and we’ll say so.",
    wedge: [
      { lbl: "The difference that matters most", big: "10,000 vs 1,000", sub: "included renders at the same $49/mo tier" },
      { lbl: "And at the limit", big: "Bill, don’t block", alt: true, sub: "we charge overage at the same rate; capped tools stop rendering until you upgrade" },
    ],
    rows: [
      { f: "Included renders at $49/mo", us: "10,000", them: "1,000", fact: true },
      { f: "Behaviour at the quota", us: "Overage billed, renders continue", them: "Renders blocked until upgrade", fact: true },
      { f: "Overage rate", us: "$4 / 1,000 — same as included", them: "Upgrade to next tier", fact: true },
      { f: "Projected-overage meter", us: true, them: false },
      { f: "n8n integration", us: true, them: false },
      { f: "Google Sheets (native)", us: true, them: "Via Zapier", fact: true },
      { f: "Video rendering", us: true, them: true },
      { f: "PDF rendering", us: true, them: true },
      { f: "Free tier", us: "100 / mo", them: "30 (trial)", fact: true },
      { f: "Template editor maturity", us: "Newer — fewer presets", them: "Deep, battle-tested", win: "them" },
      { f: "Years in market", us: "Newer entrant", them: "Since 2020", win: "them", fact: true },
    ],
    catchup: "We’re a newer entrant. Our editor has fewer ready-made presets, and we don’t yet match Bannerbear’s breadth of niche template features. If your team needs the deepest editor today, that’s a fair reason to choose them. If you need headroom on volume and a meter that never slams shut, that’s us.",
  },

  placid: {
    name: "Placid", logo: "P", route: "compare/placid",
    tagline: "4× the renders at $19, and we never block.",
    lead: "Placid is a polished, design-led product. Here’s where we differ — stated as facts — so you can decide for your own workload.",
    strong: "Placid has one of the most design-refined editors in the category. If pixel-perfect marketing visuals are your top priority, it’s excellent — and we’ll say so.",
    wedge: [
      { lbl: "Same $19 entry tier", big: "2,000 vs 500", sub: "included renders per month at the same entry price" },
      { lbl: "And at the limit", big: "Bill, don’t block", alt: true, sub: "we bill overage and keep rendering; Placid blocks renders at the cap" },
    ],
    rows: [
      { f: "Included renders at $19/mo", us: "2,000", them: "500", fact: true },
      { f: "Behaviour at the quota", us: "Overage billed, renders continue", them: "Renders blocked", fact: true },
      { f: "Free tier", us: "100 / mo, forever", them: "Trial only", fact: true },
      { f: "Published overage rate", us: "$5 / 1,000 (Starter)", them: "Upgrade tiers", fact: true },
      { f: "Projected-overage meter", us: true, them: false },
      { f: "Python & Go SDKs", us: true, them: "Under-advertised", win: "them" },
      { f: "Video rendering", us: true, them: true },
      { f: "PDF rendering", us: true, them: true },
      { f: "n8n integration", us: true, them: false },
      { f: "Editor design polish", us: "Newer", them: "Highly refined", win: "them" },
    ],
    catchup: "We’re newer, and our editor has fewer presets and less design polish than Placid’s. If the deepest design tooling matters most to you today, that’s a fair reason to choose them. If you want 4× the volume at the same price and a meter that never slams shut, that’s us.",
  },

  apitemplate: {
    name: "APITemplate.io", logo: "A", route: "compare/apitemplate",
    tagline: "Published overage and double the free tier.",
    lead: "APITemplate.io is a capable, developer-friendly product. Here’s where we differ — stated as facts — so you can decide for your own workload.",
    strong: "APITemplate.io ships more first-party SDK languages today (Python, C#, Java, PHP, JS) and a low entry price. If you need a specific SDK we don’t offer yet, that’s a real point in its favour.",
    wedge: [
      { lbl: "Overage you can see", big: "Published vs not", sub: "every paid tier has a published $/1,000 rate; APITemplate’s overage isn’t on the page" },
      { lbl: "Free tier", big: "100 vs 50", alt: true, sub: "free renders every month, forever — twice the headroom to build" },
    ],
    rows: [
      { f: "Free tier", us: "100 / mo, forever", them: "50 / mo", fact: true },
      { f: "Published overage rate", us: "$4–$5 / 1,000", them: "Not published", fact: true },
      { f: "Behaviour at the quota", us: "Overage billed, renders continue", them: "Not published", fact: true },
      { f: "Included renders (entry paid tier)", us: "2,000 at $19", them: "1,500 at $35", fact: true },
      { f: "Projected-overage meter", us: true, them: false },
      { f: "Video rendering", us: true, them: false, fact: true },
      { f: "PDF rendering", us: true, them: true },
      { f: "First-party SDK languages", us: "Python, Go", them: "Python, C#, Java, PHP, JS", win: "them", fact: true },
    ],
    catchup: "APITemplate currently offers more first-party SDK languages than our Python and Go. If you need a C#, Java or PHP library today, factor that in. Where we win is transparency — a published overage rate and a meter — plus video and double the free tier.",
  },

  htmlcsstoimage: {
    name: "HTMLCSStoImage", logo: "H", route: "compare/htmlcsstoimage",
    tagline: "A real visual editor, not just HTML.",
    lead: "HTMLCSStoImage (HCTI) is a clean, developer-loved product. Here’s where we differ — stated as facts — so you can decide for your own workload.",
    strong: "HCTI is the cheapest way in at $14, and a joy if you already author your templates as raw HTML/CSS. For a pure HTML-to-image endpoint with no editor, it’s hard to beat on price.",
    wedge: [
      { lbl: "Design without writing markup", big: "Editor vs none", sub: "a visual template editor and reusable templates — not just hand-written HTML/CSS" },
      { lbl: "Overage rate", big: "$4 vs $10", alt: true, sub: "per 1,000 renders — and we still render raw HTML/CSS when you want to" },
    ],
    rows: [
      { f: "Visual template editor", us: true, them: false, fact: true },
      { f: "Render from raw HTML/CSS", us: true, them: true },
      { f: "Entry price", us: "$19 / 2,000", them: "$14 / 1,000", win: "them", fact: true },
      { f: "Free tier", us: "100 / mo", them: "50 / mo", fact: true },
      { f: "Overage rate", us: "$4 / 1,000", them: "$10 / 1,000", fact: true },
      { f: "Video rendering", us: true, them: false, fact: true },
      { f: "PDF rendering", us: true, them: true },
      { f: "No-code integrations", us: "Zapier, Make, n8n, Sheets", them: "Limited", fact: true },
    ],
    catchup: "HCTI is cheaper at the entry tier and purpose-built for raw HTML/CSS with no editor — if that’s all you need, it’s a clean fit. We win when you want a visual editor, video, native no-code integrations, and a far lower overage rate.",
  },

  robolly: {
    name: "Robolly", logo: "R", route: "compare/robolly",
    tagline: "A forever free tier and official SDKs.",
    lead: "Robolly is a slick, motion-friendly product. Here’s where we differ — stated as facts — so you can decide for your own workload.",
    strong: "Robolly’s animated and video template presets are genuinely polished. If motion creatives are central to your work, it’s a strong option.",
    wedge: [
      { lbl: "Try before you commit", big: "Free vs trial", sub: "100 renders every month, forever — not a 7-day trial that expires" },
      { lbl: "Developer access", big: "SDKs vs none", alt: true, sub: "official Python & Go libraries; Robolly ships no first-party SDKs" },
    ],
    rows: [
      { f: "Free tier", us: "100 / mo, forever", them: "7-day trial", fact: true },
      { f: "First-party SDKs", us: "Python, Go", them: "None", fact: true },
      { f: "Published overage rate", us: "$4–$5 / 1,000", them: "Not published", fact: true },
      { f: "Behaviour at the quota", us: "Overage billed, renders continue", them: "Not published", fact: true },
      { f: "Included renders (entry tier)", us: "2,000 at $19", them: "250–1,000 at $39", fact: true },
      { f: "Projected-overage meter", us: true, them: false },
      { f: "Video rendering", us: true, them: true },
      { f: "Animated / motion templates", us: "Basic", them: "Polished", win: "them" },
    ],
    catchup: "Robolly’s motion and video template presets are more polished than ours today. If animated creatives are your core use case, weigh that. We win on a real free tier, official SDKs, and pricing you can actually see.",
  },

  templated: {
    name: "Templated.io", logo: "T", route: "compare/templated",
    tagline: "Monthly billing and no halt at the cap.",
    lead: "Templated.io is a capable, well-built product. Here’s where we differ — stated as facts — so you can decide for your own workload.",
    strong: "Templated.io has broad first-party SDK coverage (Python, Node, Java, PHP, Ruby) and a clean, capable editor. If you prepay annually, its headline price is low.",
    wedge: [
      { lbl: "Pay how you want", big: "Monthly vs annual", sub: "real monthly billing; Templated advertises annual-only pricing" },
      { lbl: "And at the limit", big: "Bill vs halt", alt: true, sub: "we bill overage and keep rendering; Templated halts rendering at the cap" },
    ],
    rows: [
      { f: "Monthly billing", us: true, them: "Annual-only display", fact: true },
      { f: "Behaviour at the quota", us: "Overage billed, renders continue", them: "Rendering halts", fact: true },
      { f: "Free tier", us: "100 / mo, forever", them: "50 trial credits", fact: true },
      { f: "Included renders", us: "2,000 at $19", them: "1,000 at $29 (annual)", fact: true },
      { f: "Published overage rate", us: "$4–$5 / 1,000", them: "$179 / 25k tier", fact: true },
      { f: "Projected-overage meter", us: true, them: false },
      { f: "Video rendering", us: true, them: true },
      { f: "First-party SDK languages", us: "Python, Go", them: "Python, Node, Java, PHP, Ruby", win: "them", fact: true },
    ],
    catchup: "Templated offers more first-party SDK languages, and if annual prepayment suits you its headline price is low. We win on flexible monthly billing, a real free tier, and a meter that bills overage instead of halting your renders.",
  },

  abyssale: {
    name: "Abyssale", logo: "A", route: "compare/abyssale",
    tagline: "Flat pricing — no per-seat tax.",
    lead: "Abyssale is a strong product for ad-creative teams. Here’s where we differ — stated as facts — so you can decide for your own workload.",
    strong: "Abyssale’s multi-format ad-set batch generation is genuinely strong for agencies producing many sizes at once. If that’s your core workflow, it’s a real strength.",
    wedge: [
      { lbl: "How you’re charged", big: "Flat vs per-seat", sub: "one account price, however many people use it; Abyssale charges per seat" },
      { lbl: "Included renders", big: "2,000 vs 150", alt: true, sub: "our $19 account vs Abyssale’s $12 per-seat plan" },
    ],
    rows: [
      { f: "Pricing model", us: "Flat per-account", them: "Per-seat", fact: true },
      { f: "Included renders", us: "2,000 at $19 (flat)", them: "150 / seat at $12", fact: true },
      { f: "Free tier", us: "100 / mo, forever", them: "14-day trial", fact: true },
      { f: "First-party SDKs", us: "Python, Go", them: "None", fact: true },
      { f: "Behaviour at the quota", us: "Overage billed at $4–$5 / 1,000", them: "$0.01 / credit", fact: true },
      { f: "Projected-overage meter", us: true, them: false },
      { f: "Video rendering", us: true, them: true },
      { f: "Multi-format ad-set batches", us: "Basic", them: "Strong", win: "them" },
    ],
    catchup: "Abyssale’s batch ad-set generation across many formats is more mature than ours. For an agency churning out dozens of sizes, that matters. We win on flat (not per-seat) pricing, official SDKs, and a real free tier.",
  },
};

function Cell({ v, win }) {
  if (v === true) return <span className="cmp-yes"><Icon d="check" size={16} /></span>;
  if (v === false) return <span className="cmp-no"><Icon d="x" size={15} /></span>;
  return <span className={"cmp-val" + (win ? " cmp-val--muted" : "")}>{v}</span>;
}

function CompareTable({ go, data }) {
  return (
    <section className="cmp">
      <div className="mk-wrap">
        <div className="mk-section-head" style={{ marginBottom: 22 }}>
          <span className="mk-eyebrow">MostlyRender vs {data.name}</span>
          <h1 className="mk-h1" style={{ fontSize: 46 }}>The honest {data.name} alternative.</h1>
          <p className="mk-lead" style={{ marginInline: "auto", maxWidth: "36em" }}>{data.lead}</p>
        </div>

        {/* concede first — the trust move */}
        <div className="cmp-concede">
          <div className="cmp-concede__icon"><Icon d="check" size={20} /></div>
          <div>
            <div className="cmp-concede__t">Where {data.name} is genuinely strong</div>
            <p className="cmp-concede__d">{data.strong}</p>
          </div>
        </div>

        {/* the core difference, as a fact */}
        <div className="cmp-wedge">
          <div className="cmp-wedge__col">
            <div className="cmp-wedge__lbl">{data.wedge[0].lbl}</div>
            <div className="cmp-wedge__big">{data.wedge[0].big}</div>
            <div className="cmp-wedge__sub">{data.wedge[0].sub}</div>
          </div>
          <div className="cmp-wedge__div" />
          <div className="cmp-wedge__col">
            <div className="cmp-wedge__lbl">{data.wedge[1].lbl}</div>
            <div className={"cmp-wedge__big" + (data.wedge[1].alt ? " cmp-wedge__big--alt" : "")}>{data.wedge[1].big}</div>
            <div className="cmp-wedge__sub">{data.wedge[1].sub}</div>
          </div>
        </div>

        {/* the table */}
        <div className="cmp-table">
          <div className="cmp-table__head">
            <div className="cmp-table__feat">Feature</div>
            <div className="cmp-table__us"><RenderMark s={20} /> MostlyRender</div>
            <div className="cmp-table__them"><span className="intg-card__logo" style={{ width: 20, height: 20, borderRadius: 6, fontSize: 11, background: "var(--fg-subtle)" }}>{data.logo}</span> {data.name}</div>
          </div>
          {data.rows.map((r, i) => (
            <div className="cmp-table__row" key={i}>
              <div className="cmp-table__feat">{r.f}{r.fact && <span className="cmp-fact">fact</span>}</div>
              <div className="cmp-table__us"><Cell v={r.us} win={r.win === "them"} /></div>
              <div className="cmp-table__them"><Cell v={r.them} win={r.win !== "them" && r.them !== true} /></div>
            </div>
          ))}
        </div>

        {/* concede where we lose — the second trust move */}
        <div className="cmp-concede cmp-concede--alt">
          <div className="cmp-concede__icon cmp-concede__icon--warn"><Icon d="clock" size={20} /></div>
          <div>
            <div className="cmp-concede__t">Where we’re still catching up</div>
            <p className="cmp-concede__d">{data.catchup}</p>
          </div>
        </div>

        <div className="mk-cta__inner" style={{ marginTop: 44 }}>
          <h2 className="mk-h2">Try it on your own render volume.</h2>
          <p className="mk-lead" style={{ marginInline: "auto" }}>100 free renders a month. Bring a real workload and watch the meter — not a wall.</p>
          <div className="mk-hero__actions" style={{ justifyContent: "center" }}>
            <BtnCM variant="primary" size="lg" iconRight={<Icon d="arrow" size={16} />} onClick={() => go("app/editor")}>Start rendering free</BtnCM>
            <BtnCM variant="secondary" size="lg" onClick={() => go("pricing")}>See pricing</BtnCM>
          </div>
        </div>
      </div>
    </section>
  );
}

// The cross-link grid — every comparison except the one you're on. Real <a href>s so
// crawlers follow the set; onClick keeps it a same-origin SPA-style nav.
function MoreComparisons({ go, current }) {
  const others = COMPARE_ORDER.filter((k) => k !== current);
  const href = (k) => "/" + COMPETITORS[k].route.replace(/^compare/, "Compare");
  return (
    <section className="cmp-more">
      <div className="mk-wrap">
        <div className="mk-section-head" style={{ marginBottom: 22 }}>
          <span className="mk-eyebrow">More comparisons</span>
          <h2 className="mk-h2">See how MostlyRender stacks up</h2>
          <p className="mk-lead" style={{ marginInline: "auto", maxWidth: "34em" }}>Honest, fact-by-fact comparisons against the image-API tools teams evaluate most.</p>
        </div>
        <div className="cmp-more__grid">
          {others.map((k) => (
            <a key={k} className="cmp-more__card" href={href(k)} onClick={(e) => { e.preventDefault(); go(COMPETITORS[k].route); }}>
              <div className="cmp-more__top">
                <span className="cmp-more__name">MostlyRender vs {COMPETITORS[k].name}</span>
              </div>
              <p className="cmp-more__tag">{COMPETITORS[k].tagline}</p>
              <span className="cmp-more__cta">{COMPETITORS[k].name} alternative <Icon d="arrow" size={14} /></span>
            </a>
          ))}
        </div>
      </div>
    </section>
  );
}

function Compare({ go, competitor = "bannerbear" }) {
  const key = COMPETITORS[competitor] ? competitor : "bannerbear";
  return (
    <div className="mk-root">
      <window.MkNav go={go} />
      <CompareTable go={go} data={COMPETITORS[key]} />
      <MoreComparisons go={go} current={key} />
      <window.MkFooter go={go} />
    </div>
  );
}

window.Compare = Compare;
window.COMPARE_COMPETITORS = COMPARE_ORDER;
