/* ============================================================
 * Integration catalogue
 * ============================================================
 *
 * THIS FILE IS SERVED PUBLICLY. Everything under this directory is
 * fetchable as source — /preview/homepage-v3/src/*.jsx returns 200 with
 * content-type text/jsx. Treat every comment here as published copy.
 * Rationale, exclusions and anything commercially sensitive belong in
 * docs/integrations-catalogue-provenance.md, which is not served.
 *
 * Generated from the integrations platform database and the GuestMaker
 * codebase. Do not hand-edit entries in; see the provenance doc for how
 * the list is derived and what must not be added to it.
 *
 * `liveBrands` — hotel brands connected in production.
 * `connectors` — technical connectors behind one vendor card.
 * `description` — null where we have no verified description. Those
 *   cards render as name + category + region rather than invented copy.
 * `logo` resolves to assets/logos/<slug>.svg|png.
 */

const INTEGRATION_CATEGORIES = [
  { id: "pms", label: "PMS" },
  { id: "booking-engine", label: "Booking engine" },
  { id: "crs", label: "CRS & channel" },
  { id: "channels", label: "Messaging channels" },
  { id: "email", label: "Email" },
  { id: "voice", label: "Voice & telephony" },
  { id: "checkin", label: "Online check-in" },
  { id: "loyalty", label: "Loyalty & wallets" },
  { id: "reviews", label: "Reviews & feedback" },
  { id: "guest-app", label: "Guest experience" },
  { id: "ads", label: "Advertising" },
  { id: "payments", label: "Payments" },
  { id: "developer", label: "Developer" },
];

/* `status` is deliberately visible on the card:
 *   "live"      — running in production for real hotels today
 *   "available" — built and callable, nobody has switched it on yet
 * Notion and HubSpot both publish status metadata and it reads as
 * candour, not weakness. The alternative — quietly calling everything
 * "integrated" — is how the homepage ended up claiming Apaleo. */

/* Logo files on the CDN. Extensions vary (svg where the vendor publishes
 * one, png/webp/gif otherwise), so the filename is recorded rather than
 * guessed. Anything absent here renders as a monogram tile — that is a
 * supported state, not a bug. Three entries currently have no usable
 * asset: Hotel Line and Slack simply haven't been sourced yet; iTrip's
 * real domain (itrip.mx) has since been squatted by an unrelated site and
 * its SOAP backend host (dorothyts.com) is a bare, unbranded directory
 * listing — there is no live public asset to source for it.
 * Assets live on R2 per guardrail #560, never in git. */
/* Bump when a logo file is replaced. Assets are served with a long
 * max-age, so without this a re-uploaded logo keeps serving the old
 * bytes from cache and looks like the upload silently failed. */
const LOGO_VERSION = "7";

const LOGO_FILES = {
  "123compareme": "123compareme.png",
  "aci-hotel": "aci-hotel.png",
  "apple-wallet": "apple-wallet.png",
  "autocheckin": "autocheckin.png",
  "avalon": "avalon.svg",
  "bookingcore": "bookingcore.png",
  "bookinweb": "dingus.png",
  "civitfun": "civitfun.png",
  "class-one": "class-one.png",
  "cloudbeds": "cloudbeds.svg",
  "deversor": "deversor.png",
  "df-sistemes": "df-sistemes.png",
  "dingus": "dingus.png",
  "easygoband": "easygoband.png",
  "engisoft": "engisoft.svg",
  "front-hotel": "front-hotel.png",
  "gmail": "gmail.svg",
  "google-ads": "google-ads.svg",
  "guest-hotel": "guest-hotel.png",
  "hestia": "hestia.png",
  "host": "host.png",
  "hoteliga": "hoteliga.png",
  "hotetec": "hotetec.png",
  "impala": "impala.png",
  "lean": "lean.png",
  "master-yields": "master-yields.svg",
  "meta-ads": "meta-ads.svg",
  "mews": "mews.svg",
  "mews-be": "mews.svg",
  "millenium": "millenium.png",
  "mirai": "mirai.png",
  "neobookings": "neobookings.png",
  "new-hotel": "new-hotel.png",
  "noray": "noray.svg",
  "openroom": "openroom.svg",
  "opera": "opera.png",
  "orbook": "orbook.png",
  "outlook": "outlook.svg",
  "paraty": "paraty.svg",
  "prestige-soft": "prestige-soft.png",
  "quicktext": "quicktext.png",
  "quohotel": "quohotel.png",
  "reviewpro": "reviewpro.svg",
  "ringover": "ringover.svg",
  "roiback": "roiback.svg",
  "sihot": "sihot.svg",
  "stay-app": "stay-app.png",
  "stripe": "stripe.png",
  "suite-pms": "suite-pms.png",
  "tca-innsist": "tca-innsist.png",
  "tecsoft": "tecsoft.png",
  "timon": "timon.png",
  "travelclick": "travelclick.svg",
  "trustyou": "trustyou.svg",
  "ulyses": "ulyses.png",
  "winhotel": "winhotel.png",
  "witbooking": "witbooking.png",
};

const INTEGRATIONS = [
  /* ---------------------------------------------------------- PMS */
  { slug: "avalon", name: "Avalon", vendor: "Antfor Software", category: "pms", region: "Spain", website: "https://www.antfor.com/", liveBrands: 280, connectors: 1, hotels: "500+",
    description: "Cloud PMS with an open web API for booking and finance data. Based in Palma, Mallorca." },
  { slug: "noray", name: "Noray", vendor: "Noray (Consultores Canarios de Informática)", category: "pms", region: "Spain", website: "https://www.noray.com/", liveBrands: 95, connectors: 4,
    description: "PMS built on Microsoft Dynamics 365 Business Central. Cloud and on-premise, both connected." },
  { slug: "sihot", name: "SIHOT 360", vendor: "Gubse AG", category: "pms", region: "Germany", website: "https://sihot.com/", liveBrands: 64, connectors: 1, hotels: "3500+",
    description: "German PMS suite. Reservation search and per-reservation detail over an authenticated session API." },
  { slug: "timon", name: "Timon", vendor: "Timón Hotel", category: "pms", region: "Spain", website: "https://timonhotel.com/", liveBrands: 60, connectors: 1, hotels: "8000+",
    description: "Spanish PMS with 30+ years in the market and a JSON REST API. Widely used across Spain and Latin America." },
  { slug: "aci-hotel", name: "ACI Hotel", vendor: null, category: "pms", region: null, website: null, liveBrands: 52, connectors: 1, description: null },
  { slug: "quohotel", name: "QuoHotel", vendor: "Quonext (CEI Europe)", category: "pms", region: "Spain", website: "https://www.quohotel.com/", liveBrands: 50, connectors: 2, hotels: "1000+",
    description: "PMS on Microsoft Dynamics 365 Business Central, with OData REST APIs." },
  { slug: "ulyses", name: "Ulyses Cloud", vendor: "Tesipro Solutions (Septeo Group)", category: "pms", region: "Spain", website: "https://www.tesipro.com/", liveBrands: 32, connectors: 2, hotels: "900+",
    description: "Cloud PMS for independent hotels and large chains, with an open API." },
  { slug: "winhotel", name: "Winhotel", vendor: "Winhotel Solution", category: "pms", region: "Spain", website: "https://winhotelsolution.com/", liveBrands: 17, connectors: 1, hotels: "500+",
    description: "Spanish PMS since 1994, with query, booking and statistics APIs. Based in Palma, Mallorca." },
  { slug: "hestia", name: "Hestia", vendor: "Grupo SIME", category: "pms", region: "Spain", website: null, liveBrands: 17, connectors: 2,
    description: "Spanish PMS supporting online check-in, passport scanning and payment processing." },
  { slug: "millenium", name: "Millenium", vendor: null, category: "pms", region: null, website: null, liveBrands: 15, connectors: 1, description: null },
  { slug: "tecsoft", name: "Tecsoft HOTEC", vendor: "Tec-Soft", category: "pms", region: "Spain", website: "https://tec-soft.es/", liveBrands: 15, connectors: 1, hotels: "300+",
    description: "HOTEC PMS, in the market since 1989, covering reservations, billing and guest services." },
  { slug: "df-sistemes", name: "DF Sistemes", vendor: "DF Sistemes", category: "pms", region: "Spain", website: null, liveBrands: 14, connectors: 1,
    description: "Spanish PMS with a REST API carrying reservations and nested guest data." },
  { slug: "new-hotel", name: "New Hotel", vendor: null, category: "pms", region: null, website: null, liveBrands: 14, connectors: 2, description: null },
  { slug: "mews", name: "Mews", vendor: "Mews Systems", category: "pms", region: "Europe", website: "https://www.mews.com/", liveBrands: 9, connectors: 1, hotels: "5000+",
    description: "Cloud-native PMS. Connected through the Mews Connector API for reservation and guest sync." },
  { slug: "hoteliga", name: "Hoteliga", vendor: "Hoteliga", category: "pms", region: "Spain", website: "https://www.hoteliga.com/", liveBrands: 9, connectors: 1,
    description: "Cloud PMS with documented reservation, guest and availability endpoints." },
  { slug: "opera", name: "Opera Cloud", vendor: "Oracle Hospitality", category: "pms", region: "Global", website: "https://www.oracle.com/hospitality/", liveBrands: 7, connectors: 1, hotels: "40000+",
    description: "Connected through the Oracle Hospitality Integration Platform (OHIP)." },
  { slug: "engisoft", name: "Engisoft BIRD", vendor: "EngiSoft", category: "pms", region: "Spain", website: "https://engisofthotel.com/", liveBrands: 5, connectors: 1,
    description: "BIRD PMS, configurable from independent hotels through to international chains." },
  { slug: "class-one", name: "Class One", vendor: null, category: "pms", region: null, website: null, liveBrands: 3, connectors: 1, description: null },
  { slug: "guest-hotel", name: "Guest Hotel", vendor: null, category: "pms", region: null, website: null, liveBrands: 3, connectors: 1, description: null },
  { slug: "hotel-line", name: "Hotel Line", vendor: null, category: "pms", region: null, website: null, liveBrands: 3, connectors: 1, description: null },
  { slug: "prestige-soft", name: "Prestige Soft", vendor: "Prestige Hospitality Solutions", category: "pms", region: "Spain", website: "https://prestige-soft.com/", liveBrands: 3, connectors: 1, hotels: "1000+",
    description: "Barcelona-based PMS with an open API and no per-connection charge." },
  { slug: "deversor", name: "Deversor Cloud", vendor: null, category: "pms", region: null, website: null, liveBrands: 2, connectors: 1, description: null },
  { slug: "cloudbeds", name: "Cloudbeds", vendor: "Cloudbeds", category: "pms", region: "Global", website: "https://www.cloudbeds.com/", liveBrands: 1, connectors: 2, hotels: "22000+",
    description: "Hospitality management platform, connected for reservations, guests, rooms and payments." },
  { slug: "master-yields", name: "Master Yields", vendor: null, category: "pms", region: null, website: null, liveBrands: 1, connectors: 1, description: null },
  { slug: "tca-innsist", name: "TCA Innsist", vendor: "TCA Software Solutions", category: "pms", region: "Spain", website: "https://www.tcass.com/", liveBrands: 1, connectors: 1, hotels: "1000+",
    description: "Hospitality software house with 35+ years in the market, OTA/GDS/CRS compliant." },
  { slug: "host", name: "Host", vendor: "Host Hotel Systems", category: "pms", region: "Portugal", website: null, liveBrands: 0, connectors: 1,
    description: "Leading PMS in the Portuguese market." },
  { slug: "front-hotel", name: "Front Hotel", vendor: null, category: "pms", region: null, website: null, liveBrands: 0, connectors: 1, description: null },
  { slug: "suite-pms", name: "Suite PMS", vendor: null, category: "pms", region: null, website: null, liveBrands: 0, connectors: 1, description: null },
  { slug: "lean", name: "Lean Hotel System", vendor: "Chapp Solutions (Zucchetti Group)", category: "pms", region: "Spain", website: "https://leanhotelsystem.com/", liveBrands: 0, connectors: 1,
    description: "Cloud PMS with an open API on its enterprise plan." },
  { slug: "impala", name: "Impala", vendor: "Impala", category: "pms", region: "UK", website: "https://www.getimpala.com/", liveBrands: 0, connectors: 1,
    description: "Hotel API platform for guest data and reservations." },

  /* ----------------------------------------------- Booking engines */
  { slug: "neobookings", name: "Neobookings", vendor: "Neobookings", category: "booking-engine", region: "Spain", website: "https://www.neobookings.com/", liveBrands: 115, connectors: 1,
    description: "Booking engine with native MCP integration for AI agents and deep GA4 instrumentation." },
  { slug: "witbooking", name: "Witbooking", vendor: "Witbooking", category: "booking-engine", region: "Spain", website: "https://www.witbooking.com/", liveBrands: 57, connectors: 2,
    description: "Booking engine sending reservation webhooks across the commit, modify and cancel lifecycle." },
  { slug: "roiback", name: "Roiback", vendor: "Roiback", category: "booking-engine", region: "Spain", website: "https://www.roiback.com/", liveBrands: 56, connectors: 2, hotels: "2000+",
    description: "Booking engine and CRS handling 40M+ availability requests a day. Both are connected." },
  { slug: "paraty", name: "Paraty Tech", vendor: "Paraty Tech", category: "booking-engine", region: "Spain", website: "https://www.paratytech.com/", liveBrands: 11, connectors: 1, hotels: "3000+",
    description: "Booking engine built on in-house technology, with native flight and hotel packaging." },
  { slug: "mews-be", name: "Mews Booking Engine", vendor: "Mews Systems", category: "booking-engine", region: "Europe", website: "https://www.mews.com/", liveBrands: 3, connectors: 1,
    description: "Connected through the Mews Distributor API for availability search and booking creation." },
  { slug: "bookingcore", name: "BookingCore", vendor: null, category: "booking-engine", region: null, website: null, liveBrands: 0, connectors: 1, description: null },

  /* Copy here describes the OUTCOME only. How booking-engine
   * availability is obtained is competitively sensitive and must not be
   * described on a public page — see the provenance doc. */
  { slug: "mirai", name: "Mirai", vendor: "Mirai", category: "booking-engine", region: "Spain", website: "https://mirai.com/", liveBrands: null, connectors: 1,
    description: "Live availability and rates in the agent, plus a pre-filled deep link into the booking flow." },
  { slug: "hotetec", name: "Hotetec", vendor: "Hotetec", category: "booking-engine", region: "Spain", website: null, liveBrands: null, connectors: 1,
    description: "Live availability and rates in the agent, plus a pre-filled deep link into the booking flow." },
  { slug: "travelclick", name: "TravelClick iHotelier", vendor: "Amadeus", category: "booking-engine", region: "Global", website: "https://amadeus-hospitality.com/", liveBrands: null, connectors: 1,
    description: "Live availability and rates in the agent, plus a pre-filled deep link into the booking flow." },
  { slug: "openroom", name: "Openroom", vendor: null, category: "booking-engine", region: null, website: null, liveBrands: null, connectors: 1,
    description: "Live availability and rates in the agent, plus a pre-filled deep link into the booking flow." },
  { slug: "orbook", name: "ORBook", vendor: null, category: "booking-engine", region: null, website: null, liveBrands: null, connectors: 1,
    description: "Live availability and rates in the agent, plus a pre-filled deep link into the booking flow." },
  { slug: "bookinweb", name: "Bookinweb", vendor: null, category: "booking-engine", region: null, website: null, liveBrands: null, connectors: 1,
    description: "Live availability and rates in the agent, plus a pre-filled deep link into the booking flow." },
  { slug: "itrip", name: "iTrip", vendor: null, category: "booking-engine", region: null, website: null, liveBrands: null, connectors: 1,
    description: "Live availability and rates in the agent, plus a pre-filled deep link into the booking flow." },

  /* ------------------------------------------ Messaging channels */
  { slug: "whatsapp", name: "WhatsApp Business", vendor: "Meta", category: "channels", region: "Global", website: "https://business.whatsapp.com/", liveBrands: 18, connectors: 1, status: "live",
    description: "The hotel connects its own WhatsApp Business Account through Meta Embedded Signup. Two-way messaging, templates, media and delivery receipts." },
  { slug: "instagram", name: "Instagram", vendor: "Meta", category: "channels", region: "Global", website: "https://business.instagram.com/", liveBrands: 2, connectors: 1, status: "live",
    description: "Connect the hotel's Instagram Business account for direct messages and comment replies in the shared inbox." },
  { slug: "messenger", name: "Facebook Messenger", vendor: "Meta", category: "channels", region: "Global", website: "https://www.facebook.com/business/", liveBrands: 1, connectors: 1, status: "live",
    description: "Connect the hotel's Facebook Page for Messenger threads and comment replies." },
  { slug: "web-chat", name: "Website chat widget", vendor: null, category: "channels", region: "Global", website: null, liveBrands: 30, connectors: 1, status: "live",
    description: "One script tag on the hotel's own site renders the AI concierge, in chat or voice." },
  /* Not a partner integration — see docs/integrations-catalogue-provenance.md
   * "Competitors" section. Quicktext (now Quinta) is a competing hotel
   * chatbot; the only real code path is detect-and-replace during
   * onboarding, not a connection to their platform. Copy is written to
   * be honest about that. */
  { slug: "quicktext", name: "Quicktext", vendor: "Quinta (formerly Quicktext)", category: "channels", region: null, website: "https://www.quinta.im/", liveBrands: null, connectors: 1, status: "live",
    description: "Already running Quicktext (now Quinta) on your site? Onboarding detects it automatically and swaps it out cleanly for GuestMaker's own concierge." },

  /* -------------------------------------------------------- Email */
  { slug: "gmail", name: "Gmail & Google Workspace", vendor: "Google", category: "email", region: "Global", website: "https://workspace.google.com/", liveBrands: 1, connectors: 1, status: "live",
    description: "Connect a mailbox by OAuth. Mail arrives in real time, the AI drafts replies, and they send as that mailbox." },
  { slug: "outlook", name: "Microsoft 365 & Outlook", vendor: "Microsoft", category: "email", region: "Global", website: "https://www.microsoft.com/microsoft-365", liveBrands: 0, connectors: 1, status: "available",
    description: "Connect an Outlook or Microsoft 365 mailbox by OAuth, with real-time inbound over Microsoft Graph." },
  { slug: "imap", name: "IMAP & SMTP", vendor: null, category: "email", region: "Global", website: null, liveBrands: 1, connectors: 1, status: "live",
    description: "Any other mailbox, by host and password. Polled rather than pushed, so inbound is on a short delay." },
  { slug: "ses-domain", name: "Your own sending domain", vendor: "Amazon SES", category: "email", region: "Global", website: null, liveBrands: null, connectors: 1, status: "live",
    description: "Publish our DKIM and SPF records on the hotel's domain so campaigns send from its own brand, not ours." },

  /* --------------------------------------------- Voice & telephony */
  { slug: "ringover", name: "Ringover", vendor: "Ringover", category: "voice", region: "Europe", website: "https://www.ringover.com/", liveBrands: 0, connectors: 1, status: "available",
    description: "Screen pop, click-to-call, and call history with recordings on the guest's contact record." },
  { slug: "sip-transfer", name: "Transfer to your phone system", vendor: null, category: "voice", region: "Global", website: null, liveBrands: null, connectors: 1, status: "live",
    description: "The AI voice agent hands a live call to the hotel's real numbers over SIP, optionally briefing the staff member first." },

  /* ---------------------------------------------- Online check-in */
  { slug: "autocheckin", name: "Hotelinking Autocheckin", vendor: "Hotelinking", category: "checkin", region: "Spain", website: "https://www.hotelinking.com/", liveBrands: 6, connectors: 1, status: "live",
    description: "Per-reservation pre-arrival check-in links, sent as a merge tag in WhatsApp and email." },
  { slug: "civitfun", name: "Civitfun", vendor: "Civitfun", category: "checkin", region: "Spain", website: "https://www.civitfun.com/", liveBrands: 6, connectors: 1, status: "live",
    description: "Per-reservation pre-arrival check-in links, sent as a merge tag in WhatsApp and email." },

  /* ------------------------------------------- Loyalty & wallets */
  { slug: "loyalty-sso", name: "Loyalty sign-in for booking engines", vendor: null, category: "loyalty", region: "Spain", website: null, liveBrands: 2, connectors: 2, status: "live",
    description: "Guests sign in to the hotel's booking engine with their loyalty account. GuestMaker is the identity provider, live with Paraty Tech and Mirai." },
  { slug: "loyalty-credit", name: "Points as cash credit", vendor: null, category: "loyalty", region: "Global", website: null, liveBrands: null, connectors: 1, status: "live",
    description: "A drop-in script for the booking engine that lets members spend points as money against a direct booking." },
  { slug: "apple-wallet", name: "Apple Wallet", vendor: "Apple", category: "loyalty", region: "Global", website: "https://developer.apple.com/wallet/", liveBrands: null, connectors: 1, status: "live",
    description: "Members add a signed loyalty card to Apple Wallet." },

  /* -------------------------------------------------- Advertising */
  { slug: "google-ads", name: "Google Ads Customer Match", vendor: "Google", category: "ads", region: "Global", website: "https://ads.google.com/", liveBrands: null, connectors: 1, status: "live",
    description: "Connect the hotel's Google Ads account; marketing-consented segments sync as hashed Customer Match audiences." },
  { slug: "meta-ads", name: "Meta Custom Audiences", vendor: "Meta", category: "ads", region: "Global", website: "https://business.facebook.com/", liveBrands: 0, connectors: 1, status: "available",
    description: "Connect the hotel's Meta Ads account; marketing-consented segments sync as hashed custom audiences." },

  /* ----------------------------------------------------- Payments */
  { slug: "stripe", name: "Stripe", vendor: "Stripe", category: "payments", region: "Global", website: "https://stripe.com/", liveBrands: 0, connectors: 1, status: "available",
    description: "The hotel connects its own Stripe account; the sales agent issues checkout links for prepaid rates and card guarantees straight into it." },

  /* ---------------------------------------------------- Developer */
  { slug: "rest-api", name: "REST API", vendor: null, category: "developer", region: "Global", website: null, liveBrands: null, connectors: 1, status: "live",
    description: "Push reservations, guests, events and loyalty from any system with an issued API key." },
  { slug: "webhooks", name: "Outbound webhooks", vendor: null, category: "developer", region: "Global", website: null, liveBrands: null, connectors: 1, status: "live",
    description: "Register an HTTPS endpoint and receive signed GuestMaker events, with automatic retry." },
  { slug: "mcp", name: "MCP server", vendor: null, category: "developer", region: "Global", website: null, liveBrands: null, connectors: 1, status: "live",
    description: "An OAuth-authenticated MCP endpoint exposing contacts, reservations and campaign analytics as tools to any AI client." },
  { slug: "slack", name: "Slack", vendor: "Slack", category: "developer", region: "Global", website: "https://slack.com/", liveBrands: null, connectors: 1, status: "live",
    description: "Paste an incoming-webhook URL to get live-chat handoffs and alerts in the hotel's own workspace." },
  { slug: "conversion-tag", name: "Conversion tracking tag", vendor: null, category: "developer", region: "Global", website: null, liveBrands: null, connectors: 1, status: "live",
    description: "A first-party tag on the booking engine that attributes real bookings back to the campaign that caused them." },

  /* ------------------------------------------------ CRS & channel */
  { slug: "dingus", name: "Dingus", vendor: null, category: "crs", region: "Spain", website: null, liveBrands: 0, connectors: 1, description: null },

  /* ------------------------------------------ Reviews & feedback */
  { slug: "reviewpro", name: "ReviewPro", vendor: "Shiji Group", category: "reviews", region: "Global", website: "https://reviewpro.shijigroup.com/", liveBrands: 62, connectors: 1, hotels: "90000+",
    description: "Guest feedback platform with direct-response APIs for Google and Booking.com reviews." },
  { slug: "trustyou", name: "TrustYou", vendor: "TrustYou", category: "reviews", region: "Germany", website: "https://www.trustyou.com/", liveBrands: 0, connectors: 1,
    description: "Guest feedback and reputation platform." },
  { slug: "123compareme", name: "123COMPARE.ME", vendor: "123COMPARE.ME", category: "reviews", region: "Spain", website: "https://123compare.me/en/", liveBrands: 0, connectors: 1, status: "available",
    description: "Rate parity monitoring and booking-engine conversion tools, so direct stays the cheapest option across OTAs and metasearch." },

  /* ---------------------------------------------- Guest experience */
  { slug: "stay-app", name: "STAY App", vendor: "STAY", category: "guest-app", region: "Spain", website: "https://www.stay-app.com/", liveBrands: 74, connectors: 2,
    description: "Guest experience app covering room service, feedback and messaging." },
  { slug: "easygoband", name: "Goguest", vendor: "Easygoband", category: "guest-app", region: null, website: null, liveBrands: 4, connectors: 2, description: null },
];

/* These are consumed by page-integrations.jsx and section-integrations.jsx.
 * The babel scripts share one global scope so a bare `const` already works,
 * but assigning to window makes the contract explicit — and matches how every
 * other file here publishes itself. */
window.INTEGRATIONS = INTEGRATIONS;
window.INTEGRATION_CATEGORIES = INTEGRATION_CATEGORIES;
window.LOGO_FILES = LOGO_FILES;
window.LOGO_VERSION = LOGO_VERSION;
