/* =========================================================
   GateWallet promo platform — pr-* namespace (css/promo.css).
   One campaign catalogue (js/core/banners.js), three bespoke
   ad formats so no two surfaces ever show the same component:

     FORMAT 1  .pr-hero     Markets — tall layered scene cards
     FORMAT 2  .pr-voucher  Assets  — one rotating punched ticket
     FORMAT 3  .pr-strip    Profile — slim membership metal strip

   Ground rules (brand): graphite radials #0B0C11..#14161E,
   gold #F7A600 used precisely, violet #7B5BFF only as a rare
   secondary, depth from layered shadows + hairlines + grain.
   Every animation is transform/opacity only. Decorative motion
   runs ONLY while the format is active and on screen: banners.js
   toggles .on per card and .pr-asleep on the mount root.
   ========================================================= */

:root {
  --pr-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  --pr-gold: #F7A600;
  --pr-gold-soft: #F7C14D;
  --pr-violet: #7B5BFF;
}

/* ------------------------------ shared ------------------------------ */

/* Tab hidden or scrolled out of view: everything freezes, nothing burns. */
.pr-asleep *,
.pr-asleep .pr-card::after { animation-play-state: paused !important; }

/* Every pr-* surface is a hardcoded graphite plate, whatever the app theme —
   so every ink below is literal (like onboarding), never a theme token that
   would flip near-black in light mode on a still-dark card. */

.pr-eyebrow {
  display: block;
  font-size: 10px; font-weight: 800; letter-spacing: .17em;
  text-transform: uppercase; color: #DFA33C;
}

.pr-cta {
  display: inline-flex; align-items: center; gap: 5px; align-self: flex-start;
  margin-top: 9px; padding: 6px 12px;
  border: 1px solid rgba(247, 166, 0, .30); border-radius: 999px;
  background: rgba(247, 166, 0, .10);
  color: var(--pr-gold-soft); font-family: inherit;
  font-size: 11.5px; font-weight: 750; letter-spacing: .01em;
  cursor: pointer; pointer-events: none; /* the whole card routes the tap */
  transition: transform var(--dur-fast) var(--ease-out);
}
.pr-cta svg { width: 11px; height: 11px; }

/* =========================================================
   FORMAT 1 — Markets hero deck. Tall (150px) campaign cards,
   each a bespoke layered scene: inline SVG + positioned DOM,
   parallax layers ([data-par]) shift against drag in JS.
   ========================================================= */

.pr-hero { position: relative; margin: 10px 12px; touch-action: pan-y; }
.pr-hero-vp {
  overflow: hidden; border-radius: var(--radius-lg);
  box-shadow: 0 18px 40px rgba(0, 0, 0, .50), 0 3px 10px rgba(0, 0, 0, .38);
}
.pr-hero-track { display: flex; transition: transform .65s var(--ease-out); }
.pr-hero-track.dragging { transition: none; }

.pr-card {
  position: relative; flex: 0 0 100%; min-width: 0; height: 150px;
  padding: 16px 16px 14px;
  display: flex; flex-direction: column; justify-content: center;
  overflow: hidden; cursor: pointer;
  border-radius: var(--radius-lg);
  background: radial-gradient(130% 175% at 80% 10%, #181B26 0%, #10121A 46%, #0A0B10 100%);
  border: 1px solid rgba(255, 255, 255, .07);
  opacity: .55; transform: scale(.95);
  transition: opacity .5s var(--ease-out), transform .7s var(--ease-out);
}
.pr-card.on { opacity: 1; transform: none; }

/* Film grain — depth without saturation. */
.pr-card::before {
  content: ""; position: absolute; inset: 0;
  background: var(--pr-grain); background-size: 140px 140px;
  opacity: .05; pointer-events: none;
}
/* Occasional shine sweep, active card only. */
.pr-card::after {
  content: ""; position: absolute; top: -40%; left: -30%; width: 34%; height: 180%;
  transform: rotate(16deg) translateX(-260%);
  background: linear-gradient(90deg,
    transparent, rgba(255, 255, 255, .05), rgba(255, 255, 255, .11),
    rgba(255, 255, 255, .05), transparent);
  pointer-events: none;
}
.pr-card.on::after { animation: prShine 8.8s var(--ease-out) 1.7s infinite; }
@keyframes prShine {
  0% { transform: rotate(16deg) translateX(-260%); }
  15%, 100% { transform: rotate(16deg) translateX(920%); }
}

/* A whisper of violet on the referral card only — the rare secondary. */
.pr-card[data-id="refer"] {
  background:
    radial-gradient(90% 120% at 88% 0%, rgba(123, 91, 255, .10), transparent 55%),
    radial-gradient(130% 175% at 80% 10%, #181B26 0%, #10121A 46%, #0A0B10 100%);
}

.pr-copy {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; gap: 3px;
  max-width: 62%;
}
.pr-title { font-size: 16.5px; font-weight: 780; letter-spacing: -.3px; color: #F2F3F8; }
.pr-fine { font-size: 11px; line-height: 1.35; color: rgba(255, 255, 255, .56); }

/* Big compact numerals carry the drama. */
.pr-num { display: flex; align-items: baseline; gap: 6px; line-height: 1; margin: 2px 0; }
.pr-num b {
  font-size: 36px; font-weight: 800; letter-spacing: -1.8px;
  font-variant-numeric: tabular-nums; color: #F2F3F8;
}
.pr-num i {
  font-style: normal; font-size: 11px; font-weight: 750;
  letter-spacing: .08em; color: rgba(255, 255, 255, .56);
}
.pr-num.gold b {
  background: linear-gradient(180deg, #FFE3A0 0%, #F7A600 58%, #B97400 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* The hero campaign earns the one solid-gold CTA. */
.pr-card[data-id="welcome"] .pr-cta {
  background: linear-gradient(180deg, #FFC85E, #F7A600 60%, #E08F00);
  border-color: rgba(255, 214, 130, .5); color: #17181D;
  box-shadow: 0 6px 16px rgba(247, 166, 0, .28);
}

/* Scene plumbing: parallax layers ease home after a drag. */
.pr-scene { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
.pr-scene [data-par] { transition: transform .5s var(--ease-out); }
.pr-hero.pr-dragging .pr-scene [data-par] { transition: none; }

/* --- scene: vault door (welcome) --- */
.pr-vault { position: absolute; right: -28px; top: 50%; margin-top: -84px; width: 168px; height: 168px; }
.pr-vault-sweep { transform-box: fill-box; transform-origin: center; }
.pr-card.on .pr-vault-sweep { animation: prRot 8.5s linear infinite; }
@keyframes prRot { to { transform: rotate(1turn); } }

/* --- scene: coin podium (universe) --- */
.pr-cones { position: absolute; right: -4px; top: 0; width: 180px; height: 100%; }
/* The stage floor: a hairline the plinths visibly stand on, so the pedestals
   read as a podium rather than rectangles clipped by the card edge. */
.pr-floor {
  position: absolute; right: 0; bottom: 7px; width: 176px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .11) 26%,
    rgba(255, 255, 255, .11) 88%, transparent);
}
.pr-pod {
  position: absolute; bottom: 8px;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
}
.pr-pod img { border-radius: 50%; box-shadow: 0 6px 16px rgba(0, 0, 0, .5); }
.pr-pod b {
  font-size: 8.5px; font-weight: 700; color: rgba(255, 255, 255, .52);
  font-variant-numeric: tabular-nums;
}
.pr-pod i {
  display: block; border-radius: 5px 5px 0 0;
  background: linear-gradient(180deg, #1E212C, #12141C);
  border: 1px solid rgba(255, 255, 255, .06); border-bottom: none;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05);
}
.pr-pod.p1 { right: 112px; } .pr-pod.p1 img { width: 24px; height: 24px; } .pr-pod.p1 i { width: 36px; height: 16px; }
.pr-pod.p2 { right: 58px; }  .pr-pod.p2 img { width: 32px; height: 32px; } .pr-pod.p2 i { width: 42px; height: 30px; }
.pr-pod.p3 { right: 10px; }  .pr-pod.p3 img { width: 22px; height: 22px; } .pr-pod.p3 i { width: 34px; height: 11px; }
.pr-card.on .pr-pod { animation: prPodIn .7s var(--ease-out) both; }
.pr-card.on .pr-pod.p1 { animation-delay: .10s; }
.pr-card.on .pr-pod.p2 { animation-delay: 0s; }
.pr-card.on .pr-pod.p3 { animation-delay: .18s; }
@keyframes prPodIn { from { opacity: 0; transform: translateY(10px); } }

/* --- scene: check-in week (streak) --- */
.pr-week {
  position: absolute; right: 12px; bottom: 18px;
  display: flex; gap: 4px; perspective: 420px;
}
.pr-day {
  position: relative; width: 22px; height: 30px; border-radius: 6px;
  display: flex; align-items: flex-end; justify-content: center; padding-bottom: 3px;
  background: linear-gradient(180deg, #171923, #0E0F16);
  border: 1px solid rgba(255, 255, 255, .07);
  transform: rotateX(34deg);
}
.pr-day b { font-size: 8.5px; font-weight: 800; color: rgba(255, 255, 255, .34); }
.pr-day.lit {
  border-color: rgba(247, 166, 0, .45);
  background: linear-gradient(180deg, #2A2413, #15100A);
  box-shadow: 0 0 12px rgba(247, 166, 0, .16), inset 0 1px 0 rgba(255, 216, 121, .22);
}
.pr-day.lit b { color: var(--pr-gold-soft); }
.pr-day.today { border-color: rgba(247, 166, 0, .65); box-shadow: 0 0 14px rgba(247, 166, 0, .14); }
.pr-day.today b { color: var(--pr-gold-soft); }
.pr-card.on .pr-day {
  animation: prDayIn .5s var(--ease-out) both;
  animation-delay: calc(90ms * var(--i));
}
@keyframes prDayIn {
  from { opacity: 0; transform: rotateX(34deg) translateY(9px); }
  to   { opacity: 1; transform: rotateX(34deg); }
}
.pr-flame {
  position: absolute; top: -14px; left: 50%; margin-left: -6px;
  width: 12px; height: 12px; color: var(--pr-gold);
}
.pr-flame svg { width: 12px; height: 12px; }
.pr-card.on .pr-flame { animation: prFlick 1.6s ease-in-out .9s infinite; }
@keyframes prFlick {
  0%, 100% { opacity: .8; transform: translateY(0); }
  50% { opacity: 1; transform: translateY(-1.5px); }
}

/* --- scene: sliced zero (zero-fees) --- */
.pr-zero { position: absolute; right: 10px; top: 22px; }
.pr-zero b {
  font-size: 88px; font-weight: 800; letter-spacing: -5px; line-height: 1;
  background: linear-gradient(180deg, rgba(255, 255, 255, .17), rgba(255, 255, 255, .03));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.pr-zero b span { font-size: 42px; letter-spacing: -1px; }
/* The stroke starts and ends INSIDE the card — the gradient fades it out
   before the edge, so the glow is never guillotined flat. */
.pr-zero-slice {
  position: absolute; left: -14%; right: 4%; top: 55%; height: 2px;
  background: linear-gradient(90deg, rgba(247, 166, 0, 0), #F7A600 30%, #FFD879 55%, rgba(247, 166, 0, 0) 92%);
  box-shadow: 0 0 10px rgba(247, 166, 0, .4);
  transform: rotate(-14deg); transform-origin: left center;
}
.pr-card.on .pr-zero-slice { animation: prSlice .8s var(--ease-out) .35s both; }
@keyframes prSlice {
  from { transform: rotate(-14deg) scaleX(0); }
  to   { transform: rotate(-14deg) scaleX(1); }
}

/* --- scene: referral coin pair (refer) ---
   Two minted portrait coins — milled rims, engraved silhouettes — struck from
   the same die: you in gold, your friend carrying the app's one violet tint. */
.pr-duo { position: absolute; right: 14px; top: 20px; width: 118px; height: 108px; }
.pr-rc { position: absolute; display: block; }
.pr-rc.a {
  left: 0; top: 2px; z-index: 2; width: 66px; height: 66px;
  filter: drop-shadow(0 10px 18px rgba(0, 0, 0, .5)) drop-shadow(0 0 12px rgba(247, 166, 0, .12));
}
.pr-rc.b {
  left: 48px; top: 24px; width: 56px; height: 56px;
  filter: drop-shadow(0 10px 18px rgba(0, 0, 0, .5));
}
.pr-split {
  position: absolute; left: 14px; bottom: 0; z-index: 3;
  display: flex; align-items: center; gap: 4px; padding: 3px 9px;
  border-radius: 999px; border: 1px solid rgba(255, 255, 255, .10);
  background: rgba(10, 11, 16, .86);
  font-size: 10.5px; font-weight: 800;
}
.pr-split b:first-of-type { color: var(--pr-gold-soft); }
.pr-split b:last-of-type { color: #A78FFF; }
.pr-split em { font-style: normal; color: rgba(255, 255, 255, .34); }
.pr-card.on .pr-rc.a { animation: prAvaA .8s var(--ease-out) both; }
.pr-card.on .pr-rc.b { animation: prAvaB .8s var(--ease-out) .12s both; }
.pr-card.on .pr-split { animation: prPodIn .6s var(--ease-out) .3s both; }
@keyframes prAvaA { from { opacity: 0; transform: translateX(-12px) rotate(-5deg); } }
@keyframes prAvaB { from { opacity: 0; transform: translateX(12px) rotate(5deg); } }

/* --- dots: the active dot is the auto-advance progress pill --- */
.pr-dots { display: flex; justify-content: center; gap: 5px; padding: 8px 0 2px; }
.pr-dot {
  position: relative; overflow: hidden; width: 6px; height: 6px; padding: 0;
  border: 0; border-radius: 999px; background: var(--line); cursor: pointer;
  transition: width .3s var(--ease-out), background-color .3s var(--ease-out);
}
.pr-dot.on { width: 22px; background: var(--accent); }
.pr-hero.playing .pr-dot.on { background: var(--line); }
.pr-dot-fill {
  position: absolute; inset: 0; border-radius: inherit;
  background: var(--accent); transform: scaleX(0); transform-origin: left;
}
/* Duration is injected inline by banners.js so pill and timer share a clock. */
.pr-hero.playing .pr-dot.on .pr-dot-fill { animation: prFill 6s linear forwards; }
@keyframes prFill { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* =========================================================
   FORMAT 2 — Assets voucher. One ticket, punched side notches
   (mask cutouts), perforated divider, rotated value stub and
   a faint barcode. Content rotates in place — not a carousel.
   ========================================================= */

.pr-voucher { margin: 10px 12px; perspective: 700px; }
.pr-vt {
  --vx: calc(100% - 96px);
  position: relative; display: flex; width: 100%; min-height: 102px;
  padding: 0; border: 0; border-radius: 14px; overflow: hidden;
  cursor: pointer; text-align: left; font-family: inherit; color: #F2F3F8;
  appearance: none; -webkit-appearance: none;
  /* Lifted a step above the page graphite so the punched holes read as holes. */
  background: linear-gradient(160deg, #1B1F2B 0%, #12141D 55%, #0E0F16 100%);
  box-shadow: 0 14px 30px rgba(0, 0, 0, .45);
  -webkit-mask:
    radial-gradient(circle 9px at var(--vx) 0, transparent 8.5px, #000 9.4px),
    radial-gradient(circle 9px at var(--vx) 100%, transparent 8.5px, #000 9.4px);
  mask:
    radial-gradient(circle 9px at var(--vx) 0, transparent 8.5px, #000 9.4px),
    radial-gradient(circle 9px at var(--vx) 100%, transparent 8.5px, #000 9.4px);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  transition: transform var(--dur-fast) var(--ease-out);
}
.pr-vt:active { transform: scale(.985); }
.pr-vt::before {
  content: ""; position: absolute; inset: 0;
  background: var(--pr-grain); background-size: 140px 140px;
  opacity: .045; pointer-events: none;
}
/* Hairline that the notches visibly punch through, plus a concave rim
   highlight hugging each punched hole (drawn just outside the mask cut at
   r 9.4px) so the bite stays legible on the dark page ground. */
.pr-vt::after {
  content: ""; position: absolute; inset: 0;
  border: 1px solid rgba(255, 255, 255, .08); border-radius: inherit;
  background:
    radial-gradient(circle at var(--vx) 0,
      transparent 9px, rgba(255, 255, 255, .18) 9.8px, rgba(255, 255, 255, .18) 10.6px, transparent 11.6px),
    radial-gradient(circle at var(--vx) 100%,
      transparent 9px, rgba(255, 255, 255, .18) 9.8px, rgba(255, 255, 255, .18) 10.6px, transparent 11.6px);
  pointer-events: none;
}

.pr-vt-main {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px;
  padding: 13px 14px 11px;
}
.pr-vt-title { font-size: 14.5px; font-weight: 780; letter-spacing: -.2px; color: #F2F3F8; }
.pr-vt-sub { font-size: 11px; color: rgba(255, 255, 255, .56); }
.pr-vt-strip { display: flex; align-items: center; gap: 8px; margin-top: auto; padding-top: 7px; }
.pr-vt-bar { width: 86px; height: 12px; opacity: .5; flex: 0 0 auto; }
.pr-vt-bar rect { fill: rgba(255, 255, 255, .45); }
.pr-vt-code {
  font-size: 8.5px; font-weight: 700; letter-spacing: .14em;
  color: rgba(255, 255, 255, .36); white-space: nowrap;
}

.pr-vt-perf { flex: 0 0 0; margin: 10px 0; border-left: 1px dashed rgba(255, 255, 255, .16); }

.pr-vt-stub {
  flex: 0 0 96px; display: flex; flex-direction: row;
  align-items: center; justify-content: center; gap: 8px;
  background: linear-gradient(180deg, rgba(247, 166, 0, .08), rgba(247, 166, 0, .02));
}
.pr-vt-val {
  writing-mode: vertical-rl; transform: rotate(180deg);
  font-size: 14.5px; font-weight: 800; letter-spacing: .05em;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(0deg, #FFE3A0, #F7A600 60%, #D08A00);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.pr-vt-tag {
  writing-mode: vertical-rl; transform: rotate(180deg);
  font-size: 7.5px; font-weight: 700; letter-spacing: .3em;
  text-transform: uppercase; color: rgba(255, 255, 255, .36);
}

/* =========================================================
   FORMAT 3 — Profile membership strip. Brushed graphite bar,
   a gold shimmer travelling the perimeter ring, the gold
   gate-G mark, and a vertical text roll cycling campaigns.
   ========================================================= */

.pr-strip {
  position: relative; display: flex; align-items: center; gap: 12px;
  width: calc(100% - 24px); margin: 6px 12px; height: 64px; padding: 0 14px;
  border: 0; border-radius: 16px; overflow: hidden;
  cursor: pointer; text-align: left; font-family: inherit; color: #F2F3F8;
  appearance: none; -webkit-appearance: none;
  background:
    repeating-linear-gradient(100deg, rgba(255, 255, 255, .015) 0 1px, rgba(255, 255, 255, 0) 1px 4px),
    linear-gradient(180deg, #191C26 0%, #101218 58%, #0C0D12 100%);
  box-shadow: 0 10px 24px rgba(0, 0, 0, .4), inset 0 1px 0 rgba(255, 255, 255, .05);
  transition: transform var(--dur-fast) var(--ease-out);
}
.pr-strip:active { transform: scale(.985); }
.pr-strip::before {
  content: ""; position: absolute; inset: 0;
  background: var(--pr-grain); background-size: 140px 140px;
  opacity: .04; pointer-events: none;
}

/* Perimeter ring: masked 1px frame; the inner spinner is a conic highlight
   rotating with transform only. The ring's own bg is the static hairline. */
.pr-strip-edge {
  position: absolute; inset: 0; border-radius: inherit; padding: 1px;
  pointer-events: none; background: rgba(255, 255, 255, .07); overflow: hidden;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
}
/* A short bright bead (~7% arc) travelling the ring slowly — a highlight
   moving along the metal edge, never a smear parked on one side. */
.pr-strip-edge > i {
  position: absolute; inset: -110%;
  background: conic-gradient(from 0deg,
    transparent 0 89%, rgba(247, 166, 0, .4) 93.5%, rgba(255, 223, 158, .48) 94.5%, transparent 96%);
  animation: prSpin 9s linear infinite;
}
@keyframes prSpin { to { transform: rotate(1turn); } }

.pr-strip-logo { flex: 0 0 auto; display: flex; }
.pr-strip-logo svg { width: 34px; height: 34px; filter: drop-shadow(0 4px 10px rgba(0, 0, 0, .5)); }

.pr-strip-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pr-strip-eyebrow {
  font-size: 8.5px; font-weight: 800; letter-spacing: .22em;
  text-transform: uppercase; color: #C9963B; opacity: .85;
}
.pr-roll { height: 18px; overflow: hidden; }
.pr-roll-lines { display: flex; flex-direction: column; transition: transform .65s var(--ease-out); }
.pr-roll-lines.snap { transition: none; }
.pr-roll-line {
  height: 18px; line-height: 18px; flex: 0 0 18px;
  font-size: 12.5px; font-weight: 650; letter-spacing: -.1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: #F2F3F8;
}

.pr-strip-chev { flex: 0 0 auto; display: flex; color: rgba(255, 255, 255, .38); }
.pr-strip-chev svg { width: 14px; height: 14px; }

/* ------------------------- small screens ------------------------- */
/* 320px: the podium scene loses its price labels and pulls in, so the
   ETH coin and its price can never sit on top of the copy column. */
@media (max-width: 359px) {
  .pr-copy { max-width: 58%; }
  .pr-pod b { display: none; }
  .pr-pod.p1 { right: 84px; }
  .pr-pod.p2 { right: 44px; }
  .pr-pod.p3 { right: 6px; }
  .pr-floor { width: 148px; }
  .pr-vault { right: -44px; }
  .pr-duo { right: 6px; }
}

/* ------------------------- reduced motion ------------------------- */
/* banners.js already refuses to self-advance; this kills the decor.
   Base states are always visible, so nothing depends on an animation
   to appear. */
@media (prefers-reduced-motion: reduce) {
  .pr-card::after,
  .pr-card.on .pr-vault-sweep,
  .pr-card.on .pr-pod,
  .pr-card.on .pr-day,
  .pr-card.on .pr-flame,
  .pr-card.on .pr-zero-slice,
  .pr-card.on .pr-rc.a,
  .pr-card.on .pr-rc.b,
  .pr-card.on .pr-split,
  .pr-dot-fill,
  .pr-strip-edge > i { animation: none !important; }
  .pr-hero-track,
  .pr-scene [data-par],
  .pr-roll-lines { transition: none !important; }
}
