/* ============================================================
   Gfx — shared "juice" layer: particles, pop text, shake, glow.
   Pure CSS animations (run even when rAF is throttled).
   ============================================================ */
.gfx-layer { position:fixed; inset:0; pointer-events:none; z-index:120; overflow:hidden; }

.gfx-particle {
  position:fixed; will-change:transform,opacity; pointer-events:none;
  transform:translate(-50%,-50%);
  animation:gfx-fly 900ms cubic-bezier(.15,.7,.25,1) forwards;
}
@keyframes gfx-fly {
  0%   { transform:translate(-50%,-50%) scale(.2) rotate(0deg); opacity:1; }
  15%  { transform:translate(-50%,-50%) scale(1.15) rotate(20deg); opacity:1; }
  100% { transform:translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.8) rotate(var(--r)); opacity:0; }
}

.gfx-poptext {
  position:fixed; transform:translate(-50%,0); pointer-events:none; z-index:121;
  font-family:inherit; font-weight:900; font-size:clamp(26px,7vw,48px);
  color:#fff; -webkit-text-stroke:2.5px rgba(0,0,0,.28); paint-order:stroke fill;
  text-shadow:0 4px 0 rgba(0,0,0,.18);
  animation:gfx-pop 1150ms cubic-bezier(.2,.9,.3,1) forwards;
}
@keyframes gfx-pop {
  0%   { opacity:0; transform:translate(-50%,14px) scale(.3) rotate(-8deg); }
  22%  { opacity:1; transform:translate(-50%,-8px) scale(1.3) rotate(4deg); }
  55%  { transform:translate(-50%,-46px) scale(1) rotate(0deg); }
  100% { opacity:0; transform:translate(-50%,-92px) scale(1); }
}

/* screen shake — apply to a scene container */
.gfx-shaking { animation:gfx-shake .42s ease both; }
@keyframes gfx-shake {
  0%,100% { transform:translate(0,0) }
  15% { transform:translate(var(--sk,7px),-2px) }
  30% { transform:translate(calc(var(--sk,7px)*-1),2px) }
  45% { transform:translate(var(--sk,7px),1px) }
  60% { transform:translate(calc(var(--sk,7px)*-1),-1px) }
  80% { transform:translate(calc(var(--sk,5px)),0) }
}

/* juicy press for any button carrying .gfx-btn */
.gfx-btn { transition:transform .08s cubic-bezier(.2,.9,.3,1.4), filter .1s; }
.gfx-btn:active { transform:scale(.9); filter:brightness(1.08); }

/* drop-in bounce (items landing on a plate etc) */
.gfx-drop { animation:gfx-drop .5s cubic-bezier(.2,1.2,.35,1) both; }
@keyframes gfx-drop {
  0% { transform:translateY(-40px) scale(.5); opacity:0; }
  60% { transform:translateY(4px) scale(1.15); opacity:1; }
  100% { transform:translateY(0) scale(1); opacity:1; }
}

/* soft idle bob + breathing for characters */
.gfx-idle { animation:gfx-idle 2.6s ease-in-out infinite; transform-origin:bottom center; }
@keyframes gfx-idle { 0%,100%{ transform:translateY(0) scaleY(1) } 50%{ transform:translateY(-5px) scaleY(1.02) } }

/* blink (apply to eye elements) */
.gfx-blink { animation:gfx-blink 4.5s infinite; transform-origin:center; }
@keyframes gfx-blink { 0%,94%,100%{ transform:scaleY(1) } 97%{ transform:scaleY(.1) } }

/* happy wobble */
.gfx-happy { animation:gfx-happy .6s ease; }
@keyframes gfx-happy { 0%,100%{transform:rotate(0) scale(1)} 25%{transform:rotate(-7deg) scale(1.12)} 60%{transform:rotate(7deg) scale(1.1)} }

/* glow pulse to draw attention */
.gfx-glow { animation:gfx-glow 1.4s ease-in-out infinite; }
@keyframes gfx-glow { 0%,100%{ filter:drop-shadow(0 0 0 rgba(255,255,255,0)) } 50%{ filter:drop-shadow(0 0 14px rgba(255,255,255,.85)) } }

/* floating (parallax-ish clouds/steam) */
.gfx-float { animation:gfx-float 6s ease-in-out infinite; }
@keyframes gfx-float { 0%,100%{ transform:translateX(0) } 50%{ transform:translateX(14px) } }
