/* ============================================================
   ALIEN IDLE ANIMATIONS
   ============================================================ */
@keyframes alienIdleBreathe {
  0%   { transform: scale(1.000) translateY(0px); }
  30%  { transform: scale(1.010) translateY(-4px); }
  60%  { transform: scale(1.016) translateY(-6px); }
  80%  { transform: scale(1.008) translateY(-3px); }
  100% { transform: scale(1.000) translateY(0px); }
}
@keyframes alienIdleSway {
  0%   { transform: rotate(-1.2deg) translateX(-2px); }
  25%  { transform: rotate(0deg)    translateX(0px); }
  50%  { transform: rotate(1.2deg)  translateX(2px); }
  75%  { transform: rotate(0deg)    translateX(0px); }
  100% { transform: rotate(-1.2deg) translateX(-2px); }
}
@keyframes alienIdleBlink {
  0%, 80%, 100% { opacity: 1; }
  88%           { opacity: 0.82; }
  93%           { opacity: 0.7; }
}
@keyframes alienIdleLook {
  0%   { transform: translateX(0px) rotate(0deg); }
  30%  { transform: translateX(5px) rotate(0.5deg); }
  70%  { transform: translateX(-4px) rotate(-0.5deg); }
  100% { transform: translateX(0px) rotate(0deg); }
}
.alien-btn.alien-idle-breathe { animation: alienIdleBreathe 1.1s cubic-bezier(0.45,0,0.55,1) forwards; }
.alien-btn.alien-idle-sway    { animation: alienIdleSway 1.3s cubic-bezier(0.45,0,0.55,1) forwards; }
.alien-btn.alien-idle-blink   { animation: alienIdleBlink 0.5s ease-in-out forwards; }
.alien-btn.alien-idle-look    { animation: alienIdleLook 0.9s cubic-bezier(0.45,0,0.55,1) forwards; }

/* ============================================================
   CONFETTI POOL ELEMENTS
   ============================================================ */
.confetti-piece {
  position: fixed;
  pointer-events: none;
  z-index: 9100;
  width: 8px; height: 8px;
  border-radius: 2px;
}
@keyframes confettiFall {
  0%   { opacity: 1; transform: translate(0,0) rotate(0deg) scale(1); }
  80%  { opacity: 0.8; }
  100% { opacity: 0; transform: translate(var(--cx,80px), var(--cy,120px)) rotate(var(--cr,540deg)) scale(0.4); }
}

/* ============================================================
   EYE SYSTEM — entry animation
   ============================================================ */
@keyframes eyeEnterAnim {
  0%   { transform: scale(0) rotate(-15deg); opacity: 0; }
  60%  { transform: scale(1.18) rotate(5deg); opacity: 1; }
  80%  { transform: scale(0.92) rotate(-2deg); }
  100% { transform: scale(1) rotate(0deg); opacity: 1; }
}
.eye-entity.eye-enter { animation: eyeEnterAnim 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards; }

/* ============================================================
   UPGRADE ??? REVEAL ANIMATION
   ============================================================ */
@keyframes nameReveal {
  from { opacity: 0; letter-spacing: 4px; filter: blur(4px); }
  to   { opacity: 1; letter-spacing: normal; filter: none; }
}
.upg-card.upg-revealing .upg-name,
.upg-card.upg-revealing .upg-desc {
  animation: nameReveal 0.55s ease-out forwards;
}

/* ============================================================
   TUTORIAL CURSOR
   ============================================================ */
.tutorial-cursor {
  position: fixed;
  z-index: 10002; /* above modal-overlay z-index:9999 so cursor is visible inside galaxy map */
  pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  width: 48px; height: 48px;
  animation: tutBounce 0.8s ease-in-out infinite;
}
.tut-pulse-ring {
  position: absolute;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 2px solid rgba(80,200,255,0.7);
  animation: tutPulse 0.9s ease-out infinite;
  top: 50%; left: 50%;
  transform-origin: center;
  margin-top: -22px; margin-left: -22px;
}
@keyframes tutPulse {
  0%   { transform: scale(0.4); opacity: 0.9; }
  100% { transform: scale(2.2); opacity: 0; }
}
/* ============================================================
   LOCKED CARD — subtle idle presence
   Layers a faint breathing glow on top of whatever opacity/
   grayscale a locked card already uses, so locked content reads
   as "not yet available" rather than dead pixels. Box-shadow only
   — never touches opacity/filter so it composes with any existing
   locked treatment without fighting it.
   ============================================================ */
@keyframes lockedIdleGlow {
  0%, 100% { box-shadow: 0 0 0 rgba(120,180,255,0); }
  50%      { box-shadow: 0 0 14px rgba(120,180,255,0.10); }
}
.locked-idle-fx { animation: lockedIdleGlow 3.6s ease-in-out infinite; }

.tut-hand { font-size: 2rem; position: relative; z-index: 1; }
/* Hint label below the tutorial cursor hand */
.tut-label {
  position: absolute;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-family: var(--font-hd, 'Orbitron', sans-serif);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: #50c8ff;
  text-shadow: 0 0 10px rgba(80,200,255,0.9), 0 0 20px rgba(80,200,255,0.5);
  background: rgba(4,6,28,0.88);
  border: 1px solid rgba(80,200,255,0.35);
  border-radius: 6px;
  padding: 3px 8px;
  pointer-events: none;
  animation: tutLabelPulse 2s ease-in-out infinite;
}
@keyframes tutLabelPulse {
  0%,100% { opacity: 0.85; }
  50%     { opacity: 1; text-shadow: 0 0 14px rgba(80,200,255,1), 0 0 28px rgba(80,200,255,0.6); }
}
@keyframes tutBounce {
  0%,100% { transform: translateY(0); }
  50%     { transform: translateY(-10px); }
}

