/* ------------------------------------------------------------------
   custom.css — hand-written layer for what Tailwind can't express:
   illustration layer utilities, clip paths, complex keyframes.
   Tokens live in tailwind.config.js; CSS custom properties here are
   only the ones the illustration manifest partial emits per element.
   ------------------------------------------------------------------ */

/* Page wrapper: clip (not hidden) so no scroll container is created —
   keeps position:sticky and ScrollTrigger pinning working (§5.4). */
.page-wrap {
  overflow-x: clip;
}

/* Every section is a positioning context for its illustration layers. */
.section {
  position: relative;
  isolation: isolate;
}

/* Illustration layer. Per-breakpoint geometry arrives as CSS custom
   properties set inline by the manifest partial (illustrations.php);
   media queries below swap which set is active. Rotation values are
   already CSS-sign (Figma value negated) when written to the manifest. */
.illu {
  position: absolute;
  pointer-events: none;
  will-change: transform;
  top: var(--illu-top);
  /* A layer may anchor to the bottom edge instead (manifest "bottom" with
     top "auto") — the right choice for art that must sit on the floor of a
     section whose height does not track its width. */
  bottom: var(--illu-bottom, auto);
  left: var(--illu-left);
  width: var(--illu-width);
  height: auto;
  z-index: var(--illu-z, 0);
  opacity: var(--illu-opacity, 1);
  transform: rotate(var(--illu-rotate, 0deg)) scaleY(var(--illu-flipy, 1));
  mix-blend-mode: var(--illu-blend, normal);
}

@media (max-width: 767px) {
  .illu {
    top: var(--illu-top-m, var(--illu-top));
    bottom: var(--illu-bottom-m, var(--illu-bottom, auto));
    left: var(--illu-left-m, var(--illu-left));
    width: var(--illu-width-m, var(--illu-width));
    transform: rotate(var(--illu-rotate-m, var(--illu-rotate, 0deg))) scaleY(var(--illu-flipy, 1));
    opacity: var(--illu-opacity-m, var(--illu-opacity, 1));
  }
  .illu[data-mobile="hide"] {
    display: none;
  }
}

/* Tablet band (768-1439). Entries may carry their own "tablet" geometry in the
   manifest; without one they simply inherit the desktop values, which is what
   every layer did before this band existed. `data-desktop="hide"` keeps its
   original meaning of "not shown above mobile", so the partial also stamps
   data-tablet="hide" on those. */
@media (min-width: 768px) and (max-width: 1439px) {
  .illu {
    top: var(--illu-top-t, var(--illu-top));
    bottom: var(--illu-bottom-t, var(--illu-bottom, auto));
    left: var(--illu-left-t, var(--illu-left));
    width: var(--illu-width-t, var(--illu-width));
    transform: rotate(var(--illu-rotate-t, var(--illu-rotate, 0deg))) scaleY(var(--illu-flipy, 1));
    opacity: var(--illu-opacity-t, var(--illu-opacity, 1));
  }
  .illu[data-tablet="hide"] {
    display: none;
  }
}

@media (min-width: 1440px) {
  .illu[data-desktop="hide"] {
    display: none;
  }
}

/* Anchor targets (the nav's /#story, /#gallery, /#faq) must stop below the
   fixed header instead of under it. --banner-h is measured by navbar.js; the
   82px fallback is the header's height at the design sizes, so this works
   before JS runs and with JS off. */
.section[id] {
  scroll-margin-top: calc(var(--banner-h, 82px) + 16px);
}

/* Sections whose illustrations intentionally bleed past their edge (§5.4). */
.section-bleed {
  overflow: visible;
}

/* Light-beam sections. The beams are negative-z manifest layers that must
   paint BEHIND the section's content (trailer video, private-event card) but
   still blend (screen) against the page backdrop and shine across section
   boundaries. That requires (a) no isolation — an isolated group would trap
   the blend and render the beam's black plate as an opaque box on any
   overhang — and (b) no opaque section background, since a negative-z child
   paints behind its own section's background (the body supplies the same
   #050505). */
#trailer,
#private-event,
#faq,
#selector {
  isolation: auto;
  background: transparent;
}

/* The banner is rendered inside each page's #hero. `.section`'s
   isolation:isolate would trap the fixed header in the hero's stacking
   context, so later sections (story, gallery…) paint over it as you scroll.
   No hero carries negative-z illustration layers, so dropping isolation here
   is visually inert and lets the header's z-index compete page-wide. */
#hero {
  isolation: auto;
}

/* Footer ≥1920: the plant/glow layers are sized as a percentage of the footer
   WIDTH (manifest), so on very wide screens they outgrow the fixed 493px
   frame and get clipped. Above the design width the footer height tracks the
   viewport at the Figma ratio (493/1440) so the arrangement stays whole. */
@media (min-width: 1920px) {
  footer.section {
    height: 34.24vw;
  }
}

/* CTA background photo. Two knobs, both here so the section can be retuned
   without touching markup:
     --cta-photo-drop  how far below the section top the photo starts. The photo
                       is pinned to the BOTTOM edge and its band shortened from
                       the top, so raising this lowers the photo (and its subject)
                       without pushing the stage floor out of the section — which
                       is what a margin on this absolutely positioned image would
                       have done.
     --cta-scrim       how far down the dark field behind the copy reaches. It
                       stays fully opaque to 62% of that distance — past the
                       bottom of the button — then fades, so the photo only
                       emerges below the copy and never sits behind type. */
#cta {
  --cta-photo-drop: 150px;
  --cta-scrim: 720px;
}
.cta-photo {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: calc(100% - var(--cta-photo-drop));
  object-fit: cover;
  object-position: bottom;
}
.cta-scrim {
  height: var(--cta-scrim);
  background: linear-gradient(
    to bottom,
    #050505 0%,
    #050505 62%,
    rgba(5, 5, 5, 0) 100%
  );
}
/* Below 1440 the headline is capped at 391px and wraps to two lines (it only
   goes single-line at dt:, where max-width becomes 691px), so the copy runs
   ~36px lower and needs correspondingly more clear space. Keyed to the dt
   breakpoint, not md — at 768-1439 the headline still wraps. */
@media (max-width: 1439px) {
  #cta {
    --cta-photo-drop: 190px;
    --cta-scrim: 790px;
  }
}
/* The viewport-tracking height that used to live here (min(63.1944vw, 1213px),
   which kept the cover crop proportional above 1440) is gone: the section is a
   flat 1200px at every width now (owner 2026-08-10), and at that height there is
   enough room for the photo without rescaling the frame. */

/* §8 touch targets (Phase 6): on coarse pointers, every interactive element
   gets an invisible centered hit area of at least 44x44 via a pseudo-element —
   no visual or layout change, and desktop (fine pointer) is untouched.
   :where() keeps specificity at 0 so any Tailwind positioning class wins. */
@media (pointer: coarse) {
  :where(a, button, summary, [role="button"], label) {
    position: relative;
  }
  :where(a, button, summary, [role="button"], label)::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    height: 100%;
    min-width: 44px;
    min-height: 44px;
  }
}

/* Sticky navbar: dark backdrop once the page scrolls (toggled by navbar.js).
   Attribute+class selector outranks the Tailwind bg utilities on the header. */
header[data-banner] {
  transition: background-color 0.25s ease;
}
header[data-banner].banner-scrolled {
  background-color: #050505;
}

/* Mobile menu panel (banner.php, driven by navbar.js).
   The clip's height animates, so the panel unfurls from under the header
   instead of appearing whole. visibility is transitioned too — with a delay
   on close so it lasts the slide, and instantly on open — which keeps the
   links out of the tab order while the menu is shut, something height alone
   would not do. Reduced motion is handled by the global kill switch at the
   bottom of this file. */
.mobile-menu-clip {
  height: 0;
  overflow: hidden;
  visibility: hidden;
  transition: height 0.28s ease, visibility 0s linear 0.28s;
}
.mobile-menu-clip[data-open] {
  height: 364px;
  visibility: visible;
  transition: height 0.28s ease, visibility 0s;
}
@media (min-width: 768px) {
  .mobile-menu-clip {
    display: none !important;
  }
}

/* Open menu: the header wears the panel's colour so the two read as one
   surface. Must outrank .banner-scrolled, which is otherwise painting #050505
   by the time the menu is used. */
header[data-banner].banner-menu-open,
header[data-banner].banner-menu-open.banner-scrolled {
  background-color: #1a1716;
}

/* One glyph per state on the toggle. */
[data-menu-icon="close"],
[aria-expanded="true"] [data-menu-icon="open"] {
  display: none;
}
[aria-expanded="true"] [data-menu-icon="close"] {
  display: block;
}

/* Booking form popovers (booking.js) — minimal menus, existing token colors,
   square corners, no animation (brief: nothing between click and result). */
.booking-popover {
  position: absolute;
  left: 0;
  top: 100%;
  z-index: 30;
  margin-top: 4px;
  min-width: 100%;
  max-height: 264px;
  overflow-y: auto;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: #211d1b;
}
.booking-popover [role="menuitemradio"] {
  display: block;
  width: 100%;
  padding: 8px 21px;
  text-align: left;
  font-size: 14px;
  line-height: 21.6px;
  color: #fff;
  white-space: nowrap;
}
.booking-popover [role="menuitemradio"]:hover,
.booking-popover [role="menuitemradio"]:focus-visible {
  background: #2c2624;
}

/* Language menu (banner) — same skin as the booking popovers, right-aligned
   under the EN/ID toggle. */
.lang-popover {
  left: auto;
  right: 0;
  min-width: 92px;
}

/* Sticky booking form: once the form row reaches the header it parks below
   it. --banner-h is the measured header height (booking.js). The hairline
   under the row spans the full viewport in the stuck state (owner request);
   at rest it keeps the Figma 1114px content width. */
#booking-form {
  position: sticky;
  top: var(--banner-h, 82px);
}
#booking-form.is-stuck {
  background-color: #050505;
  padding-top: 16px;
}
#booking-form.is-stuck [data-form-rule] {
  width: 100vw;
  margin-left: calc(50% - 50vw);
}

/* Detail modal (category "Read More Details"). The copy runs long, so the body
   scrolls inside the panel while the title row stays put. */
.detail-modal {
  width: min(552px, calc(100vw - 32px));
  max-height: min(760px, calc(100vh - 64px));
  padding: 24px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: #1a1716;
  color: #fff;
}
.detail-modal::backdrop {
  background: rgba(5, 5, 5, 0.72);
}
.detail-modal [data-detail-body] {
  max-height: min(640px, calc(100vh - 148px));
  overflow-y: auto;
  overscroll-behavior: contain;
}
.detail-modal__lede {
  font-size: 15px;
  line-height: 23.25px;
  color: rgba(255, 255, 255, 0.72);
}
.detail-modal__heading {
  margin-top: 24px;
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 500;
  line-height: 18px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}
.detail-modal__rates > div {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 7px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.detail-modal__rates dd {
  color: #fff;
  text-align: right;
}
.detail-modal__list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.detail-modal__list li {
  position: relative;
  padding-left: 18px;
}
.detail-modal__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 9px;
  width: 5px;
  height: 5px;
  border-radius: 2.5px;
  background: #dca85d; /* tailwind.config.js → colors.gold */
}
.detail-modal__note {
  margin-top: 8px;
  font-size: 14px;
  line-height: 21px;
  color: rgba(255, 255, 255, 0.55);
}
.detail-modal__note--warn {
  color: #e6b8a2;
}
.detail-modal__note--gold {
  color: #dca85d;
}
.detail-modal__rates dt,
.detail-modal__list,
.detail-modal__list li {
  font-size: 15px;
  line-height: 23.25px;
}

/* Legacy CMS copy (rate / seat / venue descriptions) rendered inside the
   detail and terms modals: the old admin wrote plain <p>/<ol>/<ul> markup, so
   give it the spacing Tailwind's preflight removes. */
.detail-copy p { margin: 0 0 0.6em; }
.detail-copy p:last-child { margin-bottom: 0; }
.detail-copy ol, .detail-copy ul { margin: 0.4em 0 0.8em; padding-left: 1.25em; }
.detail-copy ol { list-style: decimal; }
.detail-copy ul { list-style: disc; }
.detail-copy li { margin: 0.2em 0; }
.detail-copy strong, .detail-copy b { color: #fff; font-weight: 500; }
.detail-copy a { color: #f2e7bb; text-decoration: underline; text-underline-offset: 2px; }
.detail-copy h3, .detail-copy h4, .detail-copy h5 { color: #fff; font-weight: 500; margin: 0.8em 0 0.3em; }

/* The detail modal grew real content: cap it to the viewport and scroll inside. */
.detail-modal { max-height: calc(100vh - 48px); overflow-y: auto; }

/* Dark native controls on the checkout form (select popup, date picker icon). */
#checkout select, #checkout input, #checkout textarea { color-scheme: dark; }
#checkout select option { background: #211d1b; color: #fff; }

/* Seat-map category glow (booking.js toggles glow-* on .seatmap when a
   category card is clicked). Non-matching seats dim so the category pops.
   No effect at rest; reduced motion kills the transition globally. */
.seatmap svg {
  /* The exported diagrams contain huge baked-in background rects that extend
     far past the viewBox; inline they can intercept clicks over other UI.
     The map takes no direct pointer input, so kill hit-testing entirely. */
  pointer-events: none;
  overflow: hidden;
}
.seatmap .seat {
  /* Seats re-enable hit-testing (the parent svg disabled it above) so a click
     on any seat activates its category — same selection as the cards. */
  pointer-events: auto;
  cursor: pointer;
  transition: opacity 0.15s ease, filter 0.15s ease;
}
.seatmap.glow-vip .seat:not(.seat-vip),
.seatmap.glow-a .seat:not(.seat-a),
.seatmap.glow-b .seat:not(.seat-b),
.seatmap.glow-c .seat:not(.seat-c) {
  opacity: 0.35;
}
.seatmap.glow-vip .seat-vip {
  filter: drop-shadow(0 0 6px #e04444) brightness(1.35);
}
.seatmap.glow-a .seat-a {
  filter: drop-shadow(0 0 6px #4ea3e8) brightness(1.35);
}
.seatmap.glow-b .seat-b {
  filter: drop-shadow(0 0 6px #7cb35b) brightness(1.35);
}
.seatmap.glow-c .seat-c {
  filter: drop-shadow(0 0 6px #e8c93f) brightness(1.35);
}

/* Selected category card: 1px gold border via inset shadow (no layout shift). */
[data-category].card-selected {
  box-shadow: inset 0 0 0 1px #dca85d;
}

/* Motion is opt-in: GSAP (Phase 3) must render final state immediately
   under reduced motion. This kills any CSS-side animation too. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

.confirm_hero{
  margin-bottom: 120px;
}

/* Hero teaser popup (phones). Edge-to-edge landscape 16:9 box on a dark
   backdrop; the close control floats above its top-right corner. */
.hero-video {
  /* Full width in portrait; in landscape, as wide as a 16:9 box can be while
     still leaving room for the close control above it (the dialog is centred,
     so the 52px the control needs has to be reserved on both sides). */
  width: min(100vw, calc((100vh - 104px) * 16 / 9));
  max-width: 100vw;
  max-height: 100vh;
  margin: auto;
  padding: 0;
  border: 0;
  background: transparent;
  color: #fff;
  overflow: visible;
}
.hero-video::backdrop {
  background: rgba(5, 5, 5, 0.92);
}
.hero-video__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
}
.hero-video__frame video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.hero-video__close {
  position: absolute;
  right: 12px;
  bottom: calc(100% + 12px);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 9999px;
  background: rgba(255, 255, 255, 0.12);
  font-size: 28px;
  line-height: 1;
  color: #fff;
}
