/* HOW TO BUY — the walk-cycle scene (assets/scroll-animation, 121 frames)
   IS the section's background, drawn frame-by-frame to .buy__canvas by
   js/buy-scene.js. .buy__track is a tall scroll runway; .buy__stage sticks
   to the viewport for its duration so the whole sequence plays out fully
   on screen instead of scrolling past half-seen. --ink is the section's
   own near-black-maroon, used only for .buy__cta's hover/is-close
   background. */
.buy {
  --ink: #200710;
  position: relative;
  background: var(--bg-deep);
}

/* 260vh here used to leave ~51vh of runway — half a screen of scrolling —
   after the walk had already finished on its closing frame, which read as
   the page refusing to move on. 220vh keeps the walk itself at almost
   exactly its old pace (js/buy-scene.js's PROGRESS_END_FRACTION was raised
   to match, so it still resolves over ~105vh) and cuts the dead hold after
   it to ~15vh — long enough to land on the pose, short enough that nobody
   waits on it. */
.buy__track {
  position: relative;
  height: 220vh;
  height: 220svh;
}

.buy__stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}

.buy__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* pools shadow along the edges so the contract card + CTA stay readable
   over whichever frame happens to be underneath them. The bottom fade
   also does a second job: it's what the stage's last visible pixels look
   like right where .buy__track ends and THE CHAIN begins (see chain.css
   — its own ::before fades UP from var(--bg-deep) at its top edge, but
   that only meets a hard cut if the photo above it is still visibly a
   photo down to the very last pixel). It runs to fully opaque before
   fading back up into the scene, so the transition dissolves into black
   instead of cutting to it — but kept SHORT (fully faded out by 16%) on
   purpose: a taller fade here reads as a permanent dark band across the
   bottom of the whole scene, not just the seam, and was covering the
   character's feet/shoes for most of the walk cycle. */
.buy__scrim {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(46% 60% at 62% 62%, rgba(5, 5, 6, 0.5) 0%, rgba(5, 5, 6, 0) 65%),
    linear-gradient(0deg, rgba(5, 5, 6, 1) 0%, rgba(5, 5, 6, 0.9) 4%, rgba(5, 5, 6, 0.1) 10%, rgba(5, 5, 6, 0) 16%),
    linear-gradient(180deg, rgba(5, 5, 6, 0.55) 0%, rgba(5, 5, 6, 0) 20%);
  pointer-events: none;
}

/* the contract card: black + red, on brand with the rest of the site
   (var(--haiti-red) — already the palette's dedicated red, reused here
   rather than inventing a new one) instead of the old cream "postcard"
   look. Bottom-RIGHT rather than bottom-left deliberately — .s4s-player
   (css/player.css) is a `position: fixed` bottom-LEFT element on every
   page, at global z-index 950; anything placed in this section's own
   bottom-left corner sits underneath it the instant their boxes overlap,
   which is exactly what the old bottom-left postcard did. Opposite
   corners makes that collision structural, not just current-viewport
   luck. Full address + copy button share one row on wider screens (see
   .buy__contract-row); the max-width media query below collapses it to
   just the copy button for phones, where it also drops low enough to
   clear .buy__cta sitting bottom-center at that breakpoint.

   Positioned via top: 100% + a translateY, NOT `bottom` — `bottom` on an
   absolutely-positioned child of this sticky-while-pinned, overflow:
   hidden .buy__stage measures out to 0 no matter what value it's given
   (verified: right/left/top all resolve correctly against the same box,
   only bottom is affected). top: 100% anchors this box's own top edge to
   the stage's bottom edge; translateY then walks it back up by its own
   full height plus the actual gap — see #buy-contract below, which is
   also why the translateY lives on an #id selector rather than here:
   same reveal/GSAP specificity issue as #buy-cta (see that rule's
   comment) — .buy__contract carries the .reveal class too. */
.buy__contract {
  position: absolute;
  z-index: 1;
  right: var(--space-3);
  top: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-width: min(32rem, 64vw);
  background: linear-gradient(155deg, rgba(9, 10, 12, 0.94), rgba(5, 5, 6, 0.97));
  border: 1.5px solid rgba(210, 16, 52, 0.45);
  border-radius: 12px;
  padding: 0.9rem 1.1rem;
  box-shadow:
    0 18px 40px -18px rgba(0, 0, 0, 0.7),
    0 0 0 1px rgba(210, 16, 52, 0.08),
    0 0 28px -12px rgba(210, 16, 52, 0.4);
}
#buy-contract { transform: translateY(calc(-100% - var(--space-3))); }

.buy__contract-label {
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  color: var(--haiti-red);
}

.buy__contract-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.buy__contract-value {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.78rem;
  color: var(--fg);
  opacity: 0.92;
  line-height: 1.4;
  word-break: break-all;
}

.buy__contract-copy {
  flex-shrink: 0;
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  color: var(--fg);
  background: rgba(210, 16, 52, 0.16);
  border: 1px solid rgba(210, 16, 52, 0.55);
  padding: 0.55em 0.95em;
  border-radius: 6px;
  transition: background 0.2s, border-color 0.2s, color 0.2s;
}
.buy__contract-copy:hover { background: var(--haiti-red); border-color: var(--haiti-red); color: #fff; }
.buy__contract-copy[data-copied="true"] { background: var(--cyan); border-color: var(--cyan); color: var(--bg-deep); }

/* the "shut up and take my money" speech balloon — only shown on the
   walk cycle's last two frames (js/buy-scene.js toggles .is-visible off
   the same frame index used to draw the canvas, so it's always in sync
   with what's on screen, never a separate timer). Positioned up and to
   the right of the character's head in the closing pose, tail pointing
   back down toward him — percentages of .buy__stage rather than a fixed
   px offset, same reasoning as .buy__cta below: the character sits
   center-anchored in the canvas at any viewport size (drawFrame() always
   centers the cover-cropped frame), so a percentage anchor tracks his
   head across breakpoints instead of needing separate per-breakpoint
   tuning. transform-origin is the tail corner, not the center — scaling
   in from there reads as the balloon popping up from his mouth instead
   of just growing in place. */
.buy__balloon {
  position: absolute;
  z-index: 2;
  left: 54%;
  top: 9%;
  width: clamp(11rem, 16vw, 17rem);
  height: auto;
  transform-origin: 12% 88%;
  opacity: 0;
  transform: scale(0.4);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.buy__balloon.is-visible {
  opacity: 1;
  transform: scale(1);
  transition: opacity 0.3s ease, transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@media (max-width: 900px) {
  .buy__balloon { left: 56%; top: 7%; width: clamp(9rem, 22vw, 13rem); }
}
@media (max-width: 640px) {
  /* +30% over the previous clamp(7rem, 26vw, 9.5rem) */
  .buy__balloon { left: 58%; top: 9%; width: clamp(9.1rem, 33.8vw, 12.35rem); }
}

/* the big CTA: parked front-and-center, low — right where the character's
   legs land in the closing frame, clear of the contract card (bottom-
   right) and the walk path above it — a fixed anchor the sequence plays
   toward rather than a spot he walks up to. Centering it this way keeps it
   reachable at the same screen position regardless of viewport width,
   which is also why js/buy-scene.js's cursor-proximity math (measured
   live off this element's own getBoundingClientRect(), never a hardcoded
   coordinate) keeps working unchanged after a reposition. Pill-shaped and
   lifted with an idle glow-breathe so it reads as the page's one primary
   action, with the pump.fun mark badged on in its own circular chip
   (assets/pump-fun-seeklogo.png, transparent PNG) rather than flattened
   into the label text. */
.buy__cta {
  position: absolute;
  z-index: 1;
  left: 50%;
  top: 74%;
  display: flex;
  align-items: center;
  gap: 1.8rem;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(155deg, rgba(9, 10, 12, 0.94), rgba(5, 5, 6, 0.97));
  color: var(--fg);
  padding: 1.53em 3.24em 1.53em 1.53em;
  border-radius: 999px;
  border: 2.7px solid rgba(22, 232, 224, 0.35);
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease), border-color 0.35s var(--ease), background 0.35s var(--ease);
  box-shadow:
    0 32.4px 79.2px -28.8px rgba(0, 0, 0, 0.75),
    0 0 0 1.8px rgba(22, 232, 224, 0.08),
    0 0 46.8px -14.4px rgba(22, 232, 224, 0.4);
  animation: buy-cta-breathe 3.2s ease-in-out infinite;
}
/* The centering transform lives on the #id selector rather than on
   .buy__cta itself: main.js's reveal system leaves ".js-motion .reveal"
   (an ancestor-combinator rule, specificity 0,2,0) as the element's
   resting transform once its entrance tween's inline style is cleared,
   and that outranks a plain ".buy__cta" class rule (0,1,0) — the button
   would snap back to the reveal system's pre-animation translateY(28px)
   instead of staying centered. An #id selector (1,0,0) always wins. */
#buy-cta { transform: translate(-50%, -50%); }
#buy-cta:hover,
#buy-cta.is-close { transform: translate(-50%, -50%) scale(1.06); }

@media (prefers-reduced-motion: reduce) {
  .buy__cta { animation: none; }
}
@keyframes buy-cta-breathe {
  0%, 100% {
    box-shadow:
      0 32.4px 79.2px -28.8px rgba(0, 0, 0, 0.75),
      0 0 0 1.8px rgba(22, 232, 224, 0.08),
      0 0 46.8px -14.4px rgba(22, 232, 224, 0.4);
  }
  50% {
    box-shadow:
      0 32.4px 79.2px -28.8px rgba(0, 0, 0, 0.75),
      0 0 0 1.8px rgba(22, 232, 224, 0.18),
      0 0 72px -7.2px rgba(22, 232, 224, 0.65);
  }
}

/* diagonal shine, swept across on hover/is-close only (::before, so it
   layers under the icon/text which get z-index: 1 below) */
.buy__cta::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, 0.35) 50%, transparent 65%);
  transform: translateX(-130%);
  transition: transform 0.65s var(--ease);
  pointer-events: none;
}
.buy__cta:hover::before,
.buy__cta.is-close::before { transform: translateX(130%); }

.buy__cta-icon {
  position: relative;
  z-index: 1;
  flex-shrink: 0;
  width: 5.4rem;
  height: 5.4rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(circle at 35% 30%, rgba(22, 232, 224, 0.2), rgba(255, 255, 255, 0.02) 72%);
  border: 1.8px solid rgba(22, 232, 224, 0.3);
  transition: transform 0.5s var(--ease), border-color 0.35s var(--ease);
}
.buy__cta-icon img { width: 3.42rem; height: 3.42rem; object-fit: contain; }

.buy__cta-text {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 0.36rem;
  white-space: nowrap;
}
.buy__cta-label {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 3.06rem;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--cyan);
}
.buy__cta-sub {
  font-size: 1.33rem;
  letter-spacing: 0.08em;
  opacity: 0.78;
}

/* hover, or js/buy-scene.js's is-close (character has walked up close) —
   the transform itself is declared above on #buy-cta / #buy-cta.is-close */
.buy__cta:hover,
.buy__cta.is-close {
  background: linear-gradient(155deg, rgba(11, 16, 16, 0.96), var(--ink));
  border-color: var(--cyan);
  box-shadow:
    0 39.6px 100.8px -28.8px rgba(22, 232, 224, 0.6),
    0 0 0 1.8px var(--cyan),
    0 0 86.4px -10.8px rgba(22, 232, 224, 0.75);
}
.buy__cta:hover .buy__cta-icon,
.buy__cta.is-close .buy__cta-icon {
  transform: rotate(-16deg) scale(1.1);
  border-color: var(--cyan);
}

@media (max-width: 900px) {
  .buy__cta { top: 76%; padding: 1.26em 2.7em 1.26em 1.26em; gap: 1.44rem; }
  .buy__cta-icon { width: 4.5rem; height: 4.5rem; }
  .buy__cta-icon img { width: 2.7rem; height: 2.7rem; }
  .buy__cta-label { font-size: 2.52rem; }

  /* .buy__cta grows enough at this tier (top: 76%, above) that its own
     bottom edge can reach down into .buy__contract's default bottom-
     right spot — shrinking the card a bit and pulling it a bit closer to
     the true bottom edge (smaller translateY gap on #buy-contract) keeps
     clearance between the two down to ~900px wide. */
  .buy__contract { max-width: min(26rem, 58vw); padding: 0.7rem 0.9rem; gap: 0.4rem; }
  .buy__contract-value { font-size: 0.72rem; }
  .buy__contract-copy { font-size: 0.66rem; padding: 0.5em 0.85em; }
  #buy-contract { transform: translateY(calc(-100% - var(--space-1))); }
}

@media (max-width: 640px) {
  .buy__track { height: 220vh; height: 220svh; }
  /* Capped at ~1.5x the pre-doubling size here rather than the full 2x
     above — at 2x this pill runs edge-to-edge on narrow phones (its own
     width exceeds a 390px viewport), leaving no side margin and risking
     real overflow on top of just looking cramped. This still reads as
     noticeably bigger than before, just not literally double. */
  .buy__cta { top: auto; bottom: 12%; padding: 0.945em 2.025em 0.945em 0.945em; gap: 1.08rem; }
  .buy__cta-icon { width: 3.38rem; height: 3.38rem; }
  .buy__cta-icon img { width: 2.03rem; height: 2.03rem; }
  .buy__cta-label { font-size: 1.89rem; }
  .buy__cta-sub { font-size: 1rem; }
  /* bottom-anchored here, so only horizontal centering is wanted —
     translateY(-50%) would additionally lift it by half its own height */
  #buy-cta { transform: translateX(-50%); }
  #buy-cta:hover,
  #buy-cta.is-close { transform: translateX(-50%) scale(1.06); }

  /* Collapses to just the copy button — the full address doesn't fit
     phone widths without crowding .buy__cta below it (also bottom-
     anchored at this breakpoint, see above). Sits ~var(--space-3) above
     the stage's true bottom (via the top: 100% + translateY trick above
     — .buy__cta's own bottom: 12% puts it noticeably higher, ~101px up
     on a typical phone height), so the two never compete for the same
     band, and still bottom-right, clear of .s4s-player at bottom-left. */
  .buy__contract {
    right: var(--space-2);
    max-width: none;
    gap: 0;
    padding: 0.3rem;
    border-radius: 999px;
  }
  .buy__contract-label,
  .buy__contract-value { display: none; }
  .buy__contract-copy { font-size: 0.62rem; padding: 0.6em 0.9em; border-radius: 999px; }
}
