/* Launch Boarding Pass v4 (2026-07-03): centered scratch-off overlay.
 * All selectors are .gr-bpass scoped so nothing collides with the shared
 * design system. Loaded only on the anonymous landing via the
 * gorocket/boarding_pass.html include. */

/* Light, non-locking veil (2026-07-06 redesign): the page behind stays
   visible + scrollable; the ticket floats and dismisses on X / click-outside. */
/* z-index 1200 (2026-09-01): the site header is sticky at z-index 1000. At
   z-index 90 it painted OVER the ticket, and on a short viewport (360x640,
   revealed state) the card centers high enough that the header covered the
   close X - elementFromPoint returned gr-header__inner, so the visitor could
   not close the pass at all. This is the same failure the 2026-07-18 note
   below describes, arriving by a different route. The overlay is
   pointer-events:none and only the card is clickable, so sitting above the
   header costs nothing while the pass is shut, and dimming the header is
   correct for aria-modal="true" anyway. */
.gr-bpass-overlay { position: fixed; inset: 0; z-index: 1200;
  display: flex; align-items: center; justify-content: center;
  padding: 1.2rem;
  background: rgba(5,20,32,.32);
  -webkit-backdrop-filter: blur(2.5px); backdrop-filter: blur(2.5px);
  /* Non-blocking: the veil renders but lets wheel/click pass to the page so
     it stays scrollable/interactive. The ticket itself re-enables events. */
  pointer-events: none;
  opacity: 0; transition: opacity .3s ease; }
.gr-bpass { pointer-events: auto; }
.gr-bpass-overlay.is-open { opacity: 1; }
.gr-bpass-overlay[hidden] { display: none !important; }

.gr-bpass { position: relative; display: grid; grid-template-columns: 1.55fr auto 1fr; gap: 0;
  width: min(92vw, 760px); margin: auto; color: #fff;
  background: linear-gradient(165deg, #0e3349, #0a2233 68%);
  border-radius: 22px;
  /* drop-shadow (not box-shadow) so the punched notch holes cast correct
     shadow and the mask silhouette stays crisp. */
  filter: drop-shadow(0 24px 48px rgba(0,0,0,.5)) drop-shadow(0 0 26px rgba(255,90,31,.10));
  /* Clean perforation: two real holes punched at the divider (~60.8% across,
     the 1.55fr|1fr grid boundary) so the page behind shows through — no ring,
     no shadow disc. */
  --gr-notch: 13px;
  -webkit-mask:
    radial-gradient(circle var(--gr-notch) at 60.8% calc(0px - var(--gr-notch)*0.15), #0000 calc(var(--gr-notch) - 1px), #000 var(--gr-notch)) no-repeat,
    radial-gradient(circle var(--gr-notch) at 60.8% calc(100% + var(--gr-notch)*0.15), #0000 calc(var(--gr-notch) - 1px), #000 var(--gr-notch)) no-repeat;
  -webkit-mask-composite: source-in; mask-composite: intersect;
  opacity: 0; transform: scale(.94) translateY(12px);
  transition: opacity .4s cubic-bezier(.2,1,.3,1), transform .4s cubic-bezier(.2,1,.3,1); }
.gr-bpass-overlay.is-open .gr-bpass { opacity: 1; transform: none; }

.gr-bpass__close { position: absolute; top: .7rem; right: .8rem; z-index: 4;
  width: 30px; height: 30px; display: grid; place-items: center;
  border: 1px solid rgba(255,255,255,.25); border-radius: 50%;
  background: rgba(5,28,44,.55); cursor: pointer; line-height: 1;
  font-size: 1rem; color: rgba(255,255,255,.75); }
.gr-bpass__close:hover, .gr-bpass__close:focus-visible { color: #fff; border-color: rgba(255,255,255,.6); }

/* Guilloche security texture + subtle inner-highlight border (premium depth). */
.gr-bpass__main { position: relative; padding: 2.2rem 2.4rem; min-width: 0;
  border-radius: 22px 0 0 22px;
  background-image:
    repeating-linear-gradient(60deg, rgba(0,212,255,.05) 0 1px, transparent 1px 9px),
    repeating-linear-gradient(-60deg, rgba(0,212,255,.045) 0 1px, transparent 1px 9px);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); }
.gr-bpass__eyebrow { font-size: .72rem; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: #FF5A1F; }
.gr-bpass__title { margin: .55rem 0 .4rem; font-size: clamp(1.35rem, 2.6vw, 1.75rem); font-weight: 800; }
.gr-bpass__sub { margin: 0 0 1.6rem; font-size: .95rem; color: rgba(255,255,255,.75); max-width: 34ch; }
.gr-bpass__meta { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: .8rem 1.4rem; margin: 0; }
.gr-bpass__meta dt { font-size: .66rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: rgba(255,255,255,.42); margin-bottom: .12rem; }
.gr-bpass__meta dd { margin: 0; font-size: .88rem; font-weight: 600; color: rgba(255,255,255,.88); }
#gr-bpass-status.is-unlocked { color: #FF5A1F; }

/* Just the dashed perforation line; the round holes are punched by the
   .gr-bpass mask (clean, page shows through, no ring/shadow disc). */
.gr-bpass__divider { position: relative; width: 0; border-left: 2px dashed rgba(255,255,255,.22); margin: 1.6rem 0; }

.gr-bpass__stub { position: relative; display: flex; min-width: 0; min-height: 380px; }

/* The scratch surface IS the whole stub: the foil canvas covers it
   edge-to-edge and the prize card + actions live underneath. */
.gr-scratch { position: relative; flex: 1; display: flex; overflow: hidden;
  border-radius: 0 21px 21px 0; }
.gr-scratch__inner { display: flex; flex-direction: column; justify-content: center;
  gap: .8rem; width: 100%; padding: 1.6rem 1.5rem; }
.gr-scratch__prize { position: relative; display: grid; place-items: center; gap: .4rem;
  padding: 1.4rem 1rem 1.6rem; border-radius: 14px; color: #051C2C; overflow: hidden;
  background: radial-gradient(circle at 32% 22%, #ffe0bd, #FF6A24 68%, #ef4f16 100%);
  box-shadow: 0 10px 28px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.4); }
/* Holographic sheen: STATIC (2026-07-29 anti-slop rule - nothing sweeps
   left-to-right over text; the sheen texture itself stays, frozen). */
.gr-scratch__prize::after { content: ""; position: absolute; inset: -40% -10%; pointer-events: none;
  background: linear-gradient(115deg, transparent 40%, rgba(255,255,255,.32) 48%, rgba(120,220,255,.22) 52%, transparent 60%);
  transform: translateX(-12%); mix-blend-mode: screen; }
.gr-bpass__rocket { position: absolute; top: .7rem; left: .8rem; width: 20px; height: 20px;
  color: rgba(5,28,44,.8); }
.gr-scratch__unlocked { font-style: normal; font-size: .62rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: #051C2C;
  border: 1.5px solid rgba(5,28,44,.55); border-radius: 999px; padding: .3rem .8rem; }
.gr-scratch__unlocked[hidden] { display: none !important; }
.gr-scratch__off { font-size: .82rem; font-weight: 700; letter-spacing: .04em; opacity: .9;
  text-align: center; padding: 0 .4rem; }
.gr-scratch__mask, .gr-scratch__code {
  font-family: "SF Mono", ui-monospace, Menlo, Consolas, monospace;
  font-size: 2rem; letter-spacing: .1em; font-weight: 800; }
.gr-scratch__code[hidden] { display: none !important; }
.gr-scratch__cover { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 3;
  cursor: grab; touch-action: none; transition: opacity .45s ease; }
.gr-scratch__cover.is-cleared { opacity: 0; pointer-events: none; }
/* Entrance shine sweep + trail draw REMOVED (2026-07-29 anti-slop rule -
   no lines or shines moving left-to-right over text; grBpIn's fade is the
   whole entrance now). The sweep/trail markup stays inert. */
.gr-scratch__sweep { display: none; }
.gr-bpass__trail { display: none; }
.gr-bpass.is-revealed .gr-scratch { animation: grBpPulse .5s ease 1; }
@keyframes grBpPulse { 40% { transform: scale(1.015); } }

.gr-bpass__actions { display: flex; flex-direction: column; align-items: stretch; gap: .55rem;
  width: 100%; animation: grBpIn .35s ease; }
.gr-bpass__actions[hidden] { display: none !important; }
@keyframes grBpIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.gr-bpass__cta { width: 100%; text-align: center; }
.gr-bpass__code { background: transparent; border: 1px dashed rgba(255,255,255,.35); color: rgba(255,255,255,.85);
  border-radius: 999px; padding: .55rem 1rem; font-size: .82rem; cursor: pointer;
  font-family: "SF Mono", ui-monospace, Menlo, Consolas, monospace; }
.gr-bpass__code:hover { border-color: #FF5A1F; }
.gr-bpass__code strong { letter-spacing: .1em; }
.gr-dust { position: absolute; width: 3px; height: 3px; border-radius: 50%; pointer-events: none;
  background: rgba(255,255,255,.8); animation: grDust .6s ease-out forwards; }
@keyframes grDust { to { opacity: 0; transform: translateY(-14px) scale(.4); } }

@media (max-width: 640px) {
  /* Stacked: panels sit vertically with a horizontal perforation. Drop the
     desktop vertical-notch mask (page-behind punch is a desktop nicety).
     2026-07-18: the WHOLE ticket must fit one phone viewport with no inner
     scrolling - the close X used to scroll away inside overflow-y:auto and
     became unreachable. svh + clamp() shrink the content instead. */
  .gr-bpass { grid-template-columns: 1fr; width: min(94vw, 420px);
    max-height: calc(100svh - 1.6rem); overflow: hidden;
    -webkit-mask: none; mask: none; }
  .gr-bpass__divider { width: auto; height: 0; border-left: 0; border-top: 2px dashed rgba(255,255,255,.22); margin: 0 1.2rem; }
  .gr-bpass__main { padding: 1.1rem 1.2rem .9rem; border-radius: 22px 22px 0 0; }
  .gr-bpass__title { font-size: clamp(1.05rem, 4.5vw, 1.3rem); margin: .4rem 0 .3rem; }
  .gr-bpass__sub { font-size: .82rem; margin: 0 0 .8rem; }
  /* Keep Mission + Status; Gate/Class are flavor and cost two rows. */
  .gr-bpass__meta { gap: .5rem .9rem; }
  .gr-bpass__meta div:nth-child(2), .gr-bpass__meta div:nth-child(3) { display: none; }
  .gr-bpass__stub { min-height: clamp(180px, 36svh, 300px); }
  .gr-scratch { border-radius: 0 0 21px 21px; }
  .gr-scratch__inner { padding: 1rem 1.1rem; gap: .6rem; }
  .gr-scratch__prize { padding: 1rem .8rem 1.1rem; }
  .gr-scratch__mask, .gr-scratch__code { font-size: 1.6rem; }
  /* Bigger, always-visible close target (no inner scroll to lose it behind). */
  .gr-bpass__close { width: 36px; height: 36px; font-size: 1.15rem; }
}

/* Short phones (360x640 and similar). The ticket is capped at the viewport
   with overflow:hidden, so its LAST line gets clipped - and that line is the
   privacy notice. Measured 2026-09-01: it overflowed by 31px before the v7
   reorder and 11px after, on both. Reclaim the difference from the prize
   block, which is the most generously padded element on the stub. Taller
   phones (375x812) never matched this and are untouched. */
@media (max-width: 640px) and (max-height: 700px) {
  .gr-bpass__stub { min-height: clamp(150px, 30svh, 240px); }
  .gr-scratch__inner { padding: .8rem 1rem; gap: .45rem; }
  .gr-scratch__prize { padding: .7rem .8rem .8rem; }
  .gr-scratch__mask, .gr-scratch__code { font-size: 1.35rem; }
  .gr-bpass__main { padding: .9rem 1.1rem .7rem; }
}

/* Full-scratch rocket-fire celebration (visual only). A canvas overlays the
   stub; JS paints an orange/yellow flame plume + spark particles for ~1.2s. */
.gr-bpass__spark { position: absolute; inset: 0; z-index: 5; pointer-events: none;
  opacity: 0; transition: opacity .2s ease; }
.gr-bpass__spark.is-firing { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .gr-bpass-overlay { transition: none; }
  .gr-bpass { transition: none; opacity: 1; transform: none; }
  .gr-bpass-overlay.is-open .gr-scratch__sweep, .gr-bpass.is-revealed .gr-scratch,
  .gr-bpass.is-revealed .gr-bpass__trail path, .gr-scratch__prize::after { animation: none; }
  .gr-bpass.is-revealed .gr-bpass__trail { display: none; }
  .gr-bpass__spark { display: none; }
}

/* Lead capture inside the pass (2026-08-13). Deliberately quiet: it must
   read as a convenience under the revealed code, never as a second CTA
   competing with "Claim launch bonus". */
/* 2026-09-01: the email is the DELIVERY step now, not a footnote, so its
   label wears the ticket's own field styling (same uppercase micro-caps as
   the Mission / Gate / Class labels on the main panel). Reads as a line on
   the pass rather than a form bolted under it. */
.gr-bpass__lead { margin-top: 2px; }
.gr-bpass__lead-label { display: block; font-size: .66rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: rgba(255,255,255,.42);
  margin-bottom: 6px; }
.gr-bpass__lead-row { display: flex; gap: 8px; }
.gr-bpass__lead-input {
  flex: 1 1 auto; min-width: 0; padding: 9px 11px; border-radius: 8px;
  border: 1px solid rgba(255,255,255,.28); background: rgba(255,255,255,.06);
  color: #fff; font-size: 14px;
}
.gr-bpass__lead-input::placeholder { color: rgba(255,255,255,.45); }
/* 2026-09-01: the DESKTOP stub is the narrowest column (1.55fr auto 1fr),
   so the row is tightest there, not on mobile. The default btn padding left
   the input at 134px against a 149px placeholder and clipped it to
   "you@company.co". Trim the button, not the field. */
.gr-bpass__lead-btn { flex: 0 0 auto; padding-left: .85rem; padding-right: .85rem;
  font-size: .85rem; }
.gr-bpass__lead-status { font-size: 12.5px; margin: 6px 0 0; min-height: 1.2em; opacity: .9; }
.gr-bpass__lead-fineprint { font-size: 11.5px; opacity: .6; margin: 0; text-align: center; }
.gr-bpass__lead-fineprint a { color: inherit; text-decoration: underline; }
.gr-bpass__lead.is-sent .gr-bpass__lead-row { display: none; }
