/* ════════════════════════════════════════════
   Memoroam — Collector's Pass paywall  (WIREFRAME)
   Prefix: pw-   ·   Logic: js/pass/pass-paywall.js

   One sheet, two hosts:
     #authPassPaywall .pw-sheet — full bleed inside the auth overlay
     #pwOverlay .pw-sheet       — rounded sheet that slides up over the app

   Structure follows the Duolingo Super reference: saturated full-bleed
   gradient hero carrying the art and the claim, a wave cutting back to the
   page colour, then the comparison table on paper, then a chunky button with
   a solid bottom edge.

   ⚠ COLOUR RULE. Everything standing on the sky uses FIXED light values, not
   theme variables. The sky is dark in both themes, so a var(--card) passport
   would be invisible in dark mode. Only .pw-wave follows the theme, because
   its whole job is to match the content area behind it.

   House rules observed: no :has() anywhere (the WebView drops it), no
   backdrop-filter, no conic gradients, and every animation is transform or
   opacity only.
   ════════════════════════════════════════════ */

/* Fixed palette for the hero. Not themed, on purpose.
   The sky is deliberately DARKER than the passport cover it carries
   (#1C2333 to #2A3142), so the object reads as lit rather than lost. */
:root {
  --pw-sky-1: #262E4C;
  --pw-sky-2: #171D31;
  --pw-sky-3: #0F1320;
  /* The passport's own leather + foil, lifted from .passport-cover /
     .passport-crest in profile.css so the hero object matches the product. */
  --pw-leather-1: #1C2333;
  --pw-leather-2: #2A3142;
  --pw-foil: #C8A96E;
  --pw-paper: #F7F1E6;
  --pw-gold: #C68A3A;
  --pw-gold-lt: #E4C489;
}

/* ── Shared sheet ── */
.pw-sheet {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  min-height: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  overflow: hidden;
}

.pw-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
.pw-body { padding: 0 20px 22px; }

/* Sits on the dark sky, so it is translucent white rather than a card. */
.pw-close {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: 14px;
  z-index: 4;
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: rgba(255,255,255,.16);
  color: #fff;
  cursor: pointer;
  transition: opacity .15s;
}
.pw-close:active { opacity: .6; }

/* ════════════════════════════════════════════
   Hero
   ════════════════════════════════════════════ */
.pw-hero { position: relative; }

.pw-sky {
  position: relative;
  padding: calc(30px + env(safe-area-inset-top, 0px)) 20px 0;
  background: linear-gradient(170deg,
              var(--pw-sky-1) 0%,
              var(--pw-sky-2) 55%,
              var(--pw-sky-3) 100%);
  overflow: hidden;
}
/* Vignette. Without it the flat gradient reads as a coloured block rather than
   as space, which is most of what made the first pass look printed on. */
.pw-sky::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 120% 80% at 50% 34%,
              rgba(0,0,0,0) 0%,
              rgba(0,0,0,.18) 62%,
              rgba(0,0,0,.42) 100%);
  pointer-events: none;
}

/* ── Stage: the passport and its stamps ── */
/* Hero-to-table proportion lives here and in .pw-hero-copy's padding. These
   two numbers are the dial if the table feels pushed too far down the sheet. */
.pw-stage { position: relative; height: 196px; }

.pw-glow {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 280px;
  height: 220px;
  margin: -112px 0 0 -140px;
  background: radial-gradient(ellipse at center,
              rgba(200,169,110,.26) 0%,
              rgba(200,169,110,.09) 44%,
              rgba(200,169,110,0) 70%);
  pointer-events: none;
}

/* The real cover: same leather gradient, foil crest and letterspaced mono
   titles as .passport-cover in profile.css. True passport proportion (0.70). */
.pw-book {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 104px;
  height: 149px;
  margin: -74px 0 0 -52px;
  border-radius: 11px;
  background: linear-gradient(145deg,
              var(--pw-leather-1) 0%,
              var(--pw-leather-2) 40%,
              var(--pw-leather-1) 100%);
  /* Hairline of foil around the edge. This is what separates a dark object
     from a dark ground; without it the passport dissolves into the sky. */
  box-shadow: inset 0 0 0 1px rgba(200,169,110,.42),
              0 24px 44px rgba(0,0,0,.55),
              0 6px 14px rgba(0,0,0,.34);
  transform: rotate(-5deg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
}
.pw-crest { width: 46px; height: 46px; color: var(--pw-foil); opacity: .9; }
.pw-book-title {
  font-family: var(--font-mono);
  font-size: 8px;
  font-weight: 600;
  letter-spacing: 2.4px;
  text-transform: uppercase;
  color: var(--pw-foil);
}
.pw-book-sub {
  margin-top: -4px;
  font-family: var(--font-mono);
  font-size: 6.5px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: rgba(200,169,110,.5);
}

/* Real stamp silhouette from the shared clip-path in index.html, so these
   match every earned stamp in the app. drop-shadow, never box-shadow: only
   the filter follows a clipped shape. */
.pw-stamp {
  position: absolute;
  top: 50%;
  width: 64px;
  height: 76px;
  margin-top: -40px;
  background:
    radial-gradient(circle at 50% 46%, rgba(200,169,110,.20) 0%, rgba(200,169,110,0) 58%),
    var(--pw-paper);
  clip-path: url(#stampShape);
  filter: drop-shadow(0 12px 20px rgba(0,0,0,.48));
}
.pw-stamp::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 46%;
  width: 26px;
  height: 26px;
  margin: -13px 0 0 -13px;
  border-radius: 50%;
  border: 1.5px solid var(--pw-gold);
  opacity: .5;
}
.pw-stamp-a { left: 50%; margin-left: -96px; transform: rotate(-13deg); }
.pw-stamp-b { left: 50%; margin-left: 34px;  transform: rotate(11deg);  }

/* Static. An always-running keyframe here is exactly the always-on animation
   debt B1 spent a session stripping out of the Store sheet. */
.pw-spark { position: absolute; fill: var(--pw-gold-lt); pointer-events: none; }
.pw-spark-1 { width: 15px; height: 15px; left: 50%; margin-left: 58px;   top: 22px;  opacity: .8; }
.pw-spark-2 { width: 9px;  height: 9px;  left: 50%; margin-left: -104px; top: 150px; opacity: .5; }

/* ── Claim ── */
.pw-hero-copy { position: relative; z-index: 1; text-align: center; padding: 18px 0 46px; }
.pw-eyebrow {
  margin-bottom: 12px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--pw-foil);
}
.pw-claim {
  margin: 0 auto;
  max-width: 300px;
  font-family: var(--font-heading);
  font-size: 27px;
  font-weight: 500;
  line-height: 1.26;
  letter-spacing: -.005em;
  color: #F5F1EA;
}
.pw-claim-hi { color: var(--pw-gold-lt); font-style: italic; }

/* Cuts the sky back to whatever the content area is painted with, so this one
   IS themed. Sits flush at the bottom of the gradient. */
.pw-wave {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  width: 100%;
  height: 40px;
  display: block;
  fill: var(--bg);
}

/* ════════════════════════════════════════════
   Free vs Pass table
   No card, no shadow, no row borders. The first pass had all three plus a
   tinted column, and four competing containers is most of what read as busy.
   Only two things separate rows now: air, and one hairline.
   ════════════════════════════════════════════ */
.pw-table { margin: 10px 0 26px; }

.pw-row {
  display: grid;
  grid-template-columns: 1fr 62px 80px;
  align-items: center;
  min-height: 46px;
  padding: 0 2px 0 4px;
}
.pw-row + .pw-row { border-top: 1px solid var(--border); }
.pw-row-head { min-height: 38px; border-top: none; }

.pw-row-label {
  font-size: 14px;
  line-height: 1.32;
  padding: 11px 10px 11px 0;
  color: var(--text);
}
.pw-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  font-size: 12.5px;
}

/* Column headers borrow the passport's own mono letterspacing rather than a
   bold sans, which is what ties this table to the rest of the product. */
.pw-cell-free {
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}
.pw-row:not(.pw-row-head) .pw-cell-free {
  font-family: var(--font-body);
  font-size: 12.5px;
  letter-spacing: 0;
  text-transform: none;
}

/* The paid column is one quiet panel down the table so the eye reads it as a
   single product. Deliberately faint: at the previous strength it looked like
   a highlighter stripe. */
.pw-cell-pass { background: rgba(198,138,58,.055); }
.pw-row:first-child .pw-cell-pass { border-radius: 12px 12px 0 0; }
.pw-row:last-child  .pw-cell-pass { border-radius: 0 0 12px 12px; }

/* Flat foil, no gradient and no shadow. The gradient pill read as plastic. */
.pw-badge {
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--pw-gold);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
}

.pw-val { font-weight: 600; color: var(--text); text-align: center; line-height: 1.25; }
.pw-cell-free .pw-val { color: var(--muted-strong); font-weight: 400; }

.pw-tick { width: 17px; height: 17px; color: var(--gold); }

/* "Not included". A dot, never a dash: dash characters are banned in
   user-facing copy and this is the cell that would otherwise want one. */
.pw-no {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--muted);
  opacity: .32;
}

/* ════════════════════════════════════════════
   Plan cards
   Apple 3.1.2: the full renewal price is the largest thing on the card and
   the per-month breakdown sits under it, smaller and quieter. Do not invert.
   ════════════════════════════════════════════ */
.pw-plans { display: flex; flex-direction: column; gap: 10px; }

.pw-plan {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 15px 14px 14px;
  border: 2px solid var(--border);
  border-radius: 16px;
  background: var(--card);
  font-family: var(--font-body);
  text-align: left;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.pw-plan.is-selected {
  border-color: var(--gold);
  background: rgba(198,138,58,.05);
}
.pw-plan:active { opacity: .9; }

.pw-plan-radio {
  flex-shrink: 0;
  width: 21px;
  height: 21px;
  border-radius: 50%;
  border: 2px solid var(--border);
  transition: border-color .15s, box-shadow .15s;
}
.pw-plan.is-selected .pw-plan-radio {
  border-color: var(--gold);
  box-shadow: inset 0 0 0 4px var(--gold);
}

.pw-plan-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pw-plan-price {
  font-family: var(--font-mono);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--text);
}
.pw-plan-per {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--muted-strong);
}
.pw-plan-breakdown { font-size: 11.5px; color: var(--muted); }

.pw-plan-badge {
  position: absolute;
  top: 14px;
  right: 14px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--pw-gold);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
}

/* ════════════════════════════════════════════
   Pinned footer
   Holds the price restatement and the restore entry, so both stay on screen
   at every scroll position. That is the half of 3.1.2 a scrolling paywall
   normally fails.
   ════════════════════════════════════════════ */
.pw-foot {
  flex-shrink: 0;
  padding: 12px 20px calc(10px + env(safe-area-inset-bottom, 0px));
  background: var(--bg);
  border-top: 1px solid var(--border);
}

/* Deep ink, matching .si-submit and .ob-continue, which are already this app's
   primary button. The reference's saturated slab with a solid bottom edge is
   game-app language and was the single cheapest-looking element on the screen;
   gold is worth more here as an accent than as a surface. */
.pw-cta {
  width: 100%;
  height: 56px;
  border: none;
  border-radius: 16px;
  background: var(--text);
  color: #fff;
  font-family: var(--font-body);
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: .01em;
  cursor: pointer;
  box-shadow: 0 8px 22px rgba(28,23,19,.20);
  transition: opacity .15s ease, box-shadow .15s ease;
}
.pw-cta:active { opacity: .86; box-shadow: 0 3px 10px rgba(28,23,19,.18); }

.pw-fine {
  margin-top: 11px;
  font-size: 11.5px;
  line-height: 1.35;
  text-align: center;
  color: var(--muted);
}

/* Muted, not a second gold button. A bold accent-coloured decline competes
   with the CTA and makes the pair read as two equal offers. */
.pw-decline {
  display: block;
  width: 100%;
  padding: 11px 0 7px;
  border: none;
  background: none;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--muted-strong);
  text-align: center;
  cursor: pointer;
}
.pw-decline:active { opacity: .6; }

.pw-rail {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
}
.pw-link {
  border: none;
  background: none;
  padding: 2px 0;
  font-family: var(--font-body);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--muted-strong);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.pw-link:active { opacity: .6; }
.pw-rail-dot {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--muted);
  opacity: .5;
}

/* ── Toast (self contained: the shared toasts mount into page containers
      that do not exist behind the auth overlay) ── */
.pw-toast {
  position: absolute;
  left: 50%;
  bottom: 178px;   /* clears the pinned footer */
  z-index: 6;
  max-width: 82%;
  padding: 10px 16px;
  border-radius: 12px;
  background: var(--text);
  color: var(--bg);
  font-size: 13px;
  font-weight: 500;
  text-align: center;
  opacity: 0;
  transform: translate(-50%, 8px);
  pointer-events: none;
  transition: opacity .2s ease, transform .2s ease;
}
.pw-toast.is-on { opacity: .96; transform: translate(-50%, 0); }

/* ════════════════════════════════════════════
   Settings drawer pill
   Rounded pill, mark left, label centred — the Pokemon TCG Pocket pass button
   shape. Free state is a CTA painted from the paywall's own sky so the tap
   lands somewhere that looks like where it came from; member state is quiet
   paper, because status is not an offer.
   ════════════════════════════════════════════ */
.pw-upsell {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  margin: 4px 0 18px;
  padding: 13px 14px;
  border: none;
  border-radius: 999px;
  background: linear-gradient(150deg, var(--pw-sky-1) 0%, var(--pw-sky-2) 60%, var(--pw-sky-3) 100%);
  font-family: var(--font-body);
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(21,26,46,.30);
  transition: transform .1s ease, box-shadow .1s ease;
}
.pw-upsell:active {
  transform: translateY(1px);
  box-shadow: 0 2px 8px rgba(21,26,46,.26);
}

.pw-upsell-mark {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(232,184,113,.16);
}
.pw-upsell-mark svg { width: 16px; height: 16px; fill: var(--pw-gold-lt); }

/* Centred in the pill, not left aligned beside the mark — that is what makes
   the reference read as a pass rather than as another settings row. The mark
   is 30px and the chevron 18px, so the label is nudged to sit optically
   centred between them. */
.pw-upsell-label {
  flex: 1;
  text-align: center;
  padding-left: 12px;
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: .01em;
  color: #fff;
}
.pw-upsell-chev { flex-shrink: 0; width: 18px; height: 18px; color: rgba(255,255,255,.55); }

/* ── Member state ── */
.pw-upsell.is-member {
  background: var(--card);
  border: 1.5px solid var(--gold);
  box-shadow: 0 2px 8px rgba(198,138,58,.16);
}
.pw-upsell.is-member .pw-upsell-mark { background: rgba(198,138,58,.12); }
.pw-upsell.is-member .pw-upsell-mark svg { fill: var(--gold); }
.pw-upsell.is-member .pw-upsell-label { color: var(--text); padding-left: 44px; }
.pw-upsell-tag {
  flex-shrink: 0;
  padding: 4px 10px;
  border-radius: 999px;
  background: linear-gradient(180deg, var(--pw-gold-lt), var(--pw-gold));
  color: #fff;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
}

/* ════════════════════════════════════════════
   Host 1 — onboarding screen (full bleed)
   ════════════════════════════════════════════ */
#authPassPaywall { padding: 0; }
/* .auth-screen is a column flex container, so the sheet needs to claim the
   track explicitly. height:100% alone leaves it free to shrink to content. */
#authPassPaywall .pw-sheet { border-radius: 0; flex: 1; min-height: 0; }

/* ════════════════════════════════════════════
   Host 2 — occasional pop-up (slide-up sheet)
   ════════════════════════════════════════════ */
.pw-overlay {
  position: fixed;
  inset: 0;
  z-index: 10050;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.pw-scrim {
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,.45);
  opacity: 0;
  transition: opacity .3s ease;
}
.pw-overlay.open .pw-scrim { opacity: 1; }

.pw-overlay .pw-sheet {
  position: relative;
  z-index: 1;
  height: 94%;
  max-height: 94%;
  max-width: 480px;
  border-radius: 22px 22px 0 0;
  box-shadow: var(--shadow-deep);
  transform: translateY(100%);
  transition: transform .34s cubic-bezier(.32,.72,0,1);
}
.pw-overlay.open .pw-sheet { transform: translateY(0); }
/* The sky is square-cornered, so it has to be clipped to the sheet radius.
   No safe-area padding here either: the sheet stops short of the status bar. */
.pw-overlay .pw-sky {
  border-radius: 22px 22px 0 0;
  padding-top: 26px;
}
.pw-overlay .pw-close { top: 12px; }
