/* index.css â€” FULL SWAP-IN */
/* Math Monsters â€” single global stylesheet (iOS 17-ish, playful, minimal) */

:root{
  --mm-font: "Arial Rounded MT Bold", "Arial Rounded", Arial, sans-serif;

  --button-gradient-start: #0095ff;
  --button-gradient-end: #0055fc;

  --mm-bg-base: #0158FF;
  --mm-bg-radial: radial-gradient(
    circle at 50% 50%,
    rgba(0, 0, 0, 0.16) 0%,
    rgba(0, 0, 0, 0.12) 32%,
    rgba(0, 0, 0, 0.08) 48%,
    rgba(0, 0, 0, 0.04) 64%,
    rgba(0, 0, 0, 0.00) 80%
  );  
  
  --ink: #272b34;
  --ink2: rgba(13,20,32,.70);
  --white: #FFFFFF;

  --card:  rgb(255,255,255);
  --glass: rgba(255,255,255,.22);
  --glass2: rgba(255,255,255,.14);
  --stroke: rgba(255,255,255,.22);
  --shadow: 0 18px 40px rgba(0,0,0,.22);
  --shadow2: 0 10px 22px rgba(0,0,0,.12);

  --accent: #2FD1FF;
  --accent2:#6CFFB8;
  --danger: #FF5B6E;

  --r-xl: 28px;
  --r-lg: 22px;
  --r-md: 16px;

  --pad: 16px;
  --gap: 24px;

  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);

  --butter: cubic-bezier(.18,.92,.22,1);
  --spring: cubic-bezier(.22,.85,.34,1);
  --fast: 180ms;
  --med: 360ms;

  /* Battle (uniform pacing) */
  --battle-pause: 600ms;
  --battle-anim: 360ms; /* match JS + feel consistent */
  
  /* Battle pacing scale (JS also slows battle pauses). */
  --battle-scale: 1;
  --hero-size: 300px;
  --monster-size: 300px;

  /* Attack motion (feel) */
--battle-sprite-in: 760ms;
--attack-slide-ms: 430ms;
--hit-shake-ms: 320ms;

/* Friendlier attack tuning */
--attack-lunge: 56px;        /* was 78px */
--attack-overshoot: 6px;     /* was 10px */
--attack-lift: -4px;         /* was -6px */

/* Kid-friendly easing */
--attack-ease: cubic-bezier(.25,.85,.35,1);

--usable-vh: calc(100vh - var(--safe-bottom));

}

/* ================================
   MOBILE: LOCK VIEWPORT (no drag/scroll)
================================ */

/* Lock page to the device viewport */
html, body{
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;        /* no scrolling */
  overscroll-behavior: none; /* stops bounce on supported browsers */
}

/* iOS Safari: prevent â€œpage panâ€ / rubber-band */
body.mm{
  font-weight: 400;

  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  touch-action: none;      /* stops panning/zoom gestures on body */
}

/* Ensure your background truly fills and stays pinned */
.mm-bg{
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
}

body.is-home,
body.is-battle,
.mm-evolution {
  background-color: #0158FF;

  background-image: url("images/additional/background.png");
  background-repeat: no-repeat;
  background-position: center bottom;

  /* Scale by WIDTH, not height */
  /* Slightly zoomed-in on all viewports (fixes "too small" on mobile) */
  background-size: 100vw auto;

}

/* Mobile-only background zoom */
@media (max-width: 768px) {
  body.is-home,
  body.is-battle,
  .mm-evolution {
    background-size: 100vw auto;
  }
}

html,
body {
  background-color: var(--mm-bg-base);
  overscroll-behavior: none;
}

*{ box-sizing:border-box; -webkit-tap-highlight-color: transparent; }


/* ---------- iOS Safari: prevent double-tap zoom + selection/callout ---------- */
html, body{
  -webkit-text-size-adjust: 100%;
}

body, #app{
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

/* Allow taps, but don't let the browser interpret them as zoom gestures */
#app, .mm-shell, .mm-screen, .mm-battleStage, .mm-homeHero, .mm-spriteImg, .mm-qCard{
  touch-action: manipulation;
}

html,body{ height:100%; }

body.mm{
  margin:0;
  font-family: var(--mm-font);
  color: var(--white);
  overflow:hidden;
  background-color: var(--mm-bg-base); /* safe fallback */
}


#app{ position:relative; z-index: 2; }
.mm-bg{ z-index: 0; }


button, input, select, textarea{
  font-family: inherit;
}

.mm-bg,
.mm-bubbles,
.mm-bubble,
.mm-vignette{
  pointer-events: none;
}

/* Landing + Loader use a solid deep-ocean background */
body.is-landing,
body.is-loader{
  background-color: #001b41;
  background-image: none;
}

/* Remove bubbles on Auth screens */
body.is-auth .mm-bubbles,
body.is-register .mm-bubbles {
  display: none;
}

/* Error state for inputs/selects */
.mm-authInput.is-error,
.mm-gradeSelect.is-error {
  border-color: #E20000;
}

.mm-gradeErrorText,
.mm-authError{
  font-size: 16px;
  color: #E20000;
  text-align: left;
}

/* When there is no error text, take up no space */
.mm-gradeErrorText,
.mm-authError:empty{
  display: none;
}

@keyframes mm-shake {
  0%   { transform: translateX(0); }
  25%  { transform: translateX(-3px); }
  50%  { transform: translateX(3px); }
  75%  { transform: translateX(-2px); }
  100% { transform: translateX(0); }
}


.mm-bg{ position:fixed; inset:0; pointer-events:none; }
.mm-vignette{
  position:absolute; inset:-20%;
  background: radial-gradient(circle at 50% 20%, transparent 0 55%, rgba(0,0,0,.30) 85%, rgba(0,0,0,.50) 100%);
  filter: blur(0px);
}
.mm-bubbles{ position:absolute; inset:0; overflow:hidden; }

.mm-bubble{
  position:absolute;
  width: 10px; height: 10px;
  border-radius: 999px;
  background: rgba(255,255,255,.18);
  box-shadow: 0 0 0 1px rgba(255,255,255,.64) inset;
  transform: translate3d(0,0,0);
  animation: bubbleRise linear infinite;
}
@keyframes bubbleRise{
  from{ transform: translate3d(0, 16vh, 0); opacity: 0; }
  10%{ opacity: .55; }
  to{ transform: translate3d(0, -120vh, 0); opacity: 0; }
}

.mm-app{
  position: relative;
  height: var(--usable-vh);
  margin-top: var(--safe-top);
  display: flex;
  align-items: center;
  justify-content: center;
}


.mm-shell{
  width: min(400px, 100%);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}


/* (Topbar removed everywhere per spec) */

.mm-card{
  background: var(--card);
  color: var(--ink);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
  overflow: hidden;
  text-align: center;

  display: flex;          /* âœ… required */
  flex-direction: column; /* common card layout */
  gap: 16px;               /* now works */
}

.mm-card__pad{ padding: 24px; }

.mm-glass{
  background:none;
  border: 2px solid rgba(255,255,255,0.5);
  box-shadow: var(--shadow2);
  backdrop-filter: blur(8px);
color: rgba(0,0,0,.65);
  -webkit-backdrop-filter: blur(8px);
}

.mm-stack{ display:flex; flex-direction:column; gap: 10px; }
.mm-row{
  display:flex;
  gap: 10px;
  align-items:center;
}
.mm-row--between{ justify-content:space-between; }

.mm-field{
  display:flex;
  flex-direction:column;
  gap: 6px;
}
.mm-label{
  font-size: 12px;
  color: rgba(0,0,0,.50);
  font-weight: 800;
}
.mm-input, .mm-select{
  appearance:none;
  width:100%;
  border-radius: 14px;
  border: 1px solid rgba(13,20,32,.10);
  background: rgba(255,255,255,.90);
  padding: 12px 12px;
  font-size: 16px;
  font-weight: 800;
  color: var(--ink);
  outline:none;
}
.mm-input:focus, .mm-select:focus{ border-color: rgba(47,209,255,.65); box-shadow: 0 0 0 4px rgba(47,209,255,.18); }

.mm-btn{
  width:100%;
  border:0;
  border-radius: 18px;
  padding: 14px 14px;
  font-size: 16px;
  font-weight: 800;
  color: var(--ink);
  background: rgba(255,255,255,.92);
  box-shadow: 0 14px 26px rgba(0,0,0,.18);
  transform: translate3d(0,0,0);
  transition: transform var(--fast) var(--spring), filter var(--fast) var(--spring), opacity var(--fast) var(--spring);
}
.mm-btn:active{ transform: translate3d(0,2px,0) scale(.99); filter: brightness(.98); }
.mm-btn[disabled]{ opacity:.45; transform:none; }

.button--primary{
  background: linear-gradient(180deg, var(--button-gradient-start), var(--button-gradient-end));
  color:#fff;
  border:none;
}

.mm-btn--ghost{
  color: var(--white);
  background: rgba(255,255,255,.14);
  border: 1px solid rgba(255,255,255,.18);
  box-shadow: none;
}
.mm-btn--danger{
  color: #2B0C10;
  background: linear-gradient(180deg, rgba(255,91,110,.96), rgba(255,91,110,.70));
}

.mm-pill{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  padding: 8px 12px;
  border-radius: 8px;
  color: rgba(255,255,255);
  font-weight: 800;
  font-size: 16px;
  letter-spacing: .2px;
  background: #001B41;
}

/* ================================
   Universal Progress Component
================================ */

.mm-progress{
  --progress-height: 16px;
  --progress-bg: transparent; /* neutral default */
  --progress-border: rgba(255,255,255,.9);
  background: var(--progress-bg);

  position: relative;
  width: 100%;
  height: 16px;
  border-radius: 999px;
  overflow: hidden;
}

/* Fill */
.mm-progress > .mm-progress__fill{
  position: absolute;
  inset: 0 auto 0 0;
  width: 0%;
  border-radius: 999px;

  /* âœ… TOP â†’ BOTTOM */
  background: linear-gradient(
    180deg,
    var(--progress-gradient-start),
    var(--progress-gradient-end)
  );

  transition: width 1800ms var(--spring);
}

/* Progress utility: render without animating the fill (used on initial Home load) */
.mm-progress.is-static > .mm-progress__fill{
  transition: width 520ms var(--butter);
}


/* Inner shine */
.mm-progress > .mm-progress__fill::after{
  content:"";
  position:absolute;
  inset: 2px 5px 0 2px;
  height: 5px;
  border-radius: 999px;
  background: #ffffff64;
  pointer-events:none;
}

/* Battle difficulty pill */
.mm-diffPill{
  position: absolute;
  left: 50%;
  top: calc(var(--pad) + var(--safe-top));
  transform: translateX(-50%);
  z-index: 20;
  font-weight: 800;
  font-size: 16px;
  letter-spacing: .2px;
  background: #001B41;
  pointer-events: none;
}

/* ================================
   Battle HP: consistent drop speed
================================ */

/* Battle HP (and XP if used in battle): springy again */
body.is-battle .mm-stat .mm-progress > .mm-progress__fill{
  transition-property: width;
  transition-duration: calc(520ms * var(--battle-scale));
  transition-timing-function: var(--spring);
}

/* HP progress bar background */
.mm-progress--hp{
  --progress-bg: #FFFFFF16;
  --progress-gradient-start: #ffbf00;
  --progress-gradient-end: #ff6a00;
}

/* MINI GAME HIT METER — explicit hex alpha */
.mm-progress--miniHit{
  --progress-bg: #00000016;        /* EXACT value you requested */
  --progress-gradient-start: #36dc36;
  --progress-gradient-end: #00b600;
}

/* Keep fill fast + readable */
.mm-progress--miniHit .mm-progress__fill{
  transition-property: width;
  transition-duration: 140ms;
  transition-timing-function: linear;
}





/* ================================
   HOME: Gem Reward (single source of truth)
   - no jumping / no duplicate transforms
================================ */

/* --- Home Gem Track --- */

.mm-gemTrack {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.mm-gemHeader {
  width: 100%;
  text-align: center;
  margin-bottom: 4px;
}

.mm-gemTitle {
  font-weight: 950;
  font-size: 18px;
  letter-spacing: 0.02em;
}

.mm-gemRow {
  display: flex;
  justify-content: center;
  gap: 8px;
}

.mm-gemSlot {
  width: 48px;
  height: 48px;
  flex: 0 0 40px;

  image-rendering: -webkit-optimize-contrast;
  image-rendering: crisp-edges;

  transition:
    transform 220ms cubic-bezier(0.22, 0.61, 0.36, 1),
    filter 180ms ease-out,
    opacity 180ms ease-out;

    will-change: transform, opacity;
    backface-visibility: hidden;
    transform: translateZ(0);
}


/* Has gem: full color, full opacity */
.mm-gemSlot.is-full {
  filter: none;
  opacity: 1;
}

.mm-gemSlot.is-empty {
  filter: grayscale(1);   /* only grayscale */
  opacity: 0.08;          /* use normal opacity, not filter opacity() */
}

/* Popping incoming gem */
.mm-gemSlot.is-pop {
  animation: mm-gemPop 520ms cubic-bezier(0.19, 1, 0.22, 1);
}

@keyframes mm-gemPop {
  0% {
    transform: scale(0.9);
  }
  40% {
    transform: scale(1.18);
  }
  100% {
    transform: scale(1);
  }
}

/* Home – Gem Track tighter padding */
.mm-gemTrack.mm-card__pad {
  padding: 16px;
  gap: 8px
}

/* ---------- GEM FLY-IN CELEBRATION ---------- */
.mm-gemFlyLayer{
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
}

.mm-gemFly{
  position: absolute;
  width: 40px;   /* matches your 40x40 request */
  height: 40px;
  transform: translate(-50%, -50%);
  filter: drop-shadow(0 10px 22px rgba(0,0,0,.22)) drop-shadow(0 2px 6px rgba(0,0,0,.18));
  will-change: transform;
}

.mm-gemSpark{
  position: absolute;
  width: 10px;
  height: 10px;
  transform: translate(-50%, -50%) scale(0.6);
  border-radius: 999px;
  background: rgba(255,255,255,.95);
  filter: drop-shadow(0 8px 16px rgba(0,0,0,.14));
  animation: mmGemSpark 520ms ease-out forwards;
  will-change: transform, opacity;
}
@keyframes mmGemSpark{
  0%   { opacity: 0; transform: translate(-50%,-50%) scale(0.4); }
  20%  { opacity: 1; transform: translate(-50%,-50%) scale(1.0); }
  100% { opacity: 0; transform: translate(-50%,-50%) scale(1.7); }
}

.mm-gemImpactRing{
  position: absolute;
  width: 12px;
  height: 12px;
  transform: translate(-50%, -50%) scale(0.3);
  border-radius: 999px;
  border: 2px solid rgba(255,255,255,.9);
  opacity: 0;
  filter: drop-shadow(0 10px 22px rgba(0,0,0,.18));
}
.mm-gemImpactRing.is-hit{
  animation: mmGemRing 480ms cubic-bezier(.2,.9,.2,1) forwards;
}
@keyframes mmGemRing{
  0%   { opacity: 0; transform: translate(-50%,-50%) scale(0.35); }
  20%  { opacity: 1; transform: translate(-50%,-50%) scale(1.1); }
  100% { opacity: 0; transform: translate(-50%,-50%) scale(2.4); }
}

/* Slot “land” bounce (the gem you just earned) */
.mm-gemSlot.is-land{
  animation: mmGemLand 720ms cubic-bezier(.2,.9,.2,1) both;
  transform-origin: 50% 65%;
}
@keyframes mmGemLand{
  0%   { transform: translateY(0) scale(1); }
  22%  { transform: translateY(-10px) scale(1.08); }
  44%  { transform: translateY(2px)  scale(0.98); }
  64%  { transform: translateY(-4px) scale(1.03); }
  100% { transform: translateY(0) scale(1); }
}

.mm-screen{
  position:relative;
  height:100%;
  display:flex;
  flex-direction:column;
  gap: var(--gap);
}

.mm-screen__grow{ flex:1 1 auto; display:flex; flex-direction:column; gap: var(--gap); }
.mm-center{ align-items:center; justify-content:center; text-align:center; }

/* ================================
   ABSOLUTE SPRITE SIZE LOCK
   (No responsive scaling, ever)
================================ */

.mm-homeSwimWrap,
.mm-art,
.mm-heroShimmer,
.mm-spriteWrap,
.mm-evolution__stage {
  width: 300px !important;
  height: 300px !important;
  min-width: 300px !important;
  min-height: 300px !important;
  max-width: 300px !important;
  max-height: 300px !important;
  flex: 0 0 300px !important;
}

/* Inner sprite images â€” never resize */
/* Inner sprite images â€” never resize */
.mm-homeSwim,
.mm-spriteImg,
.mm-evolution__img{
  width: 300px !important;
  height: 300px !important;
  min-width: 300px !important;
  min-height: 300px !important;
  max-width: 300px !important;
  max-height: 300px !important;

  object-fit: contain;
  display: block;
}

.mm-evolution__img{
  position: absolute;
  top: 50%;
  left: 50%;

  transform: translate(-50%, -50%) scale(1);
  transform-origin: 50% 50%;

  will-change: transform;
}


.mm-hero{
  width: min(400px, 100%);
  margin: 0 auto;

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  gap: 40px;
  height: auto;        /* ðŸ”¥ important */
  min-height: unset;  /* ðŸ”¥ important */
}

.mm-homeHero.is-locked{
  pointer-events: none;
  cursor: default;
  filter: saturate(.95) brightness(.95);
}


/* ================================
   Image-only shimmer (sprite-only)
================================ */

.mm-heroShimmer{
  position: absolute;
  inset: 0;
  width: var(--hero-size);
  height: var(--hero-size);
  display: block;

  /* keeps any blur from â€œbleedingâ€ past the 300x300 area */
  overflow: hidden;

  /* helps prevent weird blend artifacts leaking outside */
  contain: paint;
}

/* keep the masked layer fixed */
.mm-heroShimmer::after{
  content:"";
  position:absolute;
  inset: 0;
  pointer-events:none;
  z-index: 3;

  /* narrower band so it reads as a sweep, not a full-tint */
  background: linear-gradient(
    120deg,
    rgba(255,255,255,0) 46%,
    rgba(180,240,255,.22) 49%,
    rgba(255,255,255,.52) 50%,
    rgba(180,240,255,.22) 51%,
    rgba(255,255,255,0) 54%
  );

  /* IMPORTANT: make the gradient â€œtravelâ€ by moving its position */
  background-size: 260% 260%;
  background-position: -180% 50%;
  opacity: 0;

  mix-blend-mode: screen;
  filter: none; /* blur can make it feel like a big overlay */

  animation: none; /* â›” paused until explicitly enabled */

  /* âœ… alpha mask from the sprite PNG */
  -webkit-mask-image: var(--mm-sprite-mask);
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: center;
  -webkit-mask-size: 100% 100%;

  mask-image: var(--mm-sprite-mask);
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: 100% 100%;
}

/* âœ… shimmer only after hero has fully loaded in */
.mm-heroShimmer.is-shimmering::after{
  animation: mmHeroShimmerBG 3.2s ease-in-out infinite;
}


/* animate background-position (NOT transform) */
@keyframes mmHeroShimmerBG{
  0%   { opacity: 0; background-position: -180% 50%; }
  14%  { opacity: 1; }
  60%  { opacity: 1; background-position: 180% 50%; }
  74%  { opacity: 0; }
  100% { opacity: 0; background-position: 180% 50%; }
}

/* ================================
   Ground Shadow (Pokemon-style)
================================ */

.mm-groundShadow{
  position: absolute;
  left: 50%;
  bottom: 8px;

  width: 220px;   /* â¬…ï¸ was 160px */
  height: 40px;   /* â¬…ï¸ was 28px */

  transform: translateX(-50%);

  background: radial-gradient(
    ellipse at center,
    rgba(0,0,0,.32) 0%,
    rgba(0,0,0,.22) 35%,
    rgba(0,0,0,.10) 55%,
    rgba(0,0,0,.04) 70%,
    rgba(0,0,0,0) 75%
  );

  filter: blur(7px);  /* â¬…ï¸ optional: slightly softer for larger shadow */
  opacity: .75;

  pointer-events: none;
  z-index: 0;
}


/* Slight shadow squash during attacks */
.mm-attack-slide-hero ~ .mm-groundShadow,
.mm-attack-slide-monster ~ .mm-groundShadow{
  transform: translateX(-50%) scaleX(1.15) scaleY(0.9);
  opacity: .85;
  transition: transform 160ms ease-out, opacity 160ms ease-out;
}


/* optional micro "click" feel */
.mm-homeSwim{
  animation: mmHeroShimmerPulse 2.2s ease-in-out infinite;
  width:100%; height:100%; display:block; object-fit:contain;
}

@keyframes mmHeroShimmerPulse{
  0%,100%{ filter:none; }
  38%{ filter: brightness(1.05) saturate(1.04); }
}



/* ================================
   Home â€œExcitingâ€ Intro
================================ */

/* root hook on Home */
.mm-homeIntro .mm-homeTop,
.mm-homeIntro .mm-homeBtns{
  opacity: 0;
  transform: translate3d(0, 14px, 0);
  filter: blur(0px);
}

/* Staggered reveal */
.mm-homeIntro.is-in .mm-homeTop{
  animation: mmHomePop 1000ms var(--spring) 0ms both;
}
.mm-homeIntro.is-in .mm-homeBtns{
  animation: mmHomePop 1000ms var(--spring) 280ms both;
}

@keyframes mmHomePop{
  0%   { opacity: 0; transform: translate3d(0, 18px, 0) scale(.98); }
  60%  { opacity: 1; transform: translate3d(0, -4px, 0) scale(1.02); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
}

/* Make the hero â€œarriveâ€ after the top UI */
.mm-homeIntro .mm-art{
  position: relative;
  transform: translate3d(0, 10px, 0) scale(.98);
  opacity: 0;
}

.mm-homeIntro.is-in .mm-art{
  animation: mmHomeHeroIn 620ms var(--spring) 180ms both;
}
@keyframes mmHomeHeroIn{
  0%   { opacity: 0; transform: translate3d(0, 18px, 0) scale(.96); }
  65%  { opacity: 1; transform: translate3d(0, -6px, 0) scale(1.03); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
}

@keyframes mmHomeHeroOut {
  0% {
    opacity: 1;
    /* match the hero's resting position in evolution */
    transform: translate(-50%, -50%) scale(1);
  }
  35% {
    opacity: 1;
    /* slight lift + overshoot, mirroring evoFocusIn */
    transform: translate(-50%, -52%) scale(1.03);
  }
  100% {
    opacity: 0;
    /* drift down + soften out */
    transform: translate(-50%, -44%) scale(0.96);
  }
}




/* ================================
   Home Battle Floating Action Button
================================ */

/* Wrapper that animates BOTH hero sprite + FAB together */
.mm-homeSwimWrap{
  position: relative;
  width: 300px;
  height: 300px;
  margin: 0 auto;
}

body.is-home .mm-homeSwimWrap{
  opacity: 0;
  transform: translate3d(0, 18px, 0) scale(.94);

  animation:
    mmHeroPopIn 1100ms cubic-bezier(.18,.92,.22,1) 0ms forwards,
    mmDriftY 4.2s ease-in-out infinite 1750ms;

  will-change: transform, opacity;
}

/* The hero img just fills the wrapper */
.mm-homeSwim{
  position: relative;
  z-index: 2;
  width:100%; height:100%;
  object-fit: contain;
  transform: translateZ(0);
  
}

/* FAB: 140 circle, 100 icon */
.mm-battle-fab{
  position: absolute;
  right: 0px;
  bottom: 0px;

  width: 140px;
  height: 140px;
  border-radius: 999px;

  display: flex;
  align-items: center;
  justify-content: center;

  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  box-shadow:
    /* Top-left rim highlight */
    inset 1px 1px 0px rgba(255, 255, 255, 0.40),
  
    /* Bottom-right rim highlight */
    inset -1px -1px 0px rgba(255, 255, 255, 0.40);

  cursor: pointer;
  z-index: 3;

  transform: translateZ(0);
  will-change: transform;
}

.mm-battle-fab img{
  width: 100px;   /* â† try 72 or 80 */
  height: 100px;
  object-fit: contain;
  pointer-events: none;
}

/* Group wrappers */
.mm-homeTop{
  width: 100%;
  display:flex;
  flex-direction: column;
  align-items: center;
  gap: 32px;
}
.mm-homeBtns{
  width: 100%;
  display:flex;
  flex-direction: column;
  gap: var(--gap);
}

.mm-big{
  font-size: 36px;
  font-weight: 800;
  color: var(--white);
}
.mm-muted{ color: rgba(255,255,255,.74); font-weight: 800; font-size: 14px; }

.mm-art{
  width: 300px;
  height: 300px;
  position: relative;   /* anchor for FAB */
  overflow: visible;
}

.mm-art > .mm-homeSwimWrap > .mm-homeSwim{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit: contain;
}


/* Home hero pop-in */
@keyframes mmHeroPopIn {
  0% {
    opacity: 0;
    transform: translate3d(0, 24px, 0) scale(0.92);
  }
  60% {
    opacity: 1;
    transform: translate3d(0, -4px, 0) scale(1.04);
  }
  100% {
    opacity: 1;
    transform: translate3d(0, 0, 0) scale(1);
  }
}

@keyframes mmDriftY{
  0%   { transform: translate3d(0, 0px, 0); }
  50%  { transform: translate3d(0, -10px, 0); }
  100% { transform: translate3d(0, 0px, 0); }
}


body.is-home .mm-homeSwim{
  opacity: 1;           /* wrapper handles opacity */
  will-change: transform;
}


body.is-home .mm-screen__grow{
  display:flex;
  align-items:center;
  justify-content:center;
}

.mm-battleStage,
.mm-spriteWrap,
.mm-spriteImg{
  transform: translateZ(0);
  -webkit-transform: translateZ(0);
}

/* Only reset filter on the image, not the wrapper */
.mm-spriteImg{
  width: 100%;
  height: 100%;
  object-fit: contain;
  -webkit-user-drag: none;
  user-drag: none;
  -webkit-user-select: none;
  user-select: none;
  backface-visibility: hidden;
  will-change: transform;
  filter: none;
  filter: drop-shadow(0 16px 18px rgba(0,0,0,.16));
}



.mm-battleStage{
  position: relative;
  flex: 1 1 auto;
  overflow:visible;

  /* Sprite arena spacing: keep fighters composed on desktop without media queries */
  --sprite-size: 300px; /* sprites are hard-locked to 300x300 */
  --sprite-half: calc(var(--sprite-size) / 2);
  --battle-gap: 200px;
  --battle-y: 180px; /* increase = monster higher + hero lower */
}

/* Battle should ignore .mm-app padding and pin to viewport like the end-card overlay */
body.is-battle .mm-battleStage{
  position: fixed;
  inset: 0;
}

.mm-spriteWrap{
  position:absolute;
  width: 300px;
  height: 300px;
  opacity: 0;

  transition-property: transform, opacity;
  transition-duration: var(--battle-sprite-in), var(--battle-sprite-in);
  transition-timing-function: var(--spring), var(--butter);

  transform: translateZ(0);
  backface-visibility: hidden;
  will-change: transform, opacity;

  filter: none
}

/* Stats now live inside the wrapper, so lock them there */
.mm-spriteWrap .mm-stat{
  position: absolute;
  z-index: 5; /* above sprite/shadow */
}

/* HERO: centered + 40px RIGHT
   centered is 70px, so 70 + 40 = 110 */
.mm-spriteWrap.hero .mm-stat.hero{
  right: -120px;
  bottom: 110px;
}

/* MONSTER: centered + 40px LEFT
   centered is 70px, so 70 - 40 = 30 */
.mm-spriteWrap.monster .mm-stat.monster{
  left: -120px;
  top: 110px;
}

/* ================================
   Battle LOADING (intro) â€” horizontal slide-in
   hero: left âžœ right
   monster: right âžœ left
================================ */

/* Start OFF-position (hidden) â€” then JS adds .is-in and we slide toward center */
.mm-spriteWrap.hero{
  transform: translate3d(-96px, var(--battle-y), 0) scale(1.02);
}

.mm-spriteWrap.monster{
  transform: translate3d(96px, calc(var(--battle-y) * -1), 0) scale(1.02);
}

/* âœ… Make wrappers visible once battle intro runs */
.mm-spriteWrap.hero.is-in{
  opacity: 1;
  transform: translate3d(16px, calc(-2px + var(--battle-y)), 0) scale(1.02);
}

.mm-spriteWrap.monster.is-in{
  opacity: 1;
  transform: translate3d(-16px, calc(-2px - var(--battle-y)), 0) scale(1.02);
}

/* keep vertical separation after settle */
.mm-spriteWrap.hero.is-in.is-settle{
  transform: translate3d(0, var(--battle-y), 0) scale(1.02);
}

.mm-spriteWrap.monster.is-in.is-settle{
  transform: translate3d(0, calc(var(--battle-y) * -1), 0) scale(1.02);
}

.mm-spriteWrap.is-in.is-settle{
  transition-property: transform, opacity;
  transition-duration: 360ms, 280ms;
  transition-timing-function:
    cubic-bezier(.12,.75,.25,1),
    cubic-bezier(.18,.92,.22,1);

  transform: translate3d(0,0,0) scale(1.02);
}

.mm-stat{
  width: 160px;
  padding: 16px;
  border-radius: 12px;

  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;

  opacity: 0;
  transform: translate3d(0, 14px, 0);
  transition:
    transform 360ms cubic-bezier(.18,.92,.22,1),
    opacity 300ms cubic-bezier(.18,.92,.22,1);
}

.mm-stat.is-in{
  opacity: 1;
  transform: translate3d(0, 0, 0);
}


.mm-stat__name{
  font-weight: 800;
  color: rgba(255,255,255);
  font-size: 20px;
}

/* Battle stat context */
.mm-stat .mm-progress{
  --progress-height: 16px;
  --progress-bg: rgba(255,255,255,.20);
  --progress-border: rgba(255,255,255,.18);
  box-shadow: none;
}

/* ---------- Attack feel: slide-in + defender shake ---------- */

/* =========================================
   Simple attacks: hero -> RIGHT, monster -> LEFT
   Keep attack on INNER img only
========================================= */

.mm-attack-slide-hero{
  transform-origin: 50% 60%;
  animation: mmAttackHeroLR calc(var(--attack-slide-ms) * var(--battle-scale)) var(--attack-ease) 1 both;
}

.mm-attack-slide-monster{
  transform-origin: 50% 60%;
  animation: mmAttackMonsterRL calc(var(--attack-slide-ms) * var(--battle-scale)) var(--attack-ease) 1 both;
}

/* linear timing + shaped keyframes = consistent â€œbutteryâ€ motion */
@keyframes mmAttackHeroLR{
  0%   { transform: translate3d(0,0,0) scale(1); }
  22%  { transform: translate3d(-8px, 3px, 0) scale(0.985); } /* gentle anticipate */
  58%  { transform: translate3d(var(--attack-lunge), var(--attack-lift), 0) scale(1.06); } /* smooth peak */
  74%  { transform: translate3d(18px, -1px, 0) scale(1.02); } /* glide back */
  100% { transform: translate3d(0,0,0) scale(1); }
}

@keyframes mmAttackMonsterRL{
  0%   { transform: translate3d(0,0,0) scale(1); }
  22%  { transform: translate3d(8px, 3px, 0) scale(0.985); }
  58%  { transform: translate3d(calc(var(--attack-lunge) * -1), var(--attack-lift), 0) scale(1.06); }
  74%  { transform: translate3d(-18px, -1px, 0) scale(1.02); }
  100% { transform: translate3d(0,0,0) scale(1); }
}


.mm-hit-shake{
  transform-origin: 50% 55%;
  animation: mmHitSquish calc(var(--hit-shake-ms) * var(--battle-scale)) var(--attack-ease) 1 both;
}

@keyframes mmHitSquish{
  0%   { transform: translate3d(0,0,0) scale(1) rotate(0deg); }
  18%  { transform: translate3d(-6px, 2px,0) scale(0.985, 1.015) rotate(-1.4deg); }
  40%  { transform: translate3d( 7px,-1px,0) scale(1.01, 0.99)  rotate( 1.1deg); }
  62%  { transform: translate3d(-3px, 1px,0) scale(0.995, 1.005) rotate(-0.8deg); }
  100% { transform: translate3d(0,0,0) scale(1) rotate(0deg); }
}

/* Final blow shake (a bit longer + punchier) */
.mm-final-shake{
  transform-origin: 50% 55%;
  animation: mmFinalShake 520ms cubic-bezier(.2,.9,.3,1) 1 both;
}

@keyframes mmFinalShake{
  0%   { transform: translate3d(0,0,0) scale(1) rotate(0deg); }
  15%  { transform: translate3d(-10px, 2px,0) scale(0.99,1.01) rotate(-2.6deg); }
  35%  { transform: translate3d( 12px,-2px,0) scale(1.01,0.99) rotate( 2.2deg); }
  55%  { transform: translate3d(-7px, 1px,0) scale(0.995,1.005) rotate(-1.4deg); }
  100% { transform: translate3d(0,0,0) scale(1) rotate(0deg); }
}

.mm-attackFx{
  position:absolute;
  width: 180px; height: 180px;
  object-fit: contain;
  opacity: 0;
  transform: scale(.7);
  pointer-events:none;
  filter: drop-shadow(0 14px 16px rgba(0,0,0,.30));
}
.mm-attackFx.is-pop{
  opacity: 1;
  transform: scale(1);
  transition: transform calc(260ms * var(--battle-scale)) var(--spring), opacity calc(260ms * var(--battle-scale)) var(--spring);
}
.mm-attackFx.is-out{
  opacity: 0;
  transform: scale(.9);
  transition: transform calc(320ms * var(--battle-scale)) var(--spring),
              opacity  calc(320ms * var(--battle-scale)) var(--spring);
}

/* ================================
   ATTACK FX — anchored per sprite
   (hero + monster separately)
================================ */

/* Make each sprite wrapper a positioning context (already absolute, but keep it explicit) */
.mm-spriteWrap{
  position: absolute;
}

/* FX element that lives INSIDE .mm-spriteWrap */
.mm-spriteWrap .mm-attackFx{
  position: absolute;
  left: 50%;
  top: 50%;

  width: 180px;
  height: 180px;
  object-fit: contain;

  /* baseline: perfectly centered */
  transform: translate3d(-50%, -50%, 0) scale(var(--fx-scale, 1));

  opacity: 0;
  pointer-events: none;
  z-index: 10; /* above sprite image + shadow */
  filter: drop-shadow(0 14px 16px rgba(0,0,0,.30));
}

/* Per-side hard-coded offsets (tweak these ONCE until perfect) */
.mm-spriteWrap.hero{
  --fx-x: 0px;   /* +right / -left */
  --fx-y: 0px;   /* +down  / -up  */
  --fx-scale: 1;
}
.mm-spriteWrap.monster{
  --fx-x: 0px;
  --fx-y: 0px;
  --fx-scale: 1;
}

/* Apply offsets */
.mm-spriteWrap .mm-attackFx{
  transform: translate3d(
      calc(-50% + var(--fx-x)),
      calc(-50% + var(--fx-y)),
      0
    )
    scale(var(--fx-scale, 1));
}

/* Your existing pop/out states still work */
.mm-spriteWrap .mm-attackFx.is-pop{
  opacity: 1;
  transform: translate3d(
      calc(-50% + var(--fx-x)),
      calc(-50% + var(--fx-y)),
      0
    )
    scale(calc(var(--fx-scale, 1) * 1)); /* keep scale consistent */
  transition: transform calc(260ms * var(--battle-scale)) var(--spring),
              opacity   calc(260ms * var(--battle-scale)) var(--spring);
}

.mm-spriteWrap .mm-attackFx.is-out{
  opacity: 0;
  transform: translate3d(
      calc(-50% + var(--fx-x)),
      calc(-50% + var(--fx-y)),
      0
    )
    scale(calc(var(--fx-scale, 1) * .9));
  transition: transform calc(320ms * var(--battle-scale)) var(--spring),
              opacity   calc(320ms * var(--battle-scale)) var(--spring);
}


/* ================================
   Attack FX: scale-up on hit
================================ */

@keyframes mmFxHitScale {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.28); }
  75%  { transform: scale(0.90); }
  100% { transform: scale(1); }
}

/* add/remove this class at impact */
.mm-attackFx.mm-fx-hit {
  animation: mmFxHitScale calc(220ms * var(--battle-scale)) cubic-bezier(.2,.9,.3,1) 1;
}

.mm-qCard{
  position: absolute;

  /* âœ… Match end-card overlay gutters */
  left: calc(var(--pad) + var(--safe-left));
  right: calc(var(--pad) + var(--safe-right));

  /* âœ… Same bottom treatment as end card */
  bottom: calc(var(--pad) + var(--safe-bottom));

  /* âœ… Same â€œ400 desktop, shrink on mobileâ€ behavior */
  max-width: 400px;
  margin: 0 auto;

  background: rgba(255,255,255);
  color: var(--ink);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);

  /* inner pad controls padding */
  padding: 24px;

  /* motion: only Y now (no translateX needed) */
  transform: translate3d(0, 18px, 0);
  opacity: 0;

  transition:
    transform calc(var(--battle-anim) * var(--battle-scale)) var(--butter),
    opacity   calc((var(--battle-anim) * .85) * var(--battle-scale)) var(--butter);
}

.mm-qCard.is-up{
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* Bottom sheet card – modeled on mm-qCard */
.mm-evolution-card{
  position: fixed;
  z-index: 5;

  /* match end card gutters + safe area */
  bottom: calc(8px + env(safe-area-inset-bottom));
  margin: 0 auto;

  /* card look */
  background: rgba(255, 255, 255);
  color: var(--ink);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
  padding: 24px;
  margin-bottom: 16px;

  /* motion: slide up from bottom */
  transform: translate3d(0, 18px, 0);
  opacity: 0;
  transition:
    transform calc(var(--battle-anim) * var(--battle-scale)) var(--butter),
    opacity   calc((var(--battle-anim) * .85) * var(--battle-scale)) var(--butter);
}

/* JS toggles these classes */
.mm-evolution-card.is-up{
  opacity: 1;
  transform: translate3d(0, 0, 0);
}
.mm-evolution-card.is-hide{
  opacity: 0;
  transform: translate3d(0, 18px, 0);
}

/* Layout for avatar + copy + button */
.mm-evolution-card__row{
  display: flex;
  flex-direction: column;
  gap: 24px;
  align-items: flex-start;
  text-align: left;
}

.mm-evolution-card__avatar{
  width: 80px;
  height: 80px;
  border-radius: 12px;
  flex-shrink: 0;
}


.mm-evolution-card__copy{
  margin: 0;
  font-size: 24px;
  line-height: 1.3;
  letter-spacing: -0.25;
  color: var(--ink);
}


.mm-evolution-card__actions{
  margin-top: 24px;
  display:flex;
  justify-content:flex-end;
}

.mm-question{
  font-weight: 800;
  font-size: 28px;
  width: 100%;
  text-align: center;
  padding: 8px 0px 8px 0px;
}

.mm-answers{
  margin-top: 16px;
  margin-bottom: 16px;
  display:grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.mm-answer{
  -webkit-appearance: none;
  appearance: none;

  color: var(--ink);
  -webkit-text-fill-color: var(--ink); /* iOS/Safari safety */

  font-family: inherit;

  border-radius: 12px;
  border: 3px solid rgba(0, 0, 0, 0.08);
  background: white;
  height: 64px;
  font-weight: 800;
  font-size: 24px;
  text-align:center;

  transition: transform var(--fast) var(--spring), box-shadow var(--fast) var(--spring), border-color var(--fast) var(--spring);
}

.mm-answer:active{ transform: translate3d(0,2px,0) scale(.99); }
.mm-answer.is-selected{
  background: #EBF3FF;
  border-color: #006AFF;
  box-shadow: none;
}


.mm-qActions{ margin-top: 12px; display:flex; gap: 10px; }
.mm-qActions .mm-btn{ padding: 12px 14px; border-radius: 18px; font-size: 15px; }

.mm-overlay{
  position: fixed;
  inset: 0;
  display:none;

  align-items: flex-end;     /* â¬…ï¸ push card to bottom */
  justify-content: center;   /* horizontal center */

  padding:
    calc(var(--pad) + var(--safe-top))
    calc(var(--pad) + var(--safe-right))
    calc(var(--pad) + var(--safe-bottom))
    calc(var(--pad) + var(--safe-left));

  background: rgba(0,0,0,.20);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.mm-overlay.is-show{ display:flex; }

/* ================================
   End of Battle Card
================================ */

.mm-endCard{
  width: 400px;
  text-align: center;

  opacity: 0;
  transform: translate3d(0, 24px, 0);

  transition:
    transform 420ms cubic-bezier(.18,.85,.25,1),
    opacity   320ms ease-out;
  will-change: transform, opacity;
}

.mm-endCard.is-in{
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

.mm-endTitle{
  margin: 0 0 16px 0;
  font-weight: 800;
  font-size: 28px;
}

.mm-gemBox{
  width: 100%;
  background: #F4F6FA;
  border-radius: 16px;
  padding: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 16px;
}

.mm-gemImg{
  width: 120px;
  height: 120px;
  object-fit: contain;
  display: block;
}

/* Full-page loader */
.mm-loaderFull{
  width: 100%;
  height: 100%;
  display:flex;
  align-items:center;
  justify-content:center;
}

.mm-loaderFull__inner{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap: 24px;
}

/* Loader logo should NOT be sprite-sized */
.mm-loaderLogo{
  width: 160px !important;
  height: 160px !important;
  min-width: 160px !important;
  min-height: 160px !important;
  max-width: 160px !important;
  max-height: 160px !important;
  object-fit: contain;
  display: block;
}

.mm-loaderTitle{
  font-size: 28px;
  font-weight: 800;
  color: rgba(255,255,255,.92);
}

.mm-spinner{
  width: 44px;
  height: 44px;
  border-radius: 999px;
  border: 4px solid rgba(255,255,255,.20);
  border-top-color: rgba(255,255,255,.85);

  animation: spinnerSpinPulse 900ms linear infinite;
  will-change: transform;
}

@keyframes spinnerSpinPulse{
  0%{
    transform: rotate(0deg) scale(0.92);
  }
  40%{
    transform: rotate(144deg) scale(1.06);
  }
  70%{
    transform: rotate(252deg) scale(0.98);
  }
  100%{
    transform: rotate(360deg) scale(0.92);
  }
}


.mm-toast{
  position: fixed;
  left: 50%;
  bottom: calc(16px + var(--safe-bottom));
  transform: translateX(-50%) translateY(20px);
  opacity: 0;
  background: rgba(0,0,0,.60);
  color: rgba(255,255,255,.92);
  padding: 10px 12px;
  border-radius: 999px;
  font-weight: 800;
  font-size: 13px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: opacity 200ms var(--spring), transform 200ms var(--spring);
  pointer-events:none;
}
.mm-toast.is-show{ opacity: 1; transform: translateX(-50%) translateY(0); }

@media (max-height: 700px){
  :root{ --hero-size: clamp(150px, 38vw, 210px); --monster-size: clamp(150px, 38vw, 210px); }
  .mm-battleStage{ min-height: 320px; }
}

/* ---------- Landing Overrides (MM landing v2) ---------- */

.landing-wrap{
  width: 100%;
  max-width: 560px;
  margin: 0 auto;

  min-height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center; /* ✅ vertical center */
  align-items: center;

  padding: 16px;
  padding-bottom: calc(16px + env(safe-area-inset-bottom));

  gap: 24px;
}



.landing-brand{
  display:flex;
  flex-direction: column;
  align-items:center;
  justify-content:center;
  gap: 14px;
}

.landing-logo{
  width: 160px;
  height: 160px;
  object-fit: contain;
}

.landing-title{
  font-size: 48px;
  font-weight: 800;
  text-align: center;
  margin: 0;
}

.landing-tagline{
  font-size: 20px;
  font-weight: 800;
  line-height: 150%;
  text-align: center;
  margin: 0;
  color: rgba(255,255,255,0.5);
}

.landing-actions{
  display:flex;
  flex-direction: column;
  gap: var(--gap);
  width: 100%;
  margin-top: 14px;
}

/* Button system (Josh spec) */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 64px;
  border-radius: 12px;
  font-size: 20px;
  font-weight: 800;
  text-decoration: none;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  width: 100%;
}

.button--primary {
  color: #ffffff;
  border: none;
}

.button--outline {
  color: #ffffff;
  background-color: #ffffff16;
  border: none;
}

.button:not(.is-correct):not(.is-wrong):not(:disabled):hover{
  transform: translateY(-2px);
  box-shadow: none;
}

.button:focus {
  outline: none;
}


/* Answer feedback */
.mm-answer.is-correct{
  border-color: #00B600;
  background: rgba(0, 182, 0, 0.08);
  color: #00B600;            /* âœ… text highlight */
  font-weight: 800;
}
.mm-answer.is-wrong{
  border-color: #E20000;
  background: rgba(226, 0, 0, 0.08);
  color: #E20000;            /* âœ… text highlight */
  font-weight: 800;
}
.mm-answer[disabled]{
  opacity: 1;
  transform: none;

  /* âœ… keep non-right/wrong answers dark */
  color: var(--ink);
  -webkit-text-fill-color: var(--ink); /* âœ… Safari fix */
}



/* Submit button feedback */
.button.is-correct{
  background: #00B600 !important;
  border-color: transparent !important;
  color: #ffffff !important;
}
.button.is-wrong{
  background: #E20000 !important;
  border-color: transparent !important;
  color: #ffffff !important;
}

/* ================================
   Evolution Flow (Full-screen)
   "Level Up!" page (landing-like)
================================ */

.mm-evolution{
  position: fixed;
  inset: 0;
  z-index: 9999;

  /* fade-in */
  display: none;
  opacity: 0;
  transition: opacity 900ms ease-out; /* â¬…ï¸ slow cinematic fade */

  align-items: center;
  justify-content: center;
  padding: 16px;
  box-sizing: border-box;
}

.mm-evolution.is-show{
  display:flex;
  opacity: 1;
}

/* Centered column like landing */

.mm-evolution__title{
  font-size: 48px;
  font-weight: 800;
  margin: 0;
  color: rgba(255,255,255);
}

/* Stage stays 300x300 hero size */
/* Center the evolution “stage” itself */
.mm-evolution__wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100dvh;
  width: 100%;
  max-width: 420px;
  margin: 0 auto;
  position: relative;
}

.mm-evolution__stage {
  position: relative;
  width: 300px;
  height: 300px;
}



/* subtle â€œrising energyâ€ particles (no assets) */
.mm-evolution__stage::before{
  content:"";
  position:absolute;
  inset: -18%;
  border-radius: 999px;
  background:
    radial-gradient(circle, rgba(255,255,255,.70) 0 1.5px, transparent 2px) 10px 18px / 70px 70px,
    radial-gradient(circle, rgba(47,209,255,.65) 0 2px, transparent 3px) 30px 44px / 90px 90px,
    radial-gradient(circle, rgba(108,255,184,.55) 0 1.5px, transparent 3px) 0 0 / 80px 80px;
  opacity: 0;
  filter: drop-shadow(0 22px 30px rgba(0,0,0,.28));
  transform: scale(.9);
  pointer-events:none;
}

/* Only burst during hatch / morph, not on initial show */
.mm-evolution.is-hatch .mm-evolution__stage::before,
.mm-evolution.is-morph .mm-evolution__stage::before{
  animation: mmEvolveSpark 900ms var(--spring) 0ms both;
}

@keyframes mmEvolveSpark{
  0%{ opacity: 0; transform: scale(.86) rotate(-6deg); }
  55%{ opacity: 1; transform: scale(1.02) rotate(6deg); }
  100%{ opacity: 0; transform: scale(1.12) rotate(14deg); }
}

/* sprite layers */

.mm-evolution__img--from{
  opacity: 0;
  /* Match New Game egg baseline exactly so pulses are perfectly centered */
  transform: translate(-50%, -50%) scale(1);
  filter: drop-shadow(0 18px 24px rgba(0,0,0,.28));
}



.mm-evolution__img--to{
  opacity: 0;
  transform: translate(-50%, -50%) scale(.5);
  filter: blur(10px) drop-shadow(0 18px 24px rgba(0,0,0,.28));
}

.mm-evolution.is-morph .mm-evolution__img--from{
  opacity: 0;
  filter: blur(4px);
  pointer-events: none;
  display: none;
}


.mm-evolution.is-morph .mm-evolution__img--to {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
  /* Match “from” sprite + home hero shadow so it doesn’t look heavier */
  filter: drop-shadow(0 18px 24px rgba(0,0,0,.28));
  transition:
    opacity 420ms var(--spring),
    transform 420ms var(--spring),
    filter 420ms var(--spring);
}


.mm-evolution__img--egg{
  opacity: 0;
  /* Match the pulse keyframe baseline so there's no jump */
  transform: translate(-50%, -50%) scale(1);
  filter: drop-shadow(0 18px 24px rgba(0,0,0,.28));
}


/* Ensure new evolution sprite always renders above old */
.mm-evolution__img--egg,
.mm-evolution__img--from{
  z-index: 1;
}

.mm-evolution__img--to{
  z-index: 2;
}

/* intro egg: use home hero load + drift */
.mm-evolution--intro .mm-evolution__img--to{
  opacity: 0;
  transform: translate(-50%, -50%) scale(.9);
  filter: drop-shadow(0 18px 24px rgba(0,0,0,.28));
}

.mm-evolution--intro.is-egg-in .mm-evolution__img--egg{
  opacity: 1;
  animation: egg-pop-in 1.1s cubic-bezier(.2,.9,.2,1) both;
}

/* Later evolutions: current hero pops in using the same home-style motion */
.mm-evolution.is-reveal.is-egg-in .mm-evolution__img--from {
  opacity: 1;
  animation: hero-pop-in 900ms cubic-bezier(.2,.9,.2,1) both;
}

.mm-evolution--intro.is-hatch .mm-evolution__img--egg{
  animation: none !important;
}

/* First evolution: egg + hero pop (centered) */
.mm-evolution--intro.is-hatch .mm-evolution__img--to{
  opacity: 1;
  animation: hero-hatch-in 0.9s cubic-bezier(.2,.9,.2,1) both;
}

@keyframes egg-pop-in {
  0%   { transform: translate(-50%, -50%) scale(0.6); opacity: 0; }
  60%  { transform: translate(-50%, -50%) scale(1.08); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1); }
}

@keyframes egg-pop-out {
  0%   { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  55%  { transform: translate(-50%, -50%) scale(0.6); opacity: 0.08; }
  100% { transform: translate(-50%, -50%) scale(0.3); opacity: 0; }
}

@keyframes hero-pop-in {
  0%   { transform: translate(-50%, -58%) scale(0.4); opacity: 0; }
  70%  { transform: translate(-50%, -58%) scale(1.08); opacity: 1; }
  100% { transform: translate(-50%, -58%) scale(1); }
}

/* Hatch: centered, no vertical travel */
@keyframes hero-hatch-in {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.4);
  }
  70% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.08);
  }
  100% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
}

/* Egg-only pulse (first evolution pre-hatch) */
.mm-evolution__stage.is-pulse .mm-evolution__img--egg {
  animation: egg-pulse 0.8s ease;
}

/* Standard evolution (non-intro): hero sprite pulse
   - match New Game egg pacing, but on the FROM/TO sprites
   - keeps everything perfectly centered because the img already uses translate(-50%, -50%) */
   .mm-evolution:not(.mm-evolution--intro) .mm-evolution__stage.is-pulse .mm-evolution__img--from,
   .mm-evolution:not(.mm-evolution--intro) .mm-evolution__stage.is-pulse .mm-evolution__img--to {
     animation: mmEvolvePulse 0.8s ease;
   }
   

@keyframes egg-pulse {
  0%   { transform: translate(-50%, -50%) scale(1); }
  50%  { transform: translate(-50%, -50%) scale(1.08); }
  100% { transform: translate(-50%, -50%) scale(1); }
}

@keyframes mmEvolvePulse{
  0%{
    transform: translate(-50%, -50%) scale(1);
  }
  45%{
    transform: translate(-50%, -50%) scale(1.08);
  }
  100%{
    transform: translate(-50%, -50%) scale(1);
  }
}

@keyframes mmEvolveFrom{
  0%   {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
    filter: blur(0px) drop-shadow(0 18px 24px rgba(0,0,0,.28));
  }
  35%  {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.04) rotate(-2deg);
  }
  55%  {
    opacity: 0.15;
    transform: translate(-50%, -50%) scale(1.08) rotate(3deg);
    filter: blur(10px) drop-shadow(0 24px 30px rgba(0,0,0,.30));
  }
  70%  {
    opacity: 0;
    transform: translate(-50%, -50%) scale(1.10) rotate(6deg);
    filter: blur(14px) drop-shadow(0 24px 30px rgba(0,0,0,.30));
  }
  100% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(1.14) rotate(10deg);
    filter: blur(16px) drop-shadow(0 24px 30px rgba(0,0,0,.30));
  }
}

@keyframes mmEvolveTo{
  0%   {
    opacity: 0;
    /* start near the old position */
    transform: translate(-50%, -52%) scale(.92);
    filter: blur(12px) drop-shadow(0 18px 24px rgba(0,0,0,.28));
  }
  40%  {
    opacity: .55;
    transform: translate(-50%, -56%) scale(1.02);
    filter: blur(6px) drop-shadow(0 18px 24px rgba(0,0,0,.28));
  }
  70%  {
    opacity: 1;
    /* final resting position a bit higher than the old sprite */
    transform: translate(-50%, -58%) scale(1.06);
    filter: blur(0px) drop-shadow(0 18px 24px rgba(0,0,0,.28));
  }
  100% {
    opacity: 1;
    transform: translate(-50%, -58%) scale(1);
    filter: blur(0px) drop-shadow(0 18px 24px rgba(0,0,0,.28));
  }
}

/* =========================================
   Evolution: Hero → Monster focus switch
   (reuse home-hero style, just scoped here)
========================================= */

@keyframes evoFocusIn {
  /* Same "pop in" feel as home hero:
     starts slightly low & small, pops up, then settles */
     0% {
      opacity: 0;
      /* match centered baseline of .mm-evolution__img--from */
      transform: translate(-50%, -50%) scale(0.96);
    }
  65% {
    opacity: 1;
    transform: translate(-50%, -52%) scale(1.03);
  }
  100% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
}

.mm-evolution--intro .mm-evolution__img--hero.is-focusOut {
  animation: mmHomeHeroOut 620ms var(--spring) both;
  will-change: transform, opacity;
}

/* Standard evolution: evolved hero exits with the same motion as New Game */
.mm-evolution .mm-evolution__img--to.is-focusOut {
  animation: mmHomeHeroOut 620ms var(--spring) both;
  will-change: transform, opacity;
}

.mm-evolution--intro .mm-evolution__img--monster.is-focusOut {
  /* Use the exact same fade-out motion as Shellfin */
  animation: mmHomeHeroOut 620ms var(--spring) both;
  will-change: transform, opacity;
}

/* Monster (Octomurk) comes IN using the home-style motion */
.mm-evolution--intro .mm-evolution__img--monster.is-focusIn {
  opacity: 1; /* ensure visible as it animates in */
  animation: evoFocusIn 620ms var(--spring) 120ms both; /* slight delay after hero */
}

/* Standard evolution: first sprite springs in like New Game hero */
.mm-evolution .mm-evolution__img--from.is-focusIn {
  opacity: 1;
  animation: evoFocusIn 620ms var(--spring) both;
  will-change: transform, opacity;
}



/* ============================
   ENERGY RING – only on morph
   ============================ */

/* Hide ring for standard (non-intro) evolutions to avoid stray circle */
.mm-evolution:not(.mm-evolution--intro) .mm-evolution__ring {
  display: none;
}


/* Hard kill ring during pulses */
.mm-evolution__stage.is-pulse .mm-evolution__ring{
  animation: none !important;
  opacity: 0 !important;
}

/* 🚫 No rings during pulses (keeps the “build” phase clean) */
.mm-evolution.is-pulse .mm-evolution__ring,
.mm-evolution--intro.is-egg-in .mm-evolution__ring {
  animation: none;
  opacity: 0;
}

/* 🔥 Kill egg immediately on hatch (no ghosting behind hero) */
.mm-evolution--intro.is-hatch .mm-evolution__img--egg{
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

/* ✅ Ring only on the actual evolution moment */
.mm-evolution.is-morph .mm-evolution__ring{
  animation: mmEvolveRing calc(var(--evolve-ms, 1650ms) * .9) var(--spring) 40ms both;
}

/* First evolution (egg → Shellfin): ring on hatch too */
.mm-evolution--intro.is-hatch .mm-evolution__ring{
  animation: mmEvolveRing 900ms var(--spring) 0ms both;
}

/* Slightly beefier, more “pro” feeling ring */
@keyframes mmEvolveRing{
  0%   { opacity: 0; transform: scale(.72) rotate(-14deg); }
  18%  { opacity: 1; transform: scale(.86) rotate(-4deg); }
  70%  { opacity: 1; transform: scale(1.08) rotate(10deg); }
  100% { opacity: 0; transform: scale(1.26) rotate(18deg); }
}

/* ============================
   EXTRA JUICE – flash + wobble
   ============================ */

/* Soft screen flash behind the stage on evolution */
.mm-evolution.is-morph::before,
.mm-evolution--intro.is-hatch::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(circle at 50% 50%, rgba(255,255,255,.85), rgba(255,255,255,0) 60%);
  opacity: 0;
  animation: mmEvolveFlash 420ms ease-out 0ms both;
}

@keyframes mmEvolveFlash {
  0%   { opacity: 0; }
  10%  { opacity: 1; }
  55%  { opacity: .35; }
  100% { opacity: 0; }
}

/* Stage wobble so it feels like a shockwave */
.mm-evolution.is-morph .mm-evolution__stage,
.mm-evolution--intro.is-hatch .mm-evolution__stage {
  animation: mmEvolveStage 620ms var(--spring) 40ms both;
}

@keyframes mmEvolveStage {
  0%   { transform: scale(1); }
  25%  { transform: scale(1.04); }  /* no translateY */
  55%  { transform: scale(.98); }   /* no translateY */
  100% { transform: scale(1); }
}


/* ================================
   Home â†’ Evolution handoff
   Fade out EVERYTHING except background
================================ */
.mm-homeIntro.is-evoFadeOut{
  opacity: 0;
  transform: translate3d(0, 8px, 0) scale(.99);
  transition: opacity 720ms ease-out, transform 720ms ease-out;
  pointer-events: none;
}

/* ================================
   Evolution: keep background from BODY (overlay is transparent)
   Then fade in title + sprite
================================ */
.mm-evolution.mm-evolution--transparent{
  background: transparent !important;
  background-image: none !important;
}

/* keep your existing reveal / hide states working */
.mm-evolution.is-reveal .mm-evolution__wrap{
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
}

.mm-evolution.is-hide .mm-evolution__wrap{
  opacity: 0;
  transform: translate3d(0, 10px, 0) scale(.96);
}


/* âœ… No hover lift when disabled */
.button[disabled]:hover{ transform:none; box-shadow:none; }


/* ================================
   Damage Mini Game (Tap-to-Attack)
   Clean + QCARD-aligned
   (Replaces previous mini-game block)
================================ */

/* --- Mini Battle Overlay: blur + centered card --- */
.mm-attackMini {
  position: fixed;
  inset: 0;
  z-index: 80;

  display: flex;
  align-items: center;     /* vertical center */
  justify-content: center; /* horizontal center */

  background: rgba(0, 18, 80, 0.45);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);

  opacity: 0;
  transform: scale(0.96) translateZ(0);
  transition:
    opacity 220ms var(--butter),
    transform 260ms var(--spring);

  pointer-events: none;
}

/* MINI GAME progress bar: fixed width + centered */
.mm-attackMini .mm-progress{
  width: 300px;
  margin: 0 auto;
}

.mm-attackMini__title{
  font-size: 32px;
  font-weight: 900;
  letter-spacing: 0.6px;
  line-height: 1;
  text-align: center;
  color: var(--ink);
  padding-top: 16px;
}

.mm-attackMini__sub {
  font-size: 16px;
  color: rgb(0,0,0,.50);
}

.mm-attackMini__header {
  display: flex;
  flex-direction: column;  /* Stack items vertically */
  align-items: center;     /* Horizontal center (in column mode) */
  justify-content: center; /* Vertical center (in column mode) */
  gap: 8px;
  width: 100%;
  margin-bottom: 16px;
}

.mm-attackMini.is-in {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
}

.mm-attackMini.is-out {
  opacity: 0;
  transform: scale(.98);
}

/* Card wrapper stays nice and tight in the center */
.mm-attackMini__wrap {
  display: flex;
  align-items: center;
  justify-content: center;
}

.mm-attackMini__card {
  width: 400px;          /* exact width */
  max-width: calc(100vw - 32px); /* safe on small phones */
  margin: 0;
  box-shadow: var(--shadow2);
}

/* Enemy sprite lives above the spinner and gets its own ground shadow */
.mm-attackMini__enemyWrap {
  width: 300px;
  height: 300px;
  margin: 10px auto 0;
  position: relative;
  display: grid;
  place-items: center;
}

.mm-attackMini__enemy {
  width: 300px;
  height: 300px;
  object-fit: contain;
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none;
}

/* --- MINI GAME: countdown bubble (80x80) --- */
/* --- MINI GAME: countdown bubble (80x80) --- */
.mm-attackMini__countdown{
  position: absolute;
  inset: 0;

  display: grid;
  place-items: center;

  /* IMPORTANT: remove the full-overlay gradient */
  background: none !important;

  pointer-events: none;
  z-index: 5;
}

/* The bubble itself (this becomes the gradient circle) */
/* The bubble itself (match attack sprite target) */
.mm-attackMini__countdown span{
  width: 80px;
  height: 80px;
  border-radius: 999px;

  display: grid;
  place-items: center;

  /* ✅ match .mm-attackMini__hitTarget */
  background: #ffffff;
  box-shadow: 0 10px 18px rgba(0,0,0,.24);

  /* number styling for white bg */
  color: var(--ink);
  font-weight: 900;
  font-size: 36px;

  opacity: 1;
  transform: scale(1);
  will-change: transform, box-shadow;
}

/* Triggered between number swaps */
.mm-attackMini__countdown.is-pulse span{
  animation: mm-miniCountBreathe 520ms var(--spring) both;
  box-shadow:
    0 14px 24px rgba(0, 0, 0, 0.32),
    0 0 0 4px rgba(255, 255, 255, 0.9);
}


/* Gentle grow + settle (no vanish) */
@keyframes mm-miniCountBreathe{
  0%   { transform: scale(1);   }
  45%  { transform: scale(1.12); }
  100% { transform: scale(1);   }
}


/* Slightly smaller shadow variant for mini-card */
.mm-groundShadow--mini {
  position: absolute;
  bottom: 14px;
  left: 50%;
  width: 70%;
  height: 22px;
  transform: translateX(-50%);
  border-radius: 999px;
  background: radial-gradient(
    ellipse at center,
    rgba(0, 0, 0, 0.32) 0%,
    rgba(0, 0, 0, 0.0) 75%
  );
  filter: blur(8px);
  opacity: 0.7;
}

/* Hit target is now positioned inside the enemyWrap */
/* Mini-game attack target: blue circle button */
.mm-attackMini__hitTarget{
  width: 80px;
  height: 80px;

  border-radius: 999px;
  background: #ffffff;

  box-shadow:
    0 10px 18px rgba(0,0,0,.24);

  display: grid;
  place-items: center;

  transform: translateZ(0);
  -webkit-tap-highlight-color: transparent;
}


.mm-attackMini__hitTarget:active{
  transform: scale(.96) translateZ(0);
}

/* The attack sprite inside the circle */
.mm-attackMini__hitImg{
  width: 82%;
  height: 82%;
  object-fit: contain;
  /* Avoid Safari filter flicker on fast-moving absolute elements */
  filter: none;
  transform: translateZ(0);
  pointer-events: none;
  user-select: none;
  display: block;
}


.mm-attackMini__hitTarget.is-live {
  opacity: 1;
  transform: scale(1) translateZ(0);
  pointer-events: auto;
}

.mm-attackMini__hitTarget.is-pop {
  transform: scale(1.08) translateZ(0);
  box-shadow:
    0 14px 24px rgba(0, 0, 0, 0.32),
    0 0 0 4px rgba(255, 255, 255, 0.9);
}


.mm-attackMini__hitDot {
  width: 50%;
  height: 50%;
  border-radius: 999px;
  background: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.8);
}

.mm-mini-hit {
  animation: mm-miniHit 180ms var(--butter);
}

.mm-mini-flash {
  /* slightly longer + smooth ease-out */
  animation: mm-miniFlash 320ms ease-out;
}


@keyframes mm-miniHit {
  0%   { transform: translate3d(0, 0, 0); }
  35%  { transform: translate3d(-6px, 3px, 0); }
  75%  { transform: translate3d(4px, -3px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

@keyframes mm-miniFlash {
  0% {
    filter: brightness(1);
  }
  40% {
    /* stay bright a bit longer */
    filter: brightness(1.4);
  }
  100% {
    /* smooth fade back to normal */
    filter: brightness(1);
  }
}


/* Bursts now live inside the mini-card enemy area */
.mm-miniBurst {
  position: absolute;
  width: 0;
  height: 0;
  pointer-events: none;
}

.mm-miniBurst__p {
  position: absolute;
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: radial-gradient(circle at 30% 30%, #ffffff, var(--accent2));
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.7),
    0 0 10px rgba(108, 255, 184, 0.8);
  opacity: 0;
  transform: translate3d(0, 0, 0);
  animation: mm-miniBurstP 560ms ease-out forwards;
}


@keyframes mm-miniBurstP {
  0% {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
  100% {
    opacity: 0;
    transform: translate3d(
      calc(cos(var(--a)) * var(--d)),
      calc(sin(var(--a)) * var(--d)),
      0
    );
  }
}

/* Hide mini-game UI during loader */
body.is-loader .mm-attackMini{ display: none !important; }

/* Global type weight override */
html, body, button, input, select, textarea{ font-weight: 800; }

@keyframes mm-miniPulse{
  0%, 100%{ transform: scale(1); filter: drop-shadow(0 0 0 rgba(0,0,0,0)); }
  50%{ transform: scale(0.92); }
}

/* ================================
   MINI GAME TIMER (CLEAN, SINGLE SOURCE OF TRUTH)
   Spinner is FIRST in the card and always visible in READY + LIVE
================================ */

.mm-attackMini__timeSlot{
  order: -1;                 /* spinner FIRST in the card */
  position: relative;
  width: 64px;
  height: 64px;
  margin: 4px auto 12px;

  display: flex;
  align-items: center;
  justify-content: center;

  border-radius: 999px;
  overflow: hidden;
}

.mm-attackMini__spinner{
  position: absolute;
  inset: 0;

  display: flex;
  align-items: center;
  justify-content: center;

  opacity: 0;
  transform: scale(.92) translateZ(0);
  transition:
    opacity 220ms var(--butter),
    transform 300ms var(--spring);

  pointer-events: none;
}

/* show spinner in READY + LIVE */
.mm-attackMini.is-ready .mm-attackMini__spinner,
.mm-attackMini.is-live  .mm-attackMini__spinner{
  opacity: 1;
  transform: scale(1) translateZ(0);
}

.mm-spinnerBasic{
  --p: 1;

  --spin-base: #ff0000;                 /* LIVE default */
  --spin-color: var(--spin-base);       /* ✅ no color-mix dependency */
  --spin-track: rgba(255,255,255,.16);

  --ring: 12px;                          /* ✅ half thickness */

  position: relative;
  width: 64px;
  height: 64px;
  border-radius: 999px;

  background: conic-gradient(
    from -90deg,
    /* track first (full circle) */
    var(--spin-track) 0deg,
    var(--spin-track) calc((1 - var(--p)) * 360deg),

    /* remaining time wedge (starts at 12 o'clock) */
    var(--spin-color) calc((1 - var(--p)) * 360deg),
    var(--spin-color) 360deg
  );

  box-shadow:
    0 0 0 1px rgba(255,255,255,.20) inset,
    0 10px 18px rgba(0,0,0,.18);

  overflow: hidden;

  transform: rotate(90deg);          /* ✅ shifts 9 → 12 */
  transform-origin: 50% 50%;
}

/* inner cutout */
.mm-spinnerBasic::after{
  content:"";
  position:absolute;
  inset: var(--ring);
  border-radius: 999px;
  background: #fff;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.75);
}

/* ================================
   Spinner: kill inner-edge hairline
   (subpixel seam during fade-out)
================================ */

/* If your card white ever changes, tie the cutout to it */
:root{
  --mm-card-white: #fff; /* or var(--card) if that's always solid white */
}

/* (Optional) remove the 1px inset rim that can "read" as a blue edge when fading */
.mm-spinnerBasic{
  box-shadow:
    /* 0 0 0 1px rgba(255,255,255,.20) inset,  <-- comment OUT this line */
    0 10px 18px rgba(0,0,0,.18);
}

/* Make the inner cutout overlap the ring slightly to eliminate the seam */
.mm-spinnerBasic::after{
  /* was: inset: var(--ring); */
  inset: calc(var(--ring) - 1px);      /* ✅ overlap ring by 1px */
  background: var(--mm-card-white);    /* ✅ match card exactly */
  box-shadow: none;                    /* ✅ remove inner highlight that can create a seam */
  transform: translateZ(0);            /* ✅ helps some GPUs avoid thin AA lines */
}

/* ready = blue */
.mm-attackMini.is-ready .mm-spinnerBasic{ --spin-base: #0057ff; }

/* READY: gentle grow/shrink pulse */
@keyframes mmSpinnerGrowPulse{
  0%   { transform: rotate(90deg) scale(1); }
  40%  { transform: rotate(90deg) scale(1.4); }
  100% { transform: rotate(90deg) scale(1); }
}

/* READY: solid ring unless JS turns on pulsing */
.mm-attackMini.is-ready .mm-spinnerBasic:not(.is-pulsing){
  animation: none;
}


/* Pulse ONLY when JS adds .is-pulsing (beats the READY rule) */
.mm-attackMini.is-ready .mm-spinnerBasic.is-pulsing{
  animation: mmSpinnerGrowPulse 1000ms var(--spring) 3;
}


/* READY ring overlay should NOT auto pulse */
.mm-attackMini.is-ready .mm-spinnerBasic::before{
  animation: none !important;
  opacity: 0;
}

/* Ring overlay pulses only when .is-pulsing */
.mm-spinnerBasic.is-pulsing::before{
  animation: mmReadyRingPulse 1000ms var(--spring) 3;
}

/* Ensure LIVE has no size pulse */
.mm-attackMini.is-live .mm-spinnerBasic{
  animation: none !important;
}


/* remove variable-animation pulse (delete your @keyframes mmSpinnerPulse and animation rules) */

/* ================================
   Spinner pulse (20% white overlay)
   - simple + reliable
================================ */

/* uniform white overlay, masked to the ring area */
/* overlay exists but off by default */
/* ================================
   READY pulse (Safari-proof)
   - no masks, no calc() in gradients
================================ */

/* ring overlay */
.mm-spinnerBasic::before{
  content:"";
  position:absolute;
  inset: 0;
  border-radius: 999px;
  pointer-events:none;
  opacity: 0;
  transform: scale(.98);
  z-index: 2; /* above ring background, below inner cutout */

  /* “ring” highlight as an inset border */
  box-shadow: inset 0 0 0 var(--ring) rgba(255,255,255,.64);
}

/* pulse */
@keyframes mmReadyRingPulse{
  0%   { opacity: 0;   transform: scale(.96); }
  40%  { opacity: .9;  transform: scale(1.06); }
  100% { opacity: 0;   transform: scale(.96); }
}

/* LIVE: pulse OFF */
.mm-attackMini.is-live .mm-spinnerBasic::before{
  animation: none !important;
  opacity: 0 !important;
}

/* ================================
   Startup + Auth Screens
================================ */
.mm-authShell{
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;

  /* Use visual viewport on iOS (avoids bottom bar overlap) */
  min-height: 100dvh;

  /* Safe-area padding */
  padding: 16px;
  padding-top: calc(16px + env(safe-area-inset-top));
  padding-bottom: calc(16px + env(safe-area-inset-bottom));
  padding-left: calc(16px + env(safe-area-inset-left));
  padding-right: calc(16px + env(safe-area-inset-right));

  box-sizing: border-box;
  z-index: 20;
}

.mm-authShell--bottom{ align-items: center; }


.mm-authCard{
  width: min(92vw, 420px);
  margin: 0 auto;
  display: flex;
  flex-direction: column;

  /* Center everything */
  align-items: center;
  text-align: center;

  /* Never sit under iOS bars */
  max-height: calc(100dvh - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 48px);
  overflow: auto;
}


.mm-authLogo{
  display: flex;
  justify-content: center;
  margin-bottom: 4px;
}

.mm-authLogo img{
  width: 160px;
  height: 160px;
  object-fit: contain;
}

.mm-authTitle{
  font-size: 36px;
  text-align: center;
  color: var(--white);
  margin-top: 24px;
}

.mm-authBody{
  font-size: 20px;
  text-align: center;
  color: #ffffff64;
  margin-top: 8px;
  line-height: 150%;
}

.mm-authActions{
  display:flex;
  flex-direction: column;
  gap: var(--gap);
  width: 100%;
  margin-top: 48px;
}

.mm-authFieldGroup{
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 4px;
  margin-bottom: 6px;
  align-items: center;
}

.mm-authFieldGroup label{
  width: 100%;
  text-align: center;
  font-size: 13px;
  color: rgba(255,255,255,0.82);
}

/* ===============================
   Auth inputs – staged color logic
   =============================== */

   .mm-authInput {
    appearance:none;
    width:100%;
    border-radius: 12px;
    height:64px;
    border: 2px solid rgba(255, 255, 255, 0.24);
    background: none;
    padding-left: 24px;
    font-size: 20px;
    color: var(--ink);
    outline:none;
  }
  
  /* Placeholder stays soft */
  .mm-authInput::placeholder {
    color: rgba(255, 255, 255, 0.4);
  }
  
  /* On focus: real white */
  .mm-authInput:focus {
    color: #ffffff;
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.35);
    outline: none;
  }
  
  /* Once user has typed (but not focused) */
  .mm-authInput:not(:placeholder-shown) {
    color: #ffffff;
  }
  
  /* iOS Safari fix */
  .mm-authInput:-webkit-autofill {
    -webkit-text-fill-color: #ffffff;
    transition: background-color 9999s ease-out;
  }  

/* Layout wrapper for the secondary (outline) auth button */
.mm-authSecondaryLink{
  margin-top: 6px;
  width: 100%;
}

.mm-authSecondaryLink button{
  width: 100%;
}

/* Auth primary button loading state */
.mm-authPrimaryBtn.is-loading {
  pointer-events: none;
}

/* Smaller spinner for inside buttons */
.mm-spinner--btn {
  width: 24px;
  height: 24px;
  border-width: 3px;
}


/* --- MINI GAME: live countdown title --- */
.mm-attackMini.is-live .mm-attackMini__title{
  font-size: 32px;
  font-weight: 900;
  letter-spacing: .5px;
  padding-top: 16px;
}

/* ================================
   EVOLUTION ENERGY RING
================================ */

.mm-evolution__ring{
  position: absolute;
  inset: 50%;
  width: 220px;
  height: 220px;
  transform: translate(-50%, -50%) scale(0.85);
  border-radius: 50%;
  border: 3px solid rgba(80,180,255,.35);
  filter: blur(0.5px) drop-shadow(0 0 18px rgba(80,180,255,.35));
  opacity: 0;
  pointer-events: none;
  z-index: 0;
}

/* ---------------------------------------------
   Grade Select (First Evolution)
--------------------------------------------- */

.mm-gradeField {
  width: 100%;
}

.mm-gradeSelectWrap {
  position: relative;
  width: 100%;
}

/* Native select reset + styling */
.mm-gradeSelect {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;

  width: 100%;
  height: 64px;

  padding: 0 56px 0 20px; /* space for chevron */
  font-size: 20px;
  font-family: var(--mm-font);
  color: var(--ink);
  text-align: left;

  background-color: #ffffff;

  border-radius: 12px;
  border: 2px solid rgba(0, 0, 0, 0.08);

  outline: none;
  cursor: pointer;

  line-height: 1;
}

/* Placeholder (Select Grade) tone */
.mm-gradeSelect option[value=""] {
  color: rgba(0, 0, 0, 0.45);
}

/* Chevron */
.mm-gradeChevron {
  position: absolute;
  right: 20px;
  top: 50%;
  transform: translateY(-50%);

  font-size: 18px;
  color: var(--ink);

  pointer-events: none;
}

/* Focus state — subtle, still kid-friendly */
.mm-gradeSelect:focus {
  border-color: rgba(0, 0, 0, 0.16);
}

/* iOS tap highlight cleanup */
.mm-gradeSelect::-ms-expand {
  display: none;
}

/* ---------- Battle tutorial tip ---------- */

.mm-battleTipOverlay {
  position: fixed;
  inset: 0;
  z-index: 40; /* Above battle stage, below mini-game / system UI */
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity 180ms ease-out;
}

.mm-battleTipOverlay.is-show {
  opacity: 1;
  pointer-events: auto;
}

.mm-battleTipOverlay__backdrop {
  position: absolute;
  pointer-events: none;
  inset: 0;
  background: rgba(0, 0, 0, 0.7);
}

/* Tip card */
.mm-battleTip {
  position: relative;
  max-width: 340px;
  width: calc(100% - 32px);
  padding: 24px;
  border-radius: 1rem;
  background: var(--white);
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.45);
  color: var(--ink);
  transform: translateY(12px);
  opacity: 0;
  transition:
    opacity 200ms ease-out,
    transform 200ms ease-out;
}

/* Slight "pop" when overlay fully shown */
.mm-battleTipOverlay.is-show .mm-battleTip {
  opacity: 1;
  transform: translateY(0);
}

.mm-battleTip__body {
  margin: 0 0 0.5rem;
  font-size: 1.25rem;
  line-height: 1.4;
}

.mm-battleTip__btn {
  width: 100%;
  margin-top: 0.1rem;
}


/* 40x40 circular close button */
.mm-battleTip__close{
  position: absolute;
  top: -18px;
  right: -18px;

  width: 48px;
  height: 48px;
  border-radius: 999px;

  display: flex;
  align-items: center;
  justify-content: center;

  border: none;
  padding: 0;

  font-size: 24px;
  line-height: 1;

  color: #ffffff;
  background: linear-gradient(180deg, var(--button-gradient-start), var(--button-gradient-end));

  cursor: pointer;

  z-index: 5;

  transition:
    transform 160ms var(--spring),
    filter 160ms var(--spring),
    opacity 160ms var(--spring);
}

/* Press feel */
.mm-battleTip__close:active{
  transform: scale(0.92);
  filter: brightness(0.95);
}

/* Optional hover polish (desktop only) */
@media (hover: hover){
  .mm-battleTip__close:hover{
    filter: brightness(1.05);
  }
}

/* Tip overlay that must sit ABOVE the mini-game */
.mm-battleTipOverlay--aboveMini{
  z-index: 120;
}

/* ================================
   Tip Avatar (replaces QUICK TIP pill)
================================ */

.mm-battleTip_avatar{
  width: 64px;
  height: 64px;
  border-radius: 999px;

  object-fit: cover;
  flex: 0 0 auto;

  margin-bottom: 16px;
}


