/* global IconSpark, IconBrain, IconChannels, IconEngine, IconRoute, IconVoice, IconShield, IconClock, IconLayers, IconInfinity, IconLang, ChannelChip */

/* ============================================================
 * PRICING
 *
 * Structure and copy come from the Claude Design project
 * (019dfd84 · Pricing.html): hero + edition finder, three editions,
 * module catalogue, comparison matrix, an always-included band, how
 * scoping works, FAQ, CTA.
 *
 * It is PORTED, not pasted. The design ships its own system — Inter,
 * Source Serif 4, JetBrains Mono, a private token object and its own
 * KBNav/KBFooter. Dropping that in would put a second type stack and a
 * second navigation on the site, and the mega menu would vanish from this
 * page alone. So the layout and words are kept and rebuilt on the tokens
 * in styles.css, with the real SectionNav and SectionFooter.
 *
 * Content was re-curated against what GuestMaker actually ships. The
 * design was written without that knowledge and got several things wrong:
 *
 *  - Booking.com appeared as a channel. OTA messaging is real, but the
 *    homepage now presents SIX channels and a pricing page contradicting
 *    the page before it is worse than one that omits a channel. Six.
 *    (2026-08-16: the channel is now called OTA Messaging everywhere it
 *    appears, which is the naming this note was reaching for.)
 *  - Languages were tiered 6 / 24 / Any. Nothing in the product limits
 *    language by plan, and inventing a commercial fence is the kind of
 *    claim procurement holds you to. 60+ everywhere; editions differ on
 *    portfolio, governance and service, which is where they really differ.
 *  - Module names did not match the mega menu or the homepage cards. A
 *    visitor should meet the same nine names everywhere.
 * ============================================================ */

/* Editions were renamed from Studio / Group / Enterprise on 2026-08-12. The
   mega-menu footer line in section-nav.jsx was updated in the same commit —
   if you rename them again, that line has to move too, or the menu
   advertises editions this page does not have. */

/* ---------- hero configurator ---------- */

const SIZES = [
  { id: "single", label: "1 property", ed: "core" },
  { id: "small", label: "2 – 9", ed: "signature" },
  { id: "mid", label: "10 – 49", ed: "signature" },
  { id: "group", label: "50+", ed: "enterprise" },
];

/* The same six channels as the homepage cards, in the same order and under
   the same names. `kind` keys into channelIcon/channelHue/channelLabel. */
const CHANNELS = ["whatsapp", "meta", "webchat", "voice", "emailIn", "emailOut"];

const MODULE_CHIPS = [
  { id: "brain", label: "Hotel Brain", Ic: IconBrain },
  { id: "crm", label: "Agentic CRM", Ic: IconChannels },
  { id: "cdp", label: "CDP", Ic: IconLayers },
  { id: "voice", label: "Voice Agent", Ic: IconVoice },
  { id: "journeys", label: "Campaigns & Journeys", Ic: IconRoute },
  { id: "loyalty", label: "Loyalty", Ic: IconInfinity },
];

const EDITIONS = {
  core: { name: "Core", blurb: "One property, one brain, every guest channel." },
  signature: { name: "Signature", blurb: "A collection that shares knowledge and guests." },
  enterprise: { name: "Enterprise", blurb: "Group-wide governance, brands and regions." },
};

const PricingHero = () => {
  const [size, setSize] = useState("mid");
  const [chan, setChan] = useState(["whatsapp", "webchat", "emailIn"]);
  const [mods, setMods] = useState(["brain", "crm"]);
  const toggle = (arr, set, id) =>
    set(arr.includes(id) ? arr.filter((x) => x !== id) : [...arr, id]);

  const sz = SIZES.find((s) => s.id === size);
  const rec = sz.ed;
  const ed = EDITIONS[rec];

  return (
    <section className="section-pad pr-hero" id="pricing-hero">
      <div className="pr-hero-glow" aria-hidden="true" />
      <div className="container-wide pr-hero-grid">
        <div>
          <Reveal><div className="eyebrow">Pricing</div></Reveal>
          <Reveal delay={120}>
            <h1 className="h-1" style={{ marginTop: 24, maxWidth: 620 }}>
              Priced like a portfolio, <span className="italic-accent">not a seat count.</span>
            </h1>
          </Reveal>
          <Reveal delay={220}>
            <p className="lead" style={{ marginTop: 26, maxWidth: 520 }}>
              Every group is a different shape, properties, brands, channels, languages, systems. So we scope, we don&rsquo;t list. Take one module or take all nine, on a portfolio of one hotel or four hundred, and pay for the footprint you actually run.
            </p>
          </Reveal>
          <Reveal delay={300}>
            <div className="flex gap-3 wrap" style={{ marginTop: 32 }}>
              <a href={DEMO_URL} className="btn btn-primary">Talk to sales <IconArrow size={14} className="arrow" /></a>
              <a href="#compare" className="btn btn-ghost">Compare editions</a>
            </div>
          </Reveal>
          <Reveal delay={380}>
            <div className="pr-assur">
              {["No per-conversation surprises", "Unlimited guest volume", "Start with a single module"].map((t) => (
                <span key={t} className="pr-assur-item">
                  <IconCheck size={13} stroke={2} /> {t}
                </span>
              ))}
            </div>
          </Reveal>
        </div>

        <Reveal delay={200}>
          <div className="pr-finder">
            <div className="pr-finder-head">
              <IconSpark size={14} stroke={1.8} />
              <span className="pr-finder-title">Edition finder</span>
              <span style={{ flex: 1 }} />
              <span className="pr-finder-live">Live</span>
              <span className="pr-finder-dot" aria-hidden="true" />
            </div>

            <div className="pr-finder-body">
              <div>
                <div className="pr-label">Portfolio</div>
                <div className="pr-seg" role="group" aria-label="Portfolio size">
                  {SIZES.map((s) => (
                    <button
                      key={s.id}
                      type="button"
                      className={`pr-seg-btn ${size === s.id ? "on" : ""}`}
                      aria-pressed={size === s.id}
                      onClick={() => setSize(s.id)}
                    >{s.label}</button>
                  ))}
                </div>
              </div>

              <div>
                <div className="pr-label">Channels</div>
                <div className="pr-chips">
                  {CHANNELS.map((c) => (
                    <button
                      key={c}
                      type="button"
                      className={`pr-chip ${chan.includes(c) ? "on" : ""}`}
                      aria-pressed={chan.includes(c)}
                      onClick={() => toggle(chan, setChan, c)}
                    >
                      <ChannelChip kind={c} status={chan.includes(c) ? "primary" : "dim"} small />
                    </button>
                  ))}
                </div>
              </div>

              <div>
                <div className="pr-label">Modules</div>
                <div className="pr-chips">
                  {MODULE_CHIPS.map((m) => (
                    <button
                      key={m.id}
                      type="button"
                      className={`pr-chip pr-chip-mod ${mods.includes(m.id) ? "on" : ""}`}
                      aria-pressed={mods.includes(m.id)}
                      onClick={() => toggle(mods, setMods, m.id)}
                    >
                      <m.Ic size={13} stroke={1.8} /> {m.label}
                    </button>
                  ))}
                </div>
              </div>
            </div>

            <div className="pr-finder-foot">
              <div className="pr-rec">
                <div className="pr-rec-glow" aria-hidden="true" />
                <div className="pr-rec-top">
                  <div>
                    <div className="pr-rec-eyebrow">Recommended edition</div>
                    {/* keyed on `rec` so React remounts the node and the
                        entrance animation replays when it changes */}
                    <div key={rec} className="pr-rec-name">{ed.name}</div>
                    <div className="pr-rec-blurb">{ed.blurb}</div>
                  </div>
                  <span className="pr-rec-badge"><IconSpark size={11} stroke={2} /> SCOPED</span>
                </div>
                <div className="pr-rec-stats">
                  {[
                    ["properties", sz.label.replace(" property", "")],
                    ["channels", String(chan.length)],
                    ["modules", String(mods.length)],
                  ].map(([k, v]) => (
                    <div key={k}>
                      <div className="pr-rec-k">{k}</div>
                      <div className="pr-rec-v">{v}</div>
                    </div>
                  ))}
                  <span style={{ flex: 1 }} />
                  <a className="pr-rec-link" href="#editions">See what&rsquo;s included →</a>
                </div>
                <div className="pr-rec-foot">
                  Your edition follows the portfolio. Channels and modules are priced on their own, adding them never moves you up a tier.
                </div>
              </div>
            </div>
          </div>
        </Reveal>
      </div>
    </section>
  );
};

/* ---------- editions ---------- */

const PLANS = [
  {
    id: "core", name: "Core", tag: "Single property",
    line: "One hotel. One brain. Every guest channel it needs.",
    meta: ["1 property", "3 channels", "60+ languages"],
    basis: "Scoped per property",
    cta: "Talk to sales", ghost: true,
    groups: [
      { h: "Foundation", items: ["Hotel Brain knowledge base", "Website, PDF and menu crawling", "Semantic search in 60+ languages", "Gap Resolver with one-click publish"] },
      { h: "Conversations", items: ["WhatsApp, web chatbot, email inbox", "AI agent with human takeover", "Shared inbox, 5 seats"] },
      { h: "Run it", items: ["Email support, next business day", "Monthly performance digest", "Implementation quoted separately"] },
    ],
  },
  {
    id: "signature", name: "Signature", tag: "Collections · 2–49 hotels", featured: true,
    line: "A portfolio that shares one knowledge base and one guest record.",
    meta: ["Multi-property", "All six channels", "60+ languages"],
    basis: "Scoped per portfolio",
    cta: "Talk to sales",
    groups: [
      { h: "Everything in Core, plus", items: ["Group and property knowledge layers", "Inheritance with per-hotel overrides", "Multimodal photo search", "Append-only versioning and dedup"] },
      { h: "Conversations", items: ["Meta Socials, Instagram and Messenger", "Voice Agent, inbound and outbound", "Unlimited inbox seats, escalation routing", "Campaigns and visual journeys"] },
      { h: "Guest data", items: ["CDP with AI identity resolution", "Segments, guest stages and custom fields", "PMS and booking engine sync"] },
      { h: "Run it", items: ["Priority support, 4h first response", "Quarterly business review", "Implementation quoted separately"] },
    ],
  },
  {
    id: "enterprise", name: "Enterprise", tag: "50+ hotels · multi-brand",
    line: "Governance, brands, regions and the integrations you already run.",
    meta: ["Unlimited properties", "Custom channels", "60+ languages"],
    basis: "Scoped per group",
    cta: "Talk to sales", ghost: true,
    groups: [
      { h: "Everything in Signature, plus", items: ["Brand and region hierarchies", "Granular permissions and approval flows", "Loyalty with tiers, points and cash credit", "Agency accounts and unified billing"] },
      { h: "Platform", items: ["External API and outbound webhooks", "Custom connectors and middleware", "Data residency options, SSO / SAML", "Test Mode and production alerting"] },
      { h: "Run it", items: ["Dedicated success team", "99.9% uptime commitment", "Security review and DPA support", "Implementation quoted separately"] },
    ],
  },
];

const PlanCard = ({ p }) => (
  <article className={`pr-plan ${p.featured ? "featured" : ""}`}>
    {p.featured && (
      <div className="pr-plan-flag"><IconSpark size={11} stroke={2} /> Most chosen by groups</div>
    )}
    <div className="pr-plan-head">
      <div className="pr-plan-tag">{p.tag}</div>
      <div className="pr-plan-name">{p.name}</div>
      <p className="pr-plan-line">{p.line}</p>
      <div className="pr-plan-meta">
        {p.meta.map((m) => <span key={m}>{m}</span>)}
      </div>
      <div className="pr-plan-basis"><IconBuilding size={14} stroke={1.7} /> {p.basis}</div>
      <a href={DEMO_URL} className={`btn ${p.ghost ? "btn-ghost" : "btn-primary"} pr-plan-cta`}>
        {p.cta} <IconArrow size={14} className="arrow" />
      </a>
    </div>
    <div className="pr-plan-body">
      {p.groups.map((g) => (
        <div key={g.h}>
          <div className="pr-plan-gh">{g.h}</div>
          <ul className="pr-plan-list">
            {g.items.map((it) => (
              <li key={it}><IconCheck size={13} stroke={2.4} /><span>{it}</span></li>
            ))}
          </ul>
        </div>
      ))}
    </div>
  </article>
);

const PricingPlans = () => (
  <section className="section-pad pr-editions" id="editions">
    <div className="container-wide">
      <div className="pr-head">
        <Reveal><div className="eyebrow">Editions</div></Reveal>
        <Reveal delay={120}>
          <h2 className="h-1" style={{ marginTop: 24, maxWidth: 860 }}>
            Three shapes of <span className="italic-accent">the same platform.</span>
          </h2>
        </Reveal>
        <Reveal delay={220}>
          <p className="lead" style={{ marginTop: 26, maxWidth: 720 }}>
            Editions size the portfolio, how many properties, how deep the hierarchy, how far the integrations reach. They do not gate the modules: every module is available on every edition, and most can be bought on their own. Nothing is metered per conversation.
          </p>
        </Reveal>
      </div>

      <div className="pr-plan-grid">
        {PLANS.map((p, i) => (
          <Reveal key={p.id} delay={i * 90} className="pr-plan-cell"><PlanCard p={p} /></Reveal>
        ))}
      </div>

      <Reveal>
        <div className="pr-strip">
          <IconShield size={16} stroke={1.7} />
          <span className="pr-strip-main">Every edition includes unlimited guest conversations, unlimited knowledge entries and unlimited crawls.</span>
          <span style={{ flex: 1 }} />
          <span className="pr-strip-meta">Annual agreements · monthly available on Core</span>
        </div>
      </Reveal>
    </div>
  </section>
);

/* ---------- modules ---------- */

/* Names match the mega menu and the homepage explore cards exactly. A
   visitor meeting "Hotel CRM" here and "Agentic CRM" one page earlier has
   to work out whether they are the same product. */
const MODULES = [
  {
    id: "brain", name: "Hotel Brain", kind: "Knowledge", Ic: IconBrain, core: true,
    line: "The self-building knowledge layer every agent answers from.",
    feats: ["Website, PDF, menu and rate-sheet crawling", "Semantic search across 60+ languages", "Multimodal photo search", "Gap Resolver, unanswered becomes answered", "Append-only versioning with auto-supersede", "KB Studio, manage it by talking"],
  },
  {
    id: "crm", name: "Agentic CRM", kind: "Conversations", Ic: IconChannels,
    line: "One inbox for every channel, with AI on the first line.",
    feats: ["WhatsApp, web chatbot, Meta Socials, email", "AI agent with human takeover", "Escalation routing to the right department", "Inline translation, both directions", "Guest memories carried across stays"],
  },
  {
    id: "cdp", name: "CDP", kind: "Guest data", Ic: IconLayers,
    line: "Every guest resolved to one profile across brands and stays.",
    feats: ["AI identity resolution across PMS, web and chat", "Reversible contact merge with full undo", "Behavioural and value segments", "Consent and marketing-preference ledger", "Ad audience sync to Google and Meta"],
  },
  {
    id: "voice", name: "Voice Agent", kind: "Telephony", Ic: IconVoice,
    line: "A front-desk voice that never puts a guest on hold.",
    feats: ["Inbound answering and outbound campaigns", "Warm SIP transfer to the front desk", "Routing by intent and language", "Transcripts, sentiment and call costs", "Ringover CTI screen pop and click-to-call"],
  },
  {
    id: "journeys", name: "Campaigns & Journeys", kind: "Marketing", Ic: IconRoute,
    line: "Sent because of what a guest did, not what day it is.",
    feats: ["Visual journey builder on real booking data", "Email campaigns with the drag-and-drop editor", "WhatsApp broadcasts and template management", "Send-time optimisation and frequency caps", "Conversion tracking and revenue attribution"],
  },
  {
    id: "loyalty", name: "Loyalty", kind: "Retention", Ic: IconInfinity,
    line: "Points, tiers and rewards that work across the whole group.",
    feats: ["Points economy and tier engine", "Cash credit spendable on direct bookings", "Rewards catalogue and redemption", "Wallet passes and referral earning", "Cross-property earn and burn"],
  },
];

const ADDONS = [
  { Ic: IconLang, h: "Tone-tuned markets", b: "Every language is included. This is a linguist tuning voice and register per market, not a bigger list." },
  { Ic: IconEngine, h: "Custom connectors", b: "Any PMS, RMS, POS, spa or door system we don't already speak to." },
  { Ic: IconSpark, h: "Managed curation", b: "Our team grooms the knowledge base and clears gaps every week." },
  { Ic: IconBuilding, h: "Multi-brand workspaces", b: "Separate governance, tone and approvals per brand or region." },
  { Ic: IconClock, h: "Onboarding & implementation", b: "Quoted per rollout. It scales with how many properties and which modules, so a one-hotel Voice launch is not priced like nine modules across forty." },
  { Ic: IconLayers, h: "Migration programme", b: "Historic guest data, transcripts and content moved in with you." },
  { Ic: IconShield, h: "Compliance pack", b: "Data residency, retention policies, penetration test support, DPA." },
];

const ModuleCard = ({ m }) => (
  <article className="pr-mod">
    <div className="pr-mod-rule" aria-hidden="true" />
    <div className="pr-mod-head">
      <span className={`pr-mod-icon ${m.core ? "core" : ""}`}><m.Ic size={19} stroke={1.7} /></span>
      <div>
        <div className="pr-mod-kind">{m.kind}</div>
        <div className="pr-mod-name">{m.name}</div>
      </div>
    </div>
    <p className="pr-mod-line">{m.line}</p>
    <ul className="pr-mod-feats">
      {m.feats.map((f) => <li key={f}><span className="pr-mod-dot" aria-hidden="true" />{f}</li>)}
    </ul>
    <div className="pr-mod-foot">
      <span className="pr-mod-in">Sign it on its own</span>
      <span style={{ flex: 1 }} />
      <span className="pr-mod-solo">Standalone</span>
    </div>
  </article>
);

const PricingModules = () => (
  <section className="section-pad pr-modules" id="modules">
    <div className="container-wide">
      <div className="pr-head">
        <Reveal><div className="eyebrow">Modules</div></Reveal>
        <Reveal delay={120}>
          <h2 className="h-1" style={{ marginTop: 24, maxWidth: 900 }}>
            Switch on what your group runs, <span className="italic-accent">they all share one brain.</span>
          </h2>
        </Reveal>
        <Reveal delay={220}>
          <p className="lead" style={{ marginTop: 26, maxWidth: 740 }}>
            Every one of these can be signed on its own. Voice alone. WhatsApp alone. The CRM alone. Nothing here is a bolt-on that only works once you have bought the rest, and because they all read from and write to the same knowledge base and the same guest profile, adding a second one makes the first smarter the same day.
          </p>
        </Reveal>
      </div>

      <div className="pr-mod-grid">
        {MODULES.map((m, i) => (
          <Reveal key={m.id} delay={i * 70} className="pr-mod-cell"><ModuleCard m={m} /></Reveal>
        ))}
      </div>

      <div className="pr-addons">
        <Reveal>
          <div className="pr-addons-head">
            <div>
              <div className="eyebrow">Add-ons</div>
              <h3 className="h-2" style={{ marginTop: 14 }}>For the edges of a real portfolio.</h3>
            </div>
            <span style={{ flex: 1 }} />
            <span className="pr-addons-meta">Available on any edition · added to your scope, not your invoice count</span>
          </div>
        </Reveal>
        <div className="pr-addon-grid">
          {ADDONS.map((a) => (
            <div key={a.h} className="pr-addon">
              <a.Ic size={17} stroke={1.7} />
              <div className="pr-addon-h">{a.h}</div>
              <p className="pr-addon-b">{a.b}</p>
            </div>
          ))}
        </div>
      </div>
    </div>
  </section>
);

/* ---------- comparison matrix ---------- */

/* Nothing here is tiered that the product does not actually tier. The
   source design gated LANGUAGES by edition; it is not gated in the
   product, and a matrix row is the kind of claim a procurement team holds
   you to in writing. */
const MATRIX = [
  {
    h: "Knowledge base", Ic: IconBrain,
    rows: [
      ["Knowledge entries", "Unlimited", "Unlimited", "Unlimited"],
      ["Website & document crawling", "Weekly", "Daily", "Custom schedule"],
      ["Languages", "60+", "60+", "60+"],
      ["Knowledge layers", "Property", "Group + property", "Group · brand · region · property"],
      ["Multimodal photo search", false, true, true],
      ["Gap Resolver", "Manual publish", "One-click publish", "Approval workflow"],
      ["Versioning & auto-supersede", true, true, true],
      ["KB Studio bulk jobs", false, true, true],
    ],
  },
  {
    h: "Conversations", Ic: IconChannels,
    rows: [
      ["Guest conversations", "Unlimited", "Unlimited", "Unlimited"],
      ["Channels", "WhatsApp · Web · Email", "All six channels", "All six + custom"],
      ["Voice concurrency", "Standard", "Standard", "Dedicated numbers"],
      ["Inbox seats", "5", "Unlimited", "Unlimited"],
      ["Human takeover & routing", "Basic", "Escalation routing", "Routing + SLA policies"],
      ["Inline translation", true, true, true],
      ["Outbound campaigns", false, true, true],
    ],
  },
  {
    h: "Guest data & loyalty", Ic: IconLayers,
    rows: [
      ["Modules available", "All, standalone", "All, standalone", "All, standalone"],
      ["Identity resolution", "Property", "Cross-property", "Cross-brand"],
      ["Segments & journeys", "10 segments", "Unlimited", "Unlimited + shared library"],
      ["Loyalty earn & burn", "Single property", "Cross-property", "Cross-brand"],
      ["Loyalty cash credit", "Optional", "Optional", "Optional"],
      ["PMS & booking engine sync", "1 system", "Standard connectors", "Any system"],
    ],
  },
  {
    h: "Platform & security", Ic: IconShield,
    rows: [
      ["Roles & permissions", "2 roles", "Role sets", "Granular + approvals"],
      ["SSO / SAML", false, "Optional", true],
      ["External API & webhooks", "Read", true, true],
      ["Test Mode & production alerts", false, true, true],
      ["Data residency", "EU", "EU · US", "Region of choice"],
      ["Audit log", "90 days", "1 year", "Configurable"],
    ],
  },
  {
    h: "Service", Ic: IconClock,
    rows: [
      ["Implementation (quoted)", "Guided", "Named lead", "Rollout programme"],
      ["Support response", "Next business day", "4 hours", "1 hour · 24×7"],
      ["Success reviews", "Monthly digest", "Quarterly", "Monthly + exec review"],
      ["Uptime commitment", "99.5%", "99.9%", "99.9% + custom SLA"],
    ],
  },
];

const MatrixCell = ({ v }) => {
  if (v === true) return <span className="pr-mx-check"><IconCheck size={13} stroke={3} /></span>;
  if (v === false) return <span className="pr-mx-no" aria-label="Not included" />;
  return <span className="pr-mx-txt">{v}</span>;
};

const PricingMatrix = () => (
  <section className="section-pad pr-compare" id="compare">
    <div className="container">
      <div className="pr-head">
        <Reveal><div className="eyebrow">Compare</div></Reveal>
        <Reveal delay={120}>
          <h2 className="h-1" style={{ marginTop: 24 }}>
            Line by line, <span className="italic-accent">edition by edition.</span>
          </h2>
        </Reveal>
        <Reveal delay={220}>
          <p className="lead" style={{ marginTop: 26, maxWidth: 640 }}>
            No hidden tiers, no asterisks. If it is in the column, it is in your contract.
          </p>
        </Reveal>
      </div>

      {/* The table is wider than a phone. It scrolls inside its own
          container rather than making the page scroll sideways. */}
      <div className="pr-mx-scroll">
        <div className="pr-mx">
          <div className="pr-mx-header">
            <div className="pr-mx-hcell">What&rsquo;s included</div>
            {[["Core", "Single property"], ["Signature", "2–49 hotels"], ["Enterprise", "50+ · brands"]].map(([n, s], i) => (
              <div key={n} className={`pr-mx-hcol ${i === 1 ? "featured" : ""}`}>
                {i === 1 && <span className="pr-mx-badge">Most popular</span>}
                <div className="pr-mx-hname">{n}</div>
                <div className="pr-mx-hsub">{s}</div>
              </div>
            ))}
          </div>

          {MATRIX.map((g) => (
            <div key={g.h}>
              <div className="pr-mx-group">
                <g.Ic size={14} stroke={1.8} />
                <span>{g.h}</span>
              </div>
              {g.rows.map((r) => (
                <div key={r[0]} className="pr-mx-row">
                  <div className="pr-mx-label">{r[0]}</div>
                  {[1, 2, 3].map((ci) => (
                    <div key={ci} className={`pr-mx-cell ${ci === 2 ? "featured" : ""}`}>
                      <MatrixCell v={r[ci]} />
                    </div>
                  ))}
                </div>
              ))}
            </div>
          ))}
        </div>
      </div>

      <div className="pr-mx-cta">
        <a href={DEMO_URL} className="btn btn-primary">Talk to sales <IconArrow size={14} className="arrow" /></a>
      </div>
    </div>
  </section>
);

/* ---------- always included ---------- */

const ALWAYS = [
  { Ic: IconEngine, h: "Unlimited conversations", b: "Guest volume never changes your invoice. Peak season is just peak season." },
  { Ic: IconRoute, h: "Continuous crawling", b: "Your knowledge base re-reads your world on a schedule, forever." },
  { Ic: IconShield, h: "GDPR & DPA by default", b: "EU hosting, consent ledger, retention policies, right-to-erasure flows." },
  { Ic: IconLang, h: "Every language included", b: "60+ languages on every edition. We never gate a market behind a plan." },
  { Ic: IconLayers, h: "One source of truth", b: "Every module, every channel, every language reads the same entry." },
  { Ic: IconClock, h: "Live in days", b: "Paste your website and the first working brain exists the same afternoon." },
];

const PricingAlways = () => (
  <section className="section-pad pr-always">
    <div className="pr-always-glow" aria-hidden="true" />
    <div className="container">
      <div className="pr-always-head">
        <Reveal><div className="eyebrow">In every edition</div></Reveal>
        <Reveal delay={120}>
          <h2 className="h-1" style={{ marginTop: 20 }}>
            Six things we refuse <span className="italic-accent">to charge extra for.</span>
          </h2>
        </Reveal>
      </div>
      <div className="pr-always-grid">
        {ALWAYS.map((a, i) => (
          <Reveal key={a.h} delay={i * 60}>
            <div className="pr-always-cell">
              <a.Ic size={17} stroke={1.7} />
              <div className="pr-always-h">{a.h}</div>
              <p className="pr-always-b">{a.b}</p>
            </div>
          </Reveal>
        ))}
      </div>
    </div>
  </section>
);

/* ---------- how scoping works ---------- */

const STEPS = [
  { n: "01", h: "A 30-minute scoping call", b: "Properties, brands, channels, languages, the systems you already run, and who needs to approve what." },
  { n: "02", h: "We build a live brain", b: "We crawl your real website before the second call, so you judge the product on your own content, not a demo hotel." },
  { n: "03", h: "One proposal, one number", b: "Edition, modules, add-ons and services in a single annual figure. No per-message meter, no overage clause." },
  { n: "04", h: "Go live, then grow", b: "Add properties, channels or modules mid-term at the same agreed rate card." },
];

const PricingHow = () => (
  <section className="section-pad pr-how">
    <div className="container pr-how-grid">
      <div>
        <Reveal><div className="eyebrow">How scoping works</div></Reveal>
        <Reveal delay={120}>
          <h2 className="h-2" style={{ marginTop: 18 }}>
            Why there&rsquo;s no <span className="italic-accent">public rate card.</span>
          </h2>
        </Reveal>
        <Reveal delay={220}>
          <p className="lead" style={{ marginTop: 20, maxWidth: 360, fontSize: 15 }}>
            A 14-hotel group with four brands and a legacy PMS is a different job to one boutique resort. Publishing one number would overcharge half of you and underserve the rest. So we scope in a week and commit for a year.
          </p>
        </Reveal>
        <Reveal delay={300}>
          <div className="pr-how-box">
            <div className="pr-how-box-h"><IconClock size={15} stroke={1.8} /> Typical time to proposal</div>
            <div className="pr-how-box-v">5 working days</div>
          </div>
        </Reveal>
      </div>
      <ol className="pr-steps">
        {STEPS.map((s, i) => (
          <Reveal key={s.n} delay={i * 90}>
            <li className="pr-step">
              <div className="pr-step-rail">
                <span className="pr-step-n">{s.n}</span>
                {i !== STEPS.length - 1 && <span className="pr-step-line" aria-hidden="true" />}
              </div>
              <div>
                <div className="pr-step-h">{s.h}</div>
                <p className="pr-step-b">{s.b}</p>
              </div>
            </li>
          </Reveal>
        ))}
      </ol>
    </div>
  </section>
);

/* ---------- FAQ ---------- */

const FAQS = [
  { q: "Why don't you publish prices?", a: "Because scope, not seats, drives cost: number of properties, brands and regions, which systems we integrate with, how many markets you serve and how much of the service you want managed. We give you one annual figure after a 30-minute call, and it covers unlimited guest conversations." },
  { q: "Are conversations or messages metered?", a: "No. Guest volume is never metered on any edition. Peak season, a viral post or a 400-room resort in high summer costs the same as a quiet Tuesday." },
  { q: "Can we start with one module and add more later?", a: "Yes. Most groups start with the Hotel Brain and the inbox, then add CDP, Voice, Campaigns or Loyalty. Modules added mid-term use the same rate card agreed at signature, pro-rated to your renewal date." },
  { q: "How does pricing work when we open or acquire a hotel?", a: "New properties join at your agreed per-property rate for the rest of the term, and inherit group knowledge on day one. No re-negotiation. Implementation for the new property is quoted on the same basis as the original rollout." },
  { q: "Is onboarding included?", a: "No, implementation is quoted separately, and it is the one number that genuinely varies. It scales with how many properties you are rolling out and with which modules you switch on: a single-property Voice rollout is a different job to nine modules across forty hotels. You get that figure in the same proposal, so there is no surprise later." },
  { q: "Which languages are included?", a: "All of them, on every edition. The agents answer in the guest's language across 60+ languages and we do not gate that commercially. What is quotable as an add-on is tone-tuning a specific market, register, formality and brand voice, which is a linguist's work, not a feature flag." },
  { q: "What contract terms do you offer?", a: "Annual agreements are standard, with monthly available on Core. Enterprise groups can run multi-year terms with fixed uplift caps and a custom SLA." },
  { q: "Can we trial it first?", a: "We build a live brain on your own website before you sign anything, and run a 30-day pilot on one property or one channel where that helps the decision." },
];

const PricingFaq = () => {
  const [open, setOpen] = useState(0);
  return (
    <section className="section-pad mp-faq-section" style={{ borderTop: '1px solid var(--hairline)' }}>
      <div className="container mp-faq-wrap">
        <div className="mp-faq-side">
          <Reveal><div className="eyebrow">Pricing FAQ</div></Reveal>
          <Reveal delay={120}>
            <h2 className="h-2" style={{ marginTop: 18 }}>
              The commercial <span className="italic-accent">fine print.</span>
            </h2>
          </Reveal>
          <Reveal delay={220}>
            <p className="mp-faq-side-p">
              Written plainly, because procurement reads this page too.
            </p>
          </Reveal>
        </div>
        {/* Single-open, unlike the other pages: this list is long and the
            answers are commercial terms read one at a time. That is markup
            behaviour, not a reason for a ninth set of styles. */}
        <div className="mp-faq-list">
          {FAQS.map((f, i) => (
            <div key={f.q} className="mp-faq-item">
              <button
                type="button"
                className="mp-faq-q"
                aria-expanded={open === i}
                onClick={() => setOpen(open === i ? -1 : i)}
              >
                <span>{f.q}</span>
                <span className={`mp-faq-icon ${open === i ? "open" : ""}`}><IconPlus size={14} stroke={2.2} /></span>
              </button>
              <div className={`mp-faq-a ${open === i ? "open" : ""}`}>
                <div><p>{f.a}</p></div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
};

/* ---------- CTA ---------- */

const PricingCTA = () => (
  <section className="section-pad pr-cta">
    <div className="pr-cta-glow" aria-hidden="true" />
    <div className="container-narrow" style={{ position: "relative", textAlign: "center" }}>
      <Reveal>
        <div className="eyebrow" style={{ justifyContent: "center" }}>Five days to a proposal</div>
      </Reveal>
      <Reveal delay={120}>
        <h2 className="h-display" style={{ marginTop: 28, fontSize: "clamp(40px, 5.6vw, 68px)" }}>
          Tell us your portfolio. <span className="italic-accent">We&rsquo;ll tell you the number.</span>
        </h2>
      </Reveal>
      <Reveal delay={220}>
        <p className="lead" style={{ marginTop: 26, fontSize: 17, maxWidth: 580, marginLeft: "auto", marginRight: "auto" }}>
          One call, one live brain built on your own website, one annual figure with nothing metered behind it.
        </p>
      </Reveal>
      <Reveal delay={320}>
        <div className="flex gap-3 wrap center" style={{ marginTop: 36, justifyContent: "center" }}>
          <a href={DEMO_URL} className="btn btn-primary">Talk to sales <IconArrow size={14} className="arrow" /></a>
        </div>
      </Reveal>
      <Reveal delay={420}>
        <div className="pr-cta-note">No credit card, no procurement gauntlet, no sales sequence.</div>
      </Reveal>
    </div>
  </section>
);

/* ---------- page ---------- */

const PricingPage = () => (
  <>
    <SectionNav current="pricing" />
    <PricingHero />
    <PricingPlans />
    <PricingModules />
    <PricingMatrix />
    <PricingAlways />
    <PricingHow />
    <PricingFaq />
    <PricingCTA />
    <SectionFooter />
  </>
);

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