/* Pairpop motion layer.
   Everything here animates transform/opacity only, so it stays on the compositor
   and never triggers layout. One global switch: prefers-reduced-motion kills it all. */

/* ---------- scroll reveal ---------- */
[data-reveal]{opacity:0;transform:translate3d(0,var(--rv-y,22px),0) scale(var(--rv-s,1));
  transition:opacity 720ms cubic-bezier(.22,1,.36,1),transform 720ms cubic-bezier(.22,1,.36,1);
  transition-delay:var(--rv-d,0ms);will-change:transform,opacity}
[data-reveal].rv-in{opacity:1;transform:translate3d(0,0,0) scale(1)}
[data-reveal].rv-done{will-change:auto}
/* eyebrows and headings arrive with a touch more travel and a hair of scale */
.eyebrow[data-reveal]{--rv-y:14px}
h2[data-reveal],.page-title[data-reveal]{--rv-y:26px;--rv-s:.985}
.pair-card[data-reveal],.how-step[data-reveal],.principle[data-reveal],.faq-item[data-reveal]{--rv-y:26px;--rv-s:.978}

/* ---------- hero entrance ---------- */
.hero-copy>*{opacity:0;transform:translate3d(0,18px,0);
  animation:heroRise 900ms cubic-bezier(.22,1,.36,1) forwards}
.hero-copy>*:nth-child(1){animation-delay:120ms}
.hero-copy>*:nth-child(2){animation-delay:220ms}
.hero-copy>*:nth-child(3){animation-delay:320ms}
.hero-copy>*:nth-child(4){animation-delay:420ms}
.hero-copy>*:nth-child(5){animation-delay:520ms}
@keyframes heroRise{to{opacity:1;transform:translate3d(0,0,0)}}
#balloon-stage{animation:stageIn 1200ms cubic-bezier(.22,1,.36,1) both;animation-delay:200ms}
@keyframes stageIn{from{opacity:0;transform:translate3d(0,26px,0) scale(.97)}to{opacity:1;transform:none}}

/* ---------- drifting balloons released on fast scroll ---------- */
.driftfield{position:fixed;inset:0;z-index:3;pointer-events:none;overflow:hidden;contain:strict;
  -webkit-user-select:none;user-select:none}
.driftball{position:absolute;bottom:-180px;width:var(--db-size,86px);height:var(--db-size,86px);
  padding:0;border:0;background:none;cursor:pointer;pointer-events:auto;
  -webkit-tap-highlight-color:transparent;
  will-change:transform,opacity;opacity:0;
  animation:dbRise var(--db-dur,7s) cubic-bezier(.32,.12,.44,1) forwards}
.driftball img{width:100%;height:100%;object-fit:contain;display:block;
  pointer-events:none;-webkit-user-drag:none;user-drag:none;user-select:none;-webkit-user-select:none;
  filter:drop-shadow(0 10px 18px rgba(28,58,92,.16));
  transition:filter 220ms ease,transform 260ms cubic-bezier(.22,1,.36,1);
  animation:dbSway var(--db-sway,3.4s) ease-in-out infinite alternate}
.driftball:hover img,.driftball:focus-visible img{
  filter:drop-shadow(0 14px 26px rgba(28,58,92,.28)) saturate(1.08)}
.driftball:focus-visible{outline:2px solid rgba(38,104,180,.75);outline-offset:6px;border-radius:50%}
/* symbol label only shows on hover, so the drift stays quiet until you reach for it */
.driftball-tag{position:absolute;left:50%;bottom:-6px;transform:translate(-50%,6px);
  font:600 11px/1 var(--font-body,inherit);letter-spacing:.06em;
  padding:4px 8px;border-radius:999px;white-space:nowrap;
  background:rgba(255,255,255,.94);color:#1c3a5c;
  box-shadow:0 6px 16px rgba(28,58,92,.18);
  opacity:0;transition:opacity 200ms ease,transform 200ms ease;pointer-events:none}
.driftball:hover .driftball-tag,.driftball:focus-visible .driftball-tag{opacity:1;transform:translate(-50%,0)}
.driftball-pop img{transform:scale(1.18);filter:drop-shadow(0 16px 30px rgba(28,58,92,.3))}
@keyframes dbRise{
  0%{opacity:0;transform:translate3d(0,0,0) rotate(var(--db-r0,-6deg))}
  9%{opacity:var(--db-op,.85)}
  78%{opacity:var(--db-op,.85)}
  100%{opacity:0;transform:translate3d(var(--db-dx,30px),calc(-100vh - 240px),0) rotate(var(--db-r1,7deg))}}
@keyframes dbSway{from{transform:translateX(-9px) rotate(-3.5deg)}to{transform:translateX(9px) rotate(3.5deg)}}

/* ---------- header condenses once you leave the hero ---------- */
.site-header{transition:transform 420ms cubic-bezier(.22,1,.36,1)}
body.sticky-head .site-header{transform:translate3d(0,-3px,0) scale(.985)}
/* Shadow belongs to the two pill groups only. Targeting .site-header>* hit the
   full width .nav-rail and painted a bar joining them once the page scrolled. */
body.sticky-head .nav-group,body.sticky-head .nav-actions{
  box-shadow:0 12px 30px rgba(24,52,84,.13)}
.nav-group,.nav-actions{transition:box-shadow 420ms ease}
.nav-rail,body.sticky-head .nav-rail{box-shadow:none}

/* ---------- parallax hooks driven by motion.js ----------
   The drift keyframes own the transform on each cloud layer, so parallax rides
   on the container instead of fighting them for the same property. */
.parallax-slow{transform:translate3d(0,var(--pxs,0px),0);will-change:transform}

/* ---------- micro interactions ---------- */
.pair-card,.stock-tile,.how-step,.principle{transition:transform 320ms cubic-bezier(.22,1,.36,1),
  box-shadow 320ms ease,border-color 240ms ease}
.pair-card:hover{transform:translateY(-5px)}
.pair-card:hover .mini-balloon{transform:translateY(-6px) rotate(-3deg)}
.mini-balloon{transition:transform 460ms cubic-bezier(.22,1,.36,1)}
.btn,.text-link,.board-link,.cta,.hero-actions a{transition:transform 220ms cubic-bezier(.22,1,.36,1),
  background 220ms ease,color 220ms ease,box-shadow 220ms ease}
.btn:hover,.cta:hover,.hero-actions a:hover{transform:translateY(-2px)}
.btn:active,.cta:active,.hero-actions a:active{transform:translateY(0) scale(.985)}
.text-link:hover,.board-link:hover{transform:translateX(3px)}
.stock-board tr{transition:background 220ms ease}
.stock-board-icon{transition:transform 340ms cubic-bezier(.22,1,.36,1)}
.stock-board tr:hover .stock-board-icon{transform:translateY(-3px) rotate(-5deg) scale(1.06)}

/* counters and chips fade up when their section lands */
.popular-pair{animation:chipIn 520ms cubic-bezier(.22,1,.36,1) both}
@keyframes chipIn{from{opacity:0;transform:translateY(8px) scale(.96)}to{opacity:1;transform:none}}

/* ---------- honour the OS switch ---------- */
@media (prefers-reduced-motion:reduce){
  [data-reveal]{opacity:1!important;transform:none!important;transition:none!important}
  .hero-copy>*,#balloon-stage{animation:none!important;opacity:1!important;transform:none!important}
  .driftfield{display:none!important}
  .pair-card:hover,.btn:hover,.cta:hover,.hero-actions a:hover,.text-link:hover,.board-link:hover{transform:none}
  .site-header,.site-header>*{transition:none}
  .parallax-slow{transform:none!important}
  .cloudscape{transform:none!important}
}

/* Balloon burst: a soft pop, not a firework. Shell flashes out over 260ms while
   six small shards drift a short distance and fade. Transform/opacity only. */
.driftball-pop{animation:dbPopShell 300ms cubic-bezier(.22,1,.36,1) forwards}
.driftball-pop img{animation:dbPopImg 260ms cubic-bezier(.3,.9,.4,1) forwards}
.driftball-pop .driftball-tag{opacity:0;transition:opacity 120ms ease}
@keyframes dbPopShell{0%{transform:scale(1)}38%{transform:scale(1.14)}100%{transform:scale(1.2);opacity:0}}
@keyframes dbPopImg{0%{transform:scale(1);filter:drop-shadow(0 10px 18px rgba(28,58,92,.16))}
  40%{transform:scale(1.16) rotate(-3deg);filter:drop-shadow(0 14px 24px rgba(28,58,92,.24)) brightness(1.06)}
  100%{transform:scale(.72) rotate(2deg);opacity:0}}
.dbshard{position:absolute;width:var(--sh,9px);height:var(--sh,9px);border-radius:50%;
  background:var(--shc,#8fc3ee);pointer-events:none;opacity:0;
  transform:translate(-50%,-50%);
  animation:dbShard var(--shd,520ms) cubic-bezier(.16,.72,.3,1) forwards}
@keyframes dbShard{0%{opacity:.9;transform:translate(-50%,-50%) scale(.5)}
  55%{opacity:.75}
  100%{opacity:0;transform:translate(calc(-50% + var(--shx,0px)),calc(-50% + var(--shy,0px))) scale(.28)}}
.dbring{position:absolute;border-radius:50%;pointer-events:none;
  border:2px solid rgba(150,200,240,.7);transform:translate(-50%,-50%) scale(.4);opacity:.8;
  animation:dbRing 420ms cubic-bezier(.2,.8,.3,1) forwards}
@keyframes dbRing{100%{transform:translate(-50%,-50%) scale(1.5);opacity:0;border-width:1px}}
@media(prefers-reduced-motion:reduce){.dbshard,.dbring{display:none}}
