/* ============================================================================
   Shared styles for guessr.market.
   Previously each page inlined its own copy of .glass-panel / .neon-glow /
   status colours. Everything common lives here now; page-specific rules stay
   in the page. Loaded after the Tailwind CDN so utility classes still win
   where they're applied directly.
   ============================================================================ */

/* ---------- surfaces (unchanged values, single source) ---------- */
.glass-panel {
  background: rgba(49, 53, 57, .4);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid rgba(140, 144, 161, .2);
}
.neon-glow { box-shadow: 0 0 20px rgba(13, 110, 253, .4); }
.text-glow { text-shadow: 0 0 10px rgba(177, 197, 255, .5); }

.status-open      { color: #4ade80; }
.status-locked    { color: #facc15; }
.status-resolved  { color: #94a3b8; }
.status-cancelled { color: #f87171; }

.rank-1 { color: #fbbf24; }
.rank-2 { color: #94a3b8; }
.rank-3 { color: #c27803; }

/* ============================================================================
   FX layers — owned by fx.js
   ============================================================================ */
#gm-fx { position: fixed; inset: 0; z-index: 80; pointer-events: none; }

#gm-edge {
  position: fixed; inset: 0; z-index: 70; pointer-events: none; opacity: 0;
}
#gm-edge.on { animation: gm-edge-flash .95s ease-out; }
@keyframes gm-edge-flash {
  0%   { opacity: 0; }
  18%  { opacity: 1; }
  100% { opacity: 0; }
}

.gm-shock {
  position: fixed; z-index: 79; pointer-events: none; border-radius: 50%;
  border: 2px solid #b1c5ff;
  transform: translate(-50%, -50%) scale(0);
  animation: gm-shock .72s cubic-bezier(.15, .8, .3, 1) forwards;
}
@keyframes gm-shock {
  0%   { transform: translate(-50%, -50%) scale(0);   opacity: .85; }
  100% { transform: translate(-50%, -50%) scale(1);   opacity: 0; }
}

/* ---------- toasts ---------- */
.gm-toasts {
  position: fixed; right: 20px; bottom: 20px; z-index: 90;
  display: flex; flex-direction: column; gap: 9px; align-items: flex-end;
  pointer-events: none; max-width: min(360px, calc(100vw - 40px));
}
.gm-toast {
  display: flex; align-items: stretch; gap: 11px;
  padding: 12px 16px; border-radius: 10px;
  background: rgba(22, 27, 33, .96);
  border: 1px solid #424655;
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 12px 34px rgba(0, 0, 0, .5);
  font-family: 'Space Grotesk', sans-serif; font-size: 12px; color: #e0e3e8;
  animation: gm-toast-in .38s cubic-bezier(.16, 1.1, .3, 1);
}
.gm-toast.out { animation: gm-toast-out .3s ease-in forwards; }
@keyframes gm-toast-in  { 0% { opacity: 0; transform: translateX(26px) scale(.96); } 100% { opacity: 1; transform: none; } }
@keyframes gm-toast-out { to { opacity: 0; transform: translateX(20px) scale(.97); } }
.gm-toast .gm-bar { width: 3px; border-radius: 2px; background: #0d6efd; flex: none; }
.gm-toast.win  .gm-bar { background: #4ade80; }
.gm-toast.gold .gm-bar { background: #fbbf24; }
.gm-toast.lose .gm-bar { background: #8c90a1; }
.gm-toast b    { display: block; font-weight: 700; margin-bottom: 2px; }
.gm-toast .sub { color: #8c90a1; line-height: 1.45; }

/* ============================================================================
   Digit roller — fx.js Roller renders into these
   ============================================================================ */
.roll { display: inline-flex; align-items: baseline; font-variant-numeric: tabular-nums; }
.roll .d { display: inline-block; height: 1em; overflow: hidden; position: relative; }
.roll .strip { display: flex; flex-direction: column; transition: transform .55s cubic-bezier(.2, .9, .2, 1); }
.roll .strip span { height: 1em; line-height: 1; display: block; }
.roll .sep { display: inline-block; }
.roll.up   { color: #4ade80 !important; }
.roll.down { color: #f87171 !important; }

/* floating +2¢ tick */
.price-tick {
  position: absolute; right: 10px; top: 10px;
  font-family: 'Space Grotesk', sans-serif; font-size: 12px; font-weight: 700;
  opacity: 0; pointer-events: none;
}
.price-tick.show { animation: gm-tick-up 1.25s ease-out; }
@keyframes gm-tick-up {
  0%   { opacity: 0; transform: translateY(6px); }
  18%  { opacity: 1; transform: translateY(0); }
  75%  { opacity: 1; transform: translateY(-6px); }
  100% { opacity: 0; transform: translateY(-11px); }
}

/* ============================================================================
   Bet widget
   ============================================================================ */
.side-card { transition: all .15s ease; }
.side-card:not(:disabled):hover { transform: translateY(-1px); }
.side-card.active-yes { background: rgba(74, 222, 128, .08); border-color: #4ade80; box-shadow: 0 0 0 1px #4ade80, 0 0 22px rgba(74, 222, 128, .16); }
.side-card.active-no  { background: rgba(248, 113, 113, .08); border-color: #f87171; box-shadow: 0 0 0 1px #f87171, 0 0 22px rgba(248, 113, 113, .16); }

.btn-ripple { position: relative; overflow: hidden; }
.btn-ripple > .ripple {
  position: absolute; border-radius: 50%; pointer-events: none;
  background: rgba(255, 255, 255, .45);
  transform: translate(-50%, -50%) scale(0);
  animation: gm-ripple .6s ease-out forwards;
}
@keyframes gm-ripple { to { transform: translate(-50%, -50%) scale(9); opacity: 0; } }

/* nav points chip reacting to a balance change */
.pts-bump { animation: gm-pts-bump .5s cubic-bezier(.2, 1.4, .4, 1); }
@keyframes gm-pts-bump {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.13); text-shadow: 0 0 18px rgba(251, 191, 36, .7); }
  100% { transform: scale(1); }
}

/* ============================================================================
   Live feed
   ============================================================================ */
.feed-item { animation: gm-slam-in .42s cubic-bezier(.16, 1.1, .3, 1); position: relative; }
@keyframes gm-slam-in {
  0%   { opacity: 0; transform: translateY(-16px) scale(.96); }
  60%  { opacity: 1; transform: translateY(2px) scale(1.01); }
  100% { opacity: 1; transform: none; }
}
.feed-item::before {
  content: ""; position: absolute; left: 0; top: 8px; bottom: 8px;
  width: 3px; border-radius: 0 3px 3px 0; background: #8c90a1;
}
.feed-item.side-yes::before { background: #4ade80; box-shadow: 0 0 12px rgba(74, 222, 128, .6); }
.feed-item.side-no::before  { background: #f87171; box-shadow: 0 0 12px rgba(248, 113, 113, .6); }
.feed-item.whale {
  border-color: rgba(251, 191, 36, .42) !important;
  background: linear-gradient(90deg, rgba(251, 191, 36, .1), rgba(28, 32, 36, .6) 60%) !important;
}
.whale-chip {
  font-size: 10px; letter-spacing: .14em; text-transform: uppercase; font-weight: 700;
  padding: 2px 6px; border-radius: 3px;
  background: rgba(251, 191, 36, .16); color: #fbbf24; border: 1px solid rgba(251, 191, 36, .3);
}

/* market card pulse when a bet lands on it */
@keyframes flash-bet-anim {
  0%   { border-color: rgba(13, 110, 253, .9); box-shadow: 0 0 24px rgba(13, 110, 253, .55); }
  100% { border-color: rgba(140, 144, 161, .2); box-shadow: none; }
}
.flash-bet { animation: flash-bet-anim 1.2s ease-out; }
.bar-fill  { transition: width .5s cubic-bezier(.2, .9, .2, 1); }

/* ============================================================================
   Countdown
   ============================================================================ */
.cd-ring { transform: rotate(-90deg); flex: none; }
.cd-ring circle { fill: none; stroke-width: 3.5; stroke-linecap: round; }
.cd-ring .track { stroke: #262a2e; }
.cd-ring .prog  { stroke: #b1c5ff; transition: stroke-dashoffset .95s linear, stroke .4s; }
.cd-urgent .cd-ring .prog { stroke: #f87171; }
.cd-urgent { border-color: rgba(248, 113, 113, .6) !important; animation: gm-breathe 1.15s ease-in-out infinite; }
@keyframes gm-breathe {
  0%, 100% { box-shadow: 0 0 0 0 rgba(248, 113, 113, 0); }
  50%      { box-shadow: 0 0 22px 0 rgba(248, 113, 113, .3); }
}

/* ============================================================================
   Streak
   ============================================================================ */
.flame { transform-origin: 50% 85%; transition: transform .45s cubic-bezier(.2, 1.5, .4, 1), opacity .4s; }
.flame.lit { animation: gm-flicker 2.4s ease-in-out infinite; }
@keyframes gm-flicker {
  0%, 100% { transform: scale(var(--fs, 1)) rotate(0deg); }
  25%      { transform: scale(calc(var(--fs, 1) * 1.035)) rotate(-1.4deg); }
  60%      { transform: scale(calc(var(--fs, 1) * .975)) rotate(1.2deg); }
}
.streak-mult { transition: transform .3s cubic-bezier(.2, 1.6, .4, 1); }
.streak-mult.pop { transform: scale(1.16); }

/* ============================================================================
   Level / XP bar
   ============================================================================ */
.xp-bar { position: relative; overflow: hidden; }
.xp-fill {
  position: absolute; inset: 0 auto 0 0; border-radius: 999px;
  background: linear-gradient(90deg, #0d6efd, #b1c5ff);
  transition: width .8s cubic-bezier(.2, .9, .2, 1);
}
.xp-fill::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, .5) 50%, transparent 70%);
  transform: translateX(-100%);
  animation: gm-shimmer 2.6s ease-in-out infinite;
}
@keyframes gm-shimmer { 0% { transform: translateX(-100%); } 55%, 100% { transform: translateX(220%); } }

/* ============================================================================
   Resolution + achievements
   ============================================================================ */
.pop-in { animation: gm-pop-in .5s cubic-bezier(.16, 1.2, .3, 1); }
@keyframes gm-pop-in { 0% { opacity: 0; transform: scale(.94) translateY(10px); } 100% { opacity: 1; transform: none; } }

.badge-tile { transform-style: preserve-3d; }
.badge-tile.flip { animation: gm-badge-flip .85s cubic-bezier(.2, .9, .25, 1); }
@keyframes gm-badge-flip {
  0%   { transform: rotateY(-180deg) scale(.6); opacity: 0; }
  55%  { transform: rotateY(12deg) scale(1.08); opacity: 1; }
  100% { transform: none; opacity: 1; }
}
.badge-locked { filter: grayscale(1); opacity: .32; }

/* leaderboard rank delta */
.delta { opacity: 0; transition: opacity .3s; }
.delta.show { opacity: 1; }

/* ============================================================================
   Motion opt-out — one place, applies to every effect above.
   fx.js checks the same query and skips particles entirely.
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
