/* ════════════════════════════════════════════════════════════════════
   Payment Gateway — embed deltas for the dashboard (hand-written)
   Loaded AFTER payment-gateway.css so it wins. Houses the few adjustments
   the standalone can't know about — keep embed-only tweaks here so the
   generated sheet stays pure (regenerable via tools/regenerate-payment.py).
   ════════════════════════════════════════════════════════════════════ */

/* ── DESKTOP/MOBILE · don't become a nested scroll-box ─────────────────
   The standalone is a full page that scrolls in the window. Mounted in the
   dashboard, the scoped `html, body { overflow-x: hidden }` lands on
   `.payment-gateway`, which (per spec) forces overflow-y → auto, turning the
   wrapper into its OWN scroll container. The dashboard shell locks #dash-view
   to the viewport height, so as a default flex item the wrapper got SHRUNK
   below its content and scrolled internally — clipping the tall device-wrap
   (the Charge/Cash buttons fell off the bottom).

   flex:1 0 auto (shrink 0, auto basis) makes the wrapper take its FULL content
   height instead, so nothing is clipped and the dashboard's own .dash-main
   provides the page scroll — same feel as the standalone. (Same idea as
   pos-retail-embed.css's `.pos-retail-desk { flex: 1 0 auto }`.) */
.payment-gateway {
  flex: 1 0 auto;
  min-height: 0;
}

/* ── DESKTOP · keep the Bamboo device at its standalone size ───────────
   The dashboard content area is ~300px narrower than the standalone's full
   page, so the proportional `1fr : 1.7fr` device column gives the device
   row only ~390px → the fixed-384px device flex-shrinks to ~316px and looks
   cramped / unlike the standalone. Give the device its OWN fixed-width column
   (sized to the 384px device + the card's padding) and stop it shrinking,
   whenever the dashboard row is wide enough for it to sit beside the
   transactions; below that, fall back to the standalone's stacked layout.
   A container query (not @media) so it responds to the ACTUAL panel width,
   not the viewport — the sidebar/collapse state changes the panel width
   without changing the viewport. (Same approach as pos-retail-embed.css.) */
.payment-gateway .pay-dash { container-type: inline-size; }
@container (min-width: 900px) {
  .payment-gateway .pay-dash__grid {
    grid-template-columns: 480px minmax(0, 1fr);
  }
  .payment-gateway .pay-dash__device-wrap .pay-device { flex-shrink: 0; }
}
@container (max-width: 899.98px) {
  .payment-gateway .pay-dash__grid { grid-template-columns: minmax(0, 1fr); }
}

/* ── Below 1200px · iPad-like layout ───────────────────────────────────────
   On desktop the dashboard shows device + data side-by-side. Below 1200px the
   panel is too narrow for that — mirror the standalone's mobile layout instead:
   hide the device preview column, show the mobile CTA card (tap → fullscreen
   device demo), leave only the Transactions/Report panel visible. Same look as
   the ≤767px mobile layout from the generated sheet, but triggered earlier for
   the narrower dashboard context. */
@media (max-width: 1199px) {
  .payment-gateway .pay-dash[data-layout] .pay-dash__grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .payment-gateway .pay-dash-section .pay-dash__right { display: none; }
  .payment-gateway .pay-mobile-cta {
    display: block;
    grid-column: 1 / -1;
    order: -1;
  }
}

/* ── TXN DETAIL POPUP · Refund button right-edge gap ───────────────────
   #txnDetailModal's scroller (overflow:auto) shows a space-taking scrollbar
   once its content overflows. The sticky full-width Refund button is
   width:100% of the scroller's CONTENT box (minus that scrollbar gutter), so
   it stops a few px short of the panel's right edge — leaving a sliver of the
   panel background beside it ("hở"). The standalone uses the OS overlay
   scrollbar (no gutter), so it never shows this. Hide the scrollbar on this
   scroller (content still scrolls) so the button spans the full panel width —
   matching the standalone. Same pattern as .pay-dash__status-tabs /
   .sub-detail__feats elsewhere. */
.payment-gateway .pay-modal--txn .pay-modal__scroller {
  scrollbar-width: none;                 /* Firefox */
}
.payment-gateway .pay-modal--txn .pay-modal__scroller::-webkit-scrollbar {
  display: none;                         /* Chromium / WebKit — no gutter */
}

/* ── CONGRATS → COMPLETE · "giật" (one-frame vertical jump) ────────────
   Every device screen is a .pay-view { position:absolute; inset:0 } so they
   overlap and cross-fade. But .pay-congrats and .pay-complete override that
   with `position: relative` (in the source — meant to host the .pay-confetti
   layer, but .pay-view is ALREADY a positioned containing block, so it's
   redundant). Relative drops them into normal flow, so during the 240ms
   cross-fade the incoming Complete stacks BELOW the outgoing Congrats, then
   snaps up to the top when Congrats is removed → a visible jump right before
   "Payment complete" shows. Force them back to absolute so they overlap and
   fade cleanly like every other screen (inset:0 still comes from .pay-view;
   confetti + z-index layering keep working — the element stays positioned). */
.payment-gateway .pay-congrats,
.payment-gateway .pay-complete {
  position: absolute;
}

/* ── Transaction detail · on-device settle action ─────────────────────
   The on-device history detail (tpl-txn-detail) now shows a sticky settle
   action pinned in a footer — Void for card/wallet, Refund for cash/gift
   (see styles/payment-gateway.css → .pay-txn-detail__footer). It used to be
   hidden here as "read-only"; it's now an active demo control, so no hide
   rule. (The old .pay-tx__refund dashboard-popup bar no longer exists — the
   dashboard detail uses .pay-txd__action-btn, which was never hidden here.) */

/* ── ON-DEVICE TXN DETAIL · Tip row lopsided on mobile ─────────────────
   The Tip section renders headline('', amount, Edit-Tip) — an EMPTY first
   column (no date/badge like the Summary headline has). At ≤720px the source
   collapses the headline to a 2-col `1fr 1fr` grid, so the empty main column
   stranded the amount in the RIGHT cell (looks centered) and the chip wrapped
   full-width onto the next row → lopsided/messy.
   When the main column is empty, drop the grid and lay the row out simply:
   amount on the left, Edit-Tip chip on the right, same baseline. Scoped to the
   empty-main headline via :has() so the Summary headline (main has content) is
   untouched, and gated on the SAME 720px breakpoint as the source rule so it
   only kicks in exactly when that broken 2-col layout is active. */
@media (max-width: 720px) {
  .payment-gateway .pay-txd__headline:has(> .pay-txd__headline-main:empty) {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
  }
  .payment-gateway .pay-txd__headline:has(> .pay-txd__headline-main:empty) > .pay-txd__headline-main {
    display: none;
  }

  /* Summary / Refund headlines (main = timestamp + status badge) → tidy 2×2 grid:
       row 1:  date            │  amount
       row 2:  status badge    │  Receipt
     The badge lives INSIDE .pay-txd__headline-main (stacked under the date) while
     the amount + Receipt are its grid siblings, so `display:contents` on the main
     wrapper promotes the date + badge to grid items — letting the badge share a
     row with the Receipt chip. 1fr/auto columns + justify-self pin labels left /
     amount+chip right (the "space-between" look). Fixes the old layout where the
     timestamp wrapped, the amount was cramped, and Receipt sat full-width alone. */
  .payment-gateway .pay-txd__headline:has(> .pay-txd__headline-main:not(:empty)) {
    grid-template-columns: 1fr auto;
    grid-template-rows: auto auto;
    column-gap: var(--space-3);
    row-gap: var(--space-2);
    align-items: center;
  }
  .payment-gateway .pay-txd__headline:has(> .pay-txd__headline-main:not(:empty)) > .pay-txd__headline-main {
    display: contents;
  }
  .payment-gateway .pay-txd__headline:has(> .pay-txd__headline-main:not(:empty)) .pay-txd__date {
    grid-area: 1 / 1;                       /* date — row 1, left */
  }
  .payment-gateway .pay-txd__headline:has(> .pay-txd__headline-main:not(:empty)) > div:not(.pay-txd__headline-main) {
    grid-area: 1 / 2; justify-self: end;    /* amount — row 1, right */
  }
  .payment-gateway .pay-txd__headline:has(> .pay-txd__headline-main:not(:empty)) .pay-txd__badge {
    grid-area: 2 / 1; justify-self: start;  /* status badge — row 2, left */
  }
  .payment-gateway .pay-txd__headline:has(> .pay-txd__headline-main:not(:empty)) .pay-txd__chip-btn {
    grid-area: 2 / 2; justify-self: end;    /* Receipt — row 2, right (space-between) */
  }
}

/* ── POS-connected · keep the Transactions / Report tab switcher ───────
   The generated sheet hides the data-tab switcher in POS mode
   (.pay-dash[data-layout="pos"] .pay-dash__data-tabs { display:none }) — the
   standalone treats POS as a "transactions-only live mirror". For the demo we
   keep the switcher visible so Report stays reachable in POS-connected too (it
   renders fine in the POS layout). Pairs with the regen tweak (step 7) that
   stops setMode from force-resetting the active tab to Transactions, so the
   selected Transactions/Report tab persists across Standalone <-> POS. */
.payment-gateway .pay-dash[data-layout="pos"] .pay-dash__data-tabs {
  display: inline-flex;
}

/* ── Device preview · uniform content scale for the narrow POS column ──
   The phone screen scales with its column (aspect-ratio 9/19) but its content
   is sized in fixed px for a full-size phone. In POS-connected at ~1440 the
   middle terminal column is narrow (screen ≈ 237px), so tall screens — most
   visibly "Add a Tip" (4 big % cards) — overflowed the ~440px screen body and
   clipped at the bottom. Rather than tweak each screen, scale the whole screen
   body down UNIFORMLY so every screen keeps its proportions and fits. `zoom`
   (not transform) reflows, and the body's flex height holds while its content
   lays out in the zoomed coordinate — so it fills the screen with no empty gap.

   Two container-width bands (desktop-only via min-width:901px guard):
     ≤ 250px  → POS preview (≈237px): zoom 0.68 — tip content 649px × 0.68 = 441px
               fits the 448px rendered body (7px spare). Custom Tip + No tip visible.
     251–320px → Standalone preview (≈288px): zoom 0.74 — content fits the taller
               555px rendered body with proportional margins; no need to go smaller.
   Mobile fullscreen and wider previews keep full size (no zoom). */
.payment-gateway .pay-dash__device-wrap .pay-screen { container-type: inline-size; }
@media (min-width: 901px) and (max-width: 1440px) {
  @container (max-width: 300px) {
    /* POS preview — layout/offsetWidth ≈ 276px (rendered ≈ 237px).
       Tip content 649px × 0.68 = 441px fits in the 448px rendered body. */
    .payment-gateway .pay-dash__device-wrap .pay-statusbar,
    .payment-gateway .pay-dash__device-wrap .pay-screen__body { zoom: 0.68; }
  }
  @container (min-width: 301px) and (max-width: 380px) {
    /* Standalone preview — layout/offsetWidth ≈ 320–360px (rendered ≈ 288px).
       Tip fits comfortably at 0.74; content 649px × 0.74 = 480px < 555px body. */
    .payment-gateway .pay-dash__device-wrap .pay-statusbar,
    .payment-gateway .pay-dash__device-wrap .pay-screen__body { zoom: 0.74; }
  }
}

/* ── POS Checkout · customer card phone number wrap ────────────────────────
   At 1440 the POS column is narrow enough that "(415) 555-0148" breaks at the
   space and the hyphen. The phone is a single datum — never wrap it. */
.payment-gateway .pay-dash__pos-cust-phone { white-space: nowrap; }

/* ── Report KPI cards · fix 3+1 wrap in POS mode ───────────────────────────
   rpt-kpis uses `auto-fit minmax(150px,1fr)` — in POS-connected the right panel
   is narrower, so auto-fit resolves to 3 columns and the 4th card drops to row 2
   (3+1 layout, uneven). Force 2×2 in POS-connected at desktop so the grid is
   always balanced regardless of panel width. Mobile (handled by the generated
   sheet at 1fr) is unaffected. */
@media (min-width: 901px) {
  .payment-gateway .pay-dash[data-layout="pos"] .rpt-kpis {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ── "Try the Bamboo Device" CTA → fullscreen demo + Live demo/Exit bar ──────
   The Jun-2026 source reworked the PHONE experience to a bottom-nav app and, in
   doing so, dropped every `body.pay-mobile-demo-open` rule from the generated
   sheet AND hid `.pay-mobile-bar` / `.pay-mobile-cta` at ≤767px. But the embed
   still surfaces the "Tap to view demo" CTA in the dashboard's narrow band
   (≤1199px, see the block above) — and the markup + JS for the dark "Live Bamboo
   demo / Exit" bar (openMobileDemo/closeMobileDemo → body.pay-mobile-demo-open)
   are all still present. With no CSS, tapping the CTA set the body class but
   nothing opened — no fullscreen device, no exit bar.

   Restore the open-demo styling HERE (hand-written = regen-safe) so the embed
   matches the POS Retail (.pos-mobile-bar) and Booking (.bk-mfull__bar) chapters:
   tap the CTA → terminal goes fullscreen under a dark bar with a Live-demo dot +
   Exit. Ported verbatim from the pre-rework generated sheet; `body.pay-mobile-
   demo-open …` outranks the embed's `.payment-gateway … .pay-dash__right{display:none}`
   on specificity (the extra `body` element), so no !important is needed.

   Gated to 768–1199px: at ≤767 the new bottom-nav model owns mobile (the CTA is
   hidden there), so the demo is only ever triggerable in this band. */
@media (min-width: 768px) and (max-width: 1199px) {
  body.pay-mobile-demo-open { overflow: hidden; }
  body.pay-mobile-demo-open .pay-mobile-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 300;
    padding: calc(env(safe-area-inset-top, 0px) + var(--space-3)) var(--space-4) var(--space-3);
    background: var(--color-ink-dark);
  }
  body.pay-mobile-demo-open .landing-nav,
  body.pay-mobile-demo-open .pay-page-hero,
  body.pay-mobile-demo-open .pay-mobile-cta,
  body.pay-mobile-demo-open .pay-dash-section .pay-dash__left,
  body.pay-mobile-demo-open .pay-footer { display: none; }

  /* Terminal section becomes the fullscreen view, sitting under the bar. */
  body.pay-mobile-demo-open .pay-dash-section .pay-dash__right {
    display: block;
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    z-index: 200;
    background: var(--color-canvas);
    padding-top: calc(60px + env(safe-area-inset-top, 0px));   /* room for the bar */
  }
  body.pay-mobile-demo-open .pay-dash-section .pay-dash__terminal-card {
    height: 100%;
    background: var(--color-canvas);
    border: 0; border-radius: 0;
    padding: 0; gap: 0;
    box-shadow: none;
  }
  body.pay-mobile-demo-open .pay-dash-section .pay-dash__terminal-head { display: none; }
  body.pay-mobile-demo-open .pay-dash-section .pay-dash__device-wrap {
    padding: 0;
    background: var(--color-canvas);
    border-radius: 0;
    height: 100%;
  }
  body.pay-mobile-demo-open .pay-dash-section .pay-device {
    width: 100vw;
    max-width: 100%;
    padding: 0;
    border-radius: 0;
    background: var(--color-canvas);
    box-shadow: none;
  }
  body.pay-mobile-demo-open .pay-dash-section .pay-device::after,
  body.pay-mobile-demo-open .pay-dash-section .pay-device__power,
  body.pay-mobile-demo-open .pay-dash-section .pay-statusbar,
  body.pay-mobile-demo-open .pay-dash-section .pay-navstrip { display: none; }
  body.pay-mobile-demo-open .pay-dash-section .pay-screen {
    aspect-ratio: auto;
    width: 100vw;
    height: calc(100dvh - 60px - env(safe-area-inset-top, 0px));
    border-radius: 0;
  }
}

/* ── PHONE · "Live Bamboo demo" header (mirrors booking's bk-mfull bar) ──────
   On ≤767px the generated payment app goes full-screen (.pay-dash-section is
   position:fixed inset:0, body[data-mtab] shell) and covers the dashboard
   topbar — leaving no visible way back. Add a dark header that matches the
   booking Live-demo bar for consistency, and push the app canvas down by the
   header height so nothing is hidden behind it. The element is appended in
   js/views/dashboard/index.js (setupPaymentDemoHeader); Exit returns to the
   tile-grid menu. Header is hand-written here so the generated sheet stays pure. */
.pay-demo-header { display: none; }
@media (max-width: 767px) {
  .pay-demo-header {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    box-sizing: border-box;
    position: fixed; top: 0; left: 0; right: 0; z-index: 330;
    height: calc(48px + env(safe-area-inset-top, 0px));
    padding: calc(env(safe-area-inset-top, 0px) + 8px) 16px 8px;
    background: #16121A; color: #fff;
  }
  /* Drop the full-screen payment canvas below the header (it's position:fixed
     inset:0 at this breakpoint, so override its top). The bottom nav is a
     separate fixed bar, unaffected. */
  .payment-gateway .pay-dash-section { top: calc(48px + env(safe-area-inset-top, 0px)); }

  .pay-demo-header__title { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; }
  .pay-demo-header__dot {
    width: 8px; height: 8px; border-radius: 50%; background: #22C55E;
    animation: payDemoPulse 1.6s ease-out infinite;
  }
  .pay-demo-header__exit {
    display: inline-flex; align-items: center; gap: 6px;
    height: 32px; padding: 0 14px;
    border: 0; border-radius: 999px;
    background: rgba(255, 255, 255, .14); color: #fff;
    font: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
  }
  .pay-demo-header__exit:hover { background: rgba(255, 255, 255, .22); }
  .pay-demo-header__exit:active { transform: scale(.96); }
}
@keyframes payDemoPulse {
  0%   { box-shadow: 0 0 0 0 rgba(34, 197, 94, .6); }
  70%  { box-shadow: 0 0 0 8px rgba(34, 197, 94, 0); }
  100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
}

/* ── PHONE · Sale terminal — keep the action buttons clear of the bottom nav ──
   On real phones the Gift-card / Manual-card-entry row was getting clipped under
   the fixed bottom nav. Two regen-safe fixes here (the generated sheet stays
   pure):
   1) The full-screen sale view (.pay-dash__right) only reserved --pay-mnav-h
      (60px) at the bottom, but the nav is 60px + env(safe-area-inset-bottom).
      Its actions are margin-top:auto (bottom-pinned), so the safe-area slice slid
      under the nav. Reserve the FULL nav height incl. safe-area.
   2) Trim the vertical spacing around the big $amount so the keypad + actions get
      more breathing room (and the column never overflows on short viewports). The
      back-button header is already hidden on phones, so collapse that dead row. */
@media (max-width: 767px) {
  body[data-mtab="sale"] .payment-gateway .pay-dash-section .pay-dash__right {
    bottom: calc(var(--pay-mnav-h) + env(safe-area-inset-bottom, 0px));
  }
  /* Lighter spacing above/below the amount (was 8px / 16px). */
  body[data-mtab="sale"] .payment-gateway .pay-entry__amount {
    margin: var(--space-1) 0 var(--space-2);
  }
  /* Reclaim the empty header row (its only child — the back button — is hidden
     on phones), removing it from the entry-column flow + its flex gap. */
  body[data-mtab="sale"] .payment-gateway .pay-entry__header { display: none; }

  /* ── Add-a-Tip · fit the whole screen on real phones ──
     The four tip cards have a fixed min-height:176px, so on short viewports (a
     real phone once Safari's chrome + safe areas eat the height) the stack ran
     taller than .pay-screen and pushed "Custom tip" / "No tip" down under the
     fixed bottom nav — the bottom section got clipped. .pay-tip is already a
     flex column that fills the screen, so let the grid flex to fill the space
     between the subtitle and the two buttons and drop the card floor: the cards
     then shrink evenly to whatever height is available, so everything fits in one
     screen on any phone (and grows back to normal on taller ones). No magic
     per-device number. Desktop (>767px) keeps the 176px cards untouched. */
  .payment-gateway .pay-tip__grid {
    flex: 1 1 auto;
    min-height: 0;
    grid-template-rows: 1fr 1fr;
  }
  .payment-gateway .pay-tip__card { min-height: 0; }
  /* Trim the big subtitle gap a touch so the cards get that space instead. */
  .payment-gateway .pay-tip__sub { margin-bottom: var(--space-4); }
}

/* ── Mobile Pricing tab · radio-card "Subscribe" UI (injected by
   setupPaymentMobilePricing) — mirrors the Go Booking mobile Subscribe tab:
   pick-one plan cards + a gradient Continue button. ── */
.pay-sub__head { margin-bottom: var(--space-5, 20px); }
.pay-sub__title { margin: 0 0 var(--space-2, 8px); font-size: 20px; font-weight: 800; letter-spacing: -.02em; color: var(--color-ink, #16121A); }
.pay-sub__note { margin: 0; font-size: var(--font-size-sm, 14px); line-height: 1.5; color: var(--color-ink-soft, #6B6470); }

.pay-sub__plans { display: flex; flex-direction: column; gap: var(--space-3, 12px); }

/* Shared by the Payment + Go Check-In mobile Subscribe tabs. Kept scoped (not
   bare `.pay-plan-card`) so it retains the specificity that beats the payment
   button reset; the .chk-subscribe copy carries the same style into Check-in. */
.payment-gateway .pay-plan-card,
.chk-subscribe .pay-plan-card {
  display: flex; align-items: center; gap: var(--space-3, 12px);
  width: 100%; text-align: left;
  padding: var(--space-4, 16px);
  border: 1.5px solid var(--color-divider, #E7E3EE);
  border-radius: var(--radius-lg, 16px);
  background: var(--color-canvas, #fff);
  font: inherit; color: inherit; cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.pay-plan-card.is-on { border-color: var(--color-brand, #7C3AED); background: var(--color-brand-soft, rgba(124, 58, 237, .07)); }

.pay-plan-card__radio {
  flex: 0 0 auto; position: relative;
  width: 20px; height: 20px; border-radius: 50%;
  border: 2px solid var(--color-divider, #CFC9DA);
}
.pay-plan-card.is-on .pay-plan-card__radio { border-color: var(--color-brand, #7C3AED); }
.pay-plan-card.is-on .pay-plan-card__radio::after {
  content: ""; position: absolute; inset: 3px; border-radius: 50%;
  background: var(--color-brand, #7C3AED);
}

.pay-plan-card__info { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pay-plan-card__name { font-size: var(--font-size-base, 16px); font-weight: 700; color: var(--color-ink, #16121A); }
.pay-plan-card__star { color: #F5A623; }
.pay-plan-card__badge {
  align-self: flex-start; margin: 2px 0;
  padding: 2px 8px; border-radius: 999px;
  background: var(--color-brand, #7C3AED); color: #fff;
  font-size: 10px; font-weight: 800; letter-spacing: .04em;
}
.pay-plan-card__sub { font-size: var(--font-size-sm, 13px); color: var(--color-ink-soft, #6B6470); }

.pay-plan-card__price { flex: 0 0 auto; text-align: right; white-space: nowrap; }
.pay-plan-card__price b { font-size: 20px; font-weight: 800; color: var(--color-ink, #16121A); }
.pay-plan-card__price span { font-size: var(--font-size-sm, 13px); color: var(--color-ink-soft, #6B6470); }

/* Subscribe CTA — matched to the Go Booking mobile demo's Continue button
   (.cta-grad) so all three products' Subscribe tabs are consistent: purple→pink
   linear-gradient(90deg,#7C3AED,#EC4899) + --radius-lg (12px, = Booking .btn) +
   Booking's lifted shadow. Kept as a dedicated scoped class so specificity beats
   `.payment-gateway button { background:none }`, which the styleguide allows for
   gradient CTAs. */
.payment-gateway .pay-sub__continue,
.chk-subscribe .pay-sub__continue {
  width: 100%; margin-top: var(--space-5, 20px);
  padding: 13px 20px; border: 0; border-radius: var(--radius-lg);
  background: linear-gradient(90deg, #7C3AED, #EC4899);
  color: #fff; font: inherit; font-size: var(--font-size-md, 16px); font-weight: 800;
  cursor: pointer; box-shadow: 0 10px 22px -10px rgba(124, 58, 237, .7);
  transition: box-shadow .2s ease, transform .15s ease;
}
.payment-gateway .pay-sub__continue:hover,
.chk-subscribe .pay-sub__continue:hover {
  box-shadow: 0 12px 26px -10px rgba(124, 58, 237, .8);
}
.payment-gateway .pay-sub__continue:active,
.chk-subscribe .pay-sub__continue:active { transform: scale(.99); }

/* ── PHONE · transaction-detail popup must not trap the user ────────────────
   On a phone the generated sheet blows the txn-detail popup up to a full-screen
   panel (height:100dvh), so it covered the "Live Bamboo demo" header AND the
   bottom nav — and its own "← back" header was hidden behind our header, leaving
   no way out. Pin the panel BETWEEN the header and the bottom nav: the detail's
   own ← back (→ transaction list) and the bottom nav (→ other tabs, closed via
   index.js setupPaymentDemoHeader) both become visible and usable again. */
@media (max-width: 767px) {
  .payment-gateway .pay-modal--txn .pay-modal__panel {
    position: fixed; left: 0; right: 0;
    top: calc(56px + env(safe-area-inset-top, 0px));
    bottom: calc(var(--pay-mnav-h, 60px) + env(safe-area-inset-bottom, 0px));
    height: auto; max-height: none; margin: 0; border-radius: 0;
  }
}

/* ── Dual Pricing Savings Calculator (in the mobile Pricing tab) ───────────── */
.pay-calc {
  margin-top: var(--space-8, 32px);
  padding: var(--space-5, 20px);
  border: 1px solid var(--color-divider, #E7E3EE);
  border-radius: var(--radius-lg, 16px);
  background: var(--color-surface, #F7F5FB);
}
.pay-calc__title { margin: 0 0 4px; font-size: var(--font-size-base, 16px); font-weight: 800; color: var(--color-ink, #16121A); }
.pay-calc__note { margin: 0 0 var(--space-4, 16px); font-size: var(--font-size-sm, 13px); color: var(--color-ink-soft, #6B6470); }
.pay-calc__field { display: block; }
.pay-calc__label { display: block; margin-bottom: 6px; font-size: 12px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--color-ink-soft, #6B6470); }
.pay-calc__input-wrap {
  display: flex; align-items: center; gap: 4px;
  padding: 12px 14px; border-radius: var(--radius-md, 12px);
  border: 1.5px solid var(--color-divider, #E7E3EE); background: var(--color-canvas, #fff);
}
.pay-calc__input-wrap:focus-within { border-color: var(--color-brand, #7C3AED); }
.pay-calc__prefix { font-size: 18px; font-weight: 700; color: var(--color-ink, #16121A); }
.pay-calc__input { flex: 1 1 auto; min-width: 0; border: 0; outline: 0; background: transparent; font: inherit; font-size: 18px; font-weight: 700; color: var(--color-ink, #16121A); }
.pay-calc__results { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3, 12px); margin-top: var(--space-4, 16px); }
.pay-calc__result {
  padding: var(--space-3, 12px) var(--space-4, 16px); text-align: center;
  border-radius: var(--radius-md, 12px); border: 1px solid var(--color-divider, #E7E3EE);
  background: var(--color-canvas, #fff);
}
.pay-calc__result-label { display: block; margin-bottom: 4px; font-size: 12px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--color-ink-soft, #6B6470); }
.pay-calc__result b { font-size: 22px; font-weight: 800; color: var(--color-brand, #7C3AED); }
.pay-calc__fineprint { margin: var(--space-3, 12px) 0 0; font-size: 11px; line-height: 1.4; color: var(--color-ink-soft, #9890A5); }

/* ── Toast · don't shrink to 50% on mobile ────────────────────────────
   The generated `.pay-toast` is `position:fixed; left:50%` with no width, so
   it sizes to the ~50%-of-viewport available space and long messages ("Report
   printing is available in the full version only") wrap into a skinny 3-line
   pill on phones. width:max-content sizes it to the text instead, still capped
   by the generated `max-width: 90vw`. (`.pay-home__toast` already has
   white-space:nowrap, so it's unaffected and left as-is.) */
.payment-gateway .pay-toast { width: max-content; }

