/**
 * The ticket panel — the shop's buying card in an overlay.
 *
 * These rules used to live only in gravity-2026.css, which the Opera template
 * loads and the Techno one does not. The panel's markup and script are shared,
 * so on Techno it rendered with no styling at all: the overlay sat in the page
 * flow, permanently "open", and pressing Get tickets appeared to do nothing.
 *
 * Everything here is panel-only and reads the accent from whichever landing
 * template is around it, so one file serves both. Opera still carries its own
 * copy inside gravity-2026.css; that page is selling right now and is left
 * alone deliberately — see the note at the bottom of this file.
 */

/* A double tap on a stepper used to zoom the page instead of counting twice:
   the browser waits to see whether a second tap is coming and reads the pair as
   a zoom gesture. manipulation says these are controls, not a document to be
   magnified — pinch to zoom still works everywhere. */
.tmodal { touch-action: manipulation }
.wcvcl-circ-btn, .wcvcl-info, .vclose { touch-action: manipulation }

.tmodal{ position: fixed; inset: 0; z-index: 100010; display: grid; place-items: center;
  background: rgba(5,5,7,.82); backdrop-filter: blur(6px); padding: 18px; }

/* The panel is parked, not removed — and its state is a class, not the hidden
   attribute.
   Stripe builds its Apple Pay / Google Pay button into a container that lives
   in here, and Stripe Elements will not mount into a box with no dimensions.
   Parked, the panel keeps a layout box for the button to be built in while
   being invisible, untouchable and out of the accessibility tree.
   The attribute cannot be used for this: Bootstrap loads across the whole site
   and its reset carries `[hidden] { display: none !important }`, which no rule
   written here can outrank. A class is beyond its reach. */
.tmodal{ visibility: hidden; opacity: 0; pointer-events: none;
  backdrop-filter: none; -webkit-backdrop-filter: none; }
.tmodal.open{ visibility: visible; opacity: 1; pointer-events: auto;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }

.tmbox{ position: relative; width: min(560px, 100%); max-height: calc(100vh - 36px); max-height: calc(100svh - 36px);
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  background: none; border: 0; padding: 0 0 6px;
  /* The panel keeps scrolling, it just stops drawing the bar. What tells
     people there is more below is the chevron under the panel, which the
     script raises exactly when the Add button has gone off screen. */
  scrollbar-width: none;
  /* Nothing in a buying panel should scroll sideways. Stripe's express slot
     briefly measures wider than the card while it builds, and the sideways bar
     it left behind sat across the bottom of the panel. */
  overflow-x: hidden; }
.tmbox::-webkit-scrollbar { display: none }

/* The wait state. Anchored to .tmodal, which is fixed to the viewport — not to
   .tmbox, which scrolls. Inside the scrolling box `inset: 0` resolves against
   the content, so the overlay sat over the top of the ticket list while the
   pay buttons below stayed bright and tappable. Covering them is the point. */
.tmwait{ position: fixed; inset: 0; z-index: 100014;
  background: rgba(8,8,10,.88); backdrop-filter: blur(3px);
  display: grid; place-items: center; }
.tmwait[hidden]{ display: none }
.tmwait-in{ text-align: center; padding: 24px; max-width: 24ch }
.tmwait-in b{ display: block; font-family: var(--display); font-size: 19px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .02em; color: #fff; margin: 16px 0 6px }
.tmwait-in span{ display: block; font-size: 13px; color: var(--fg-2) }
.tmwait-ring{ display: block; width: 34px; height: 34px; margin: 0 auto; border-radius: 50%;
  border: 3px solid rgba(255,255,255,.20); border-top-color: var(--action);
  animation: tmspin .9s linear infinite; }
@keyframes tmspin{ to{ transform: rotate(360deg) } }
/* Motion off: the ring stops turning but the words still say what is
   happening, which is the part that actually carries the message. */
@media (prefers-reduced-motion: reduce){
  .tmwait-ring{ animation: none; border-top-color: rgba(255,255,255,.55) }
}

/* The scroll nudge. Sits above the panel, never inside it, so it stays put
   while the rows move. The colour needs !important because the armour block
   repaints every unclassed button to inherit — it caught this one too and
   painted the arrow white on a white disc. */
.tmnudge{ position: absolute; left: 50%; bottom: 26px; z-index: 100012;
  width: 44px; height: 44px; border-radius: 50%; border: 0; padding: 0;
  background: var(--ink); color: #fff !important; display: grid; place-items: center;
  cursor: pointer; box-shadow: 0 8px 24px rgba(0,0,0,.42);
  opacity: 0; pointer-events: none; transform: translate(-50%, 0);
  transition: opacity .25s ease; }
.tmnudge svg{ width: 17px; height: 17px; display: block }
.tmnudge svg path{ stroke: #fff !important; }
.tmnudge.show{ opacity: 1; pointer-events: auto; animation: tmbob 1.8s ease-in-out infinite }
@keyframes tmbob{ 0%,100%{ transform: translate(-50%, 0) } 50%{ transform: translate(-50%, 4px) } }
@media (prefers-reduced-motion: reduce){ .tmnudge.show{ animation: none } }

/* padding: 0 because the parent theme puts 8px 16px on every button. Inside
   a 36px circle that leaves a 4px content box and shoves the glyph to the
   right of the ring. */
.vclose{ width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid var(--line-2); background: transparent; color: #fff;
  display: grid; place-items: center; cursor: pointer;
  padding: 0 !important; line-height: 1 !important; }
.vclose:hover{ border-color: #fff }
/* Above the wait overlay (z-index 100014): whatever happens during a
   payment, the way out stays reachable. */
.tmbox .vclose{ position: sticky; top: 0; float: right; z-index: 100015; margin: 0 0 -12px }

/* The title and the two facts above the card, set the way the product page
   sets them: white on the dark overlay, grey label above a large value.

   !important throughout, and not for tidiness: style-new.css sets h3 and span
   typography on the bare tag with !important of its own. Without this the
   panel's title came out in the site's body font in sentence case — the panel
   said "Gravity Techno presents: Holy Priest" in light grey where Opera's says
   it in the display face, uppercase. gravity-2026.css does the same thing for
   Opera through its generated armour block; this file is small enough to state
   it once, by hand. */
.g26-tickethead{ padding: 4px 6px 20px !important; text-align: left !important; padding-right: 60px !important }
.g26-tickethead h3{ margin: 0 0 16px !important; font-family: var(--display) !important;
  font-weight: 600 !important; text-transform: uppercase !important;
  letter-spacing: -.01em !important; line-height: 1.05 !important;
  font-size: clamp(24px, 5.4vw, 34px) !important; color: #fff !important }
.g26-tktfacts{ display: flex !important; gap: 34px !important }
.g26-tktfacts span{ display: block !important; font-size: 12px !important;
  color: #9D9D9D !important; margin-bottom: 4px !important; letter-spacing: 0 !important;
  text-transform: none !important; font-weight: 400 !important }
.g26-tktfacts b{ display: block !important; font-family: var(--body) !important;
  font-weight: 600 !important; text-transform: uppercase !important;
  font-size: clamp(18px, 4.4vw, 24px) !important; line-height: 1 !important; color: #fff !important }

/* Never seen, never in the way, never reachable by a keyboard — but present,
   with real dimensions, because Stripe reads it rather than being told. */
.g26-shadow{ position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  pointer-events: none; opacity: 0 }

/* Full width from the very first moment, not only once it is shown. Stripe
   measures this box when it mounts and sizes its buttons to what it finds —
   once. Giving the box its real width before Stripe ever looks means the
   buttons come out the width of the panel on their own. */
#wcvcl-express{ height: 0; overflow: hidden; visibility: hidden; pointer-events: none;
  width: 100%; max-width: 100%;
  /* The shop lays this slot out as a grid whose column sizes to its content,
     so the two pay buttons made it 584px inside a 560px card and the panel
     grew a sideways scrollbar. minmax(0, 1fr) says the column is the card's
     width and the content fits into it, not the other way round. */
  grid-template-columns: minmax(0, 1fr) }
/* The shop's stylesheet lays this slot out as a row of max-content columns and
   forces `width: auto !important` on whatever is inside it — which for an empty
   container means no width at all, and Stripe will not build a button into a
   box of nothing. min-width is not on that list, so it is what gives the
   container a real size to be born into. */
#wcvcl-express > #wc-stripe-express-checkout-element{
  min-width: 240px; min-height: 48px;
  width: 100%; max-width: 100%;
  display: flex; flex-direction: column; align-items: center; gap: 8px }
#wcvcl-express > #wc-stripe-express-checkout-element > *{
  width: 100%; max-width: 420px; margin-left: auto; margin-right: auto }
#wcvcl-express.ready{ height: auto; overflow: visible; visibility: visible;
  pointer-events: auto; margin-top: 12px }

/* Scarcity, set as a chip rather than as a footnote. On a sheet this quiet,
   contrast does the work that size would otherwise have to. */
.g26-left{ display: inline-flex; align-items: center; margin-left: 10px;
  font-size: 11px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: #B23C08; background: rgba(255,82,14,.11);
  border: 1px solid rgba(255,82,14,.30);
  padding: 4px 9px; border-radius: 999px; line-height: 1; white-space: nowrap;
  vertical-align: middle }

.tmmount .wcvcl-bottombar{ justify-content: space-between; align-items: center; gap: 14px }
/* the amount must not break across two lines — a price split down the middle
   reads as two prices */
.tmmount .wcvcl-bottom-total{ color: #fff; white-space: nowrap; flex: none }
.tmmount .wcvcl-direct-btn{ flex: 1; text-align: center }

/* The description behind the ⓘ spans the whole row.
   The row is a two-column grid — details on the left, stepper on the right —
   and the description arrives as a third grid item, so it landed underneath
   the details in the narrow column and wrapped over five lines while the space
   beside the stepper stayed empty. Told to span both columns it reads in two. */
.tmbox .wcvcl-row .wcvcl-desc-row,
.tmmount .wcvcl-row .wcvcl-desc-row { grid-column: 1 / -1; }


@media (max-width: 640px) {
  /* Near the top, not floated at the bottom. Seven ticket types plus a header
     do not fit in the lower two thirds of a phone, and what was left over was
     a band of dead page above a panel already scrolled past its own title. */
  .tmodal{ padding: 0; align-items: start; padding-top: 8px }
  .tmbox{ width: 100%; max-height: calc(100vh - 16px); max-height: calc(100svh - 16px);
    padding: 0 0 10px }
  .g26-tickethead{ padding: 4px 60px 14px 16px }
  .g26-tktfacts{ gap: 26px }
  /* the way out stays on screen, whatever the list is doing underneath */
  .tmbox .vclose{ position: fixed; top: 14px; right: 14px; float: none; margin: 0;
    background: rgba(10,10,12,.72); backdrop-filter: blur(8px) }
}

/* Known duplication: gravity-2026.css still carries its own copy of these
   rules for the Opera page. Merging the two means editing the stylesheet of a
   page that is selling tickets today, so it wants its own change and its own
   test — not a side effect of getting Techno working. */
