/* Linh vật + hiệu ứng (js/mascot.js, js/fx.js).
   Bản xem thử: dev/preview/fx-lab.html. */

/* ---------- linh vật ----------
   Đứng trên mép trên thanh nhập, góc trái (bong bóng của mình căn phải).
   .mascot là ô cắt: hop trượt xuống 100% là linh vật chui mất sau thanh nhập.
   Sprite lưới (cột × hàng khung 48px) chạy bằng HAI lớp transform: .sy bước
   theo hàng, .sx bước theo cột — GPU lo, không vẽ lại mỗi khung.
   File gốc quay mặt sang trái → lật cho quay phải. */
.mascot{
  position:absolute; left:var(--spacing-16); bottom:100%;
  width:48px; height:54px; overflow:hidden; z-index:1;
  pointer-events:none; user-select:none;
}
.mascot__hop{position:absolute; inset:0; transform:translateY(100%)}
.mascot__sprite{
  position:absolute; left:0; bottom:2px; width:48px; height:48px; overflow:hidden;
  transform:scaleX(-1); transform-origin:50% 100%;
}
.mascot__sprite .sy{
  position:absolute; left:0; top:0;
  width:calc(48px * var(--cols, 1)); height:calc(48px * var(--rows, 1));
  animation:mascot-sy var(--T, 1s) steps(var(--rows, 1)) infinite; will-change:transform;
}
.mascot__sprite .sx{
  width:100%; height:100%; background:var(--img) 0 0 / 100% 100% no-repeat;
  animation:mascot-sx calc(var(--T, 1s) / var(--rows, 1)) steps(var(--cols, 1)) infinite; will-change:transform;
}
@keyframes mascot-sy{ to{ transform:translateY(-100%) } }
@keyframes mascot-sx{ to{ transform:translateX(-100%) } }
/* đang lặn / chưa có ảnh: dừng hẳn Idle cho đỡ tốn pin */
.mascot.asleep .sy, .mascot.asleep .sx{animation-play-state:paused}
@media (prefers-reduced-motion:reduce){ .mascot__sprite .sy, .mascot__sprite .sx{animation:none} }
/* bàn phím mở: khung tin nhắn đã hẹp, linh vật ẩn để không che khoản chi
   (kb-open do keyboardFit ở startup.js bật/tắt) */
.app.kb-open .mascot{display:none}

/* bong bóng vừa ghi đang chờ vật thể bay tới: giữ chỗ, chưa hiện */
.expense-bubble.fx-wait{visibility:hidden}

/* ---------- hiệu ứng (nằm trong lớp #coins) ---------- */
.fx-px, .fx-obj, .fx-leafp{position:absolute; left:0; top:0; pointer-events:none; will-change:transform}
.fx-obj{width:24px; height:24px; background:center / contain no-repeat}   /* vật thể bay: 24px */
.fx-spark{background:transparent}
.fx-glow{position:absolute; left:0; top:0; width:90px; height:90px; margin:-45px 0 0 -45px; border-radius:50%; pointer-events:none}
.fx-ring{position:absolute; left:0; top:0; width:36px; height:36px; margin:-18px 0 0 -18px; border-radius:50%; border:3px solid; pointer-events:none}
/* lớp phủ bên trong bong bóng (bong bóng đã position:relative + isolation ở motion.css) */
.fx-shine, .fx-frost, .fx-clean{position:absolute; inset:-1px; border-radius:inherit; pointer-events:none}
.fx-shine, .fx-frost{z-index:1}
.fx-clean{z-index:2; overflow:hidden}
.fx-clean i{position:absolute; inset:0; transform:translateX(-100%); background:linear-gradient(100deg, transparent 25%, rgb(255 255 255 / .85) 50%, transparent 75%)}
/* quầng sáng quanh bong bóng: box-shadow vẽ MỘT lần, chỉ animate opacity */
.fx-halo{position:absolute; inset:-1px; border-radius:inherit; z-index:-1; pointer-events:none; opacity:0}
/* băng */
.fx-frost{
  overflow:hidden;
  background:linear-gradient(160deg, rgb(242 250 255 / .55), rgb(178 218 255 / .42));
  box-shadow:inset 0 0 0 2px rgb(255 255 255 / .95), inset 0 0 14px rgb(110 180 255 / .55);
}
.fx-frost__band{position:absolute; inset:0; transform:translateX(-100%); background:linear-gradient(105deg, transparent 30%, rgb(255 255 255 / .9) 50%, transparent 70%)}
.fx-pix{position:absolute; width:3px; height:3px; z-index:2; pointer-events:none}
.fx-cracks{position:absolute; inset:-1px; z-index:3; overflow:visible; pointer-events:none}
.fx-cracks path{fill:none; stroke:#fff; stroke-width:1.5; stroke-linecap:square; filter:drop-shadow(0 0 1px rgb(80 160 255 / .9))}
/* vết nứt, đường chỉ vẽ bằng SVG */
.fx-thread-line{position:absolute; z-index:3; overflow:visible; pointer-events:none}
.fx-thread-line path{fill:none; stroke-linecap:round; stroke-linejoin:round}
/* lửa: lớp vẽ vết cháy theo ô, đúng bằng khung viền bong bóng */
.fx-burn-canvas{position:absolute; left:-1px; top:-1px; z-index:1; pointer-events:none; image-rendering:pixelated}
