/* ============================================================
   特效层
   ------------------------------------------------------------
   全部特效都挂在一个 fixed 的 .fxlayer 上，pointer-events:none，
   不参与布局也不挡点击；元素用完即删。
   ============================================================ */

.fxlayer { position: fixed; inset: 0; pointer-events: none; z-index: 70; overflow: hidden; }

/* ---------- 粒子 ---------- */
.fxp {
  position: absolute;
  left: 0; top: 0;
  will-change: transform, opacity;
  animation: fxp-fly var(--d, .9s) cubic-bezier(.15, .7, .3, 1) forwards;
}
@keyframes fxp-fly {
  0%   { opacity: 1; transform: translate(var(--x), var(--y)) scale(.3) rotate(0deg); }
  22%  { opacity: 1; transform: translate(calc(var(--x) + var(--dx) * .45), calc(var(--y) + var(--dy) * .45)) scale(1.15) rotate(90deg); }
  100% { opacity: 0; transform: translate(calc(var(--x) + var(--dx)), calc(var(--y) + var(--dy) + var(--g, 90px))) scale(.55) rotate(var(--rot, 360deg)); }
}
.fxp--dot { border-radius: 50%; }
.fxp--star { font-size: var(--sz, 26px); line-height: 1; }
.fxp--bar { border-radius: 3px; }

/* ---------- 扩散圈 ---------- */
.fxring {
  position: absolute;
  border-radius: 50%;
  border: var(--bw, 6px) solid var(--col, #fff);
  transform: translate(-50%, -50%);
  animation: fxring-go var(--d, .72s) cubic-bezier(.16, 1, .3, 1) forwards;
}
@keyframes fxring-go {
  0%   { opacity: .95; width: 0; height: 0; border-width: var(--bw, 6px); }
  100% { opacity: 0; width: var(--r, 320px); height: var(--r, 320px); border-width: 1px; }
}

/* ---------- 飘字（+160）----------
   白描边 + 厚底影，保证压在花花绿绿的粒子上也读得清 */
.fxtext {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: var(--font-en);
  font-weight: 900;
  font-size: var(--fz, 44px);
  color: var(--col, #fff);
  -webkit-text-stroke: 5px #fff;
  paint-order: stroke fill;
  text-shadow: 0 4px 0 rgba(255, 255, 255, .9), 0 10px 22px rgba(122, 92, 70, .3);
  white-space: nowrap;
  z-index: 2;
  animation: fxtext-up 1.15s cubic-bezier(.16, 1, .3, 1) forwards;
}
@keyframes fxtext-up {
  0%   { opacity: 0; transform: translate(-50%, -40%) scale(.35) rotate(-8deg); }
  16%  { opacity: 1; transform: translate(-50%, -105%) scale(1.32) rotate(4deg); }
  30%  { transform: translate(-50%, -118%) scale(1) rotate(0); }
  70%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -260%) scale(.9); }
}

/* ---------- 边缘光晕 ----------
   用径向渐变只染四周，中间保持透明。
   之前用 inset box-shadow 会把整页都糊上一层色，字母全变色了。 */
.fxglow {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse 82% 82% at 50% 50%, rgba(0,0,0,0) 64%, var(--col, #4ecb71) 100%);
  opacity: 0;
  animation: fxglow-go .68s var(--ease-out) forwards;
}
@keyframes fxglow-go {
  0%   { opacity: 0; transform: scale(1.12); }
  24%  { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.06); }
}

/* ---------- 命中格子上的白闪 ---------- */
.fxflash {
  position: absolute; inset: 0;
  border-radius: inherit;
  background: #fff;
  pointer-events: none;
  animation: fxflash-go .38s var(--ease-out) forwards;
}
@keyframes fxflash-go {
  0%   { opacity: .85; }
  100% { opacity: 0; }
}

/* ---------- 答对：格子本体 ---------- */
@keyframes fx-cheer {
  0%   { transform: scale(1); }
  26%  { transform: scale(1.24) rotate(-4deg); }
  48%  { transform: scale(.94) rotate(3deg); }
  70%  { transform: scale(1.08) rotate(-1deg); }
  100% { transform: scale(1) rotate(0); }
}
.fx-cheer { animation: fx-cheer .62s var(--ease-bounce); }

/* ---------- 答错：软软地压扁再弹回，不用"打叉"那种批评感 ---------- */
@keyframes fx-squish {
  0%   { transform: scale(1, 1); }
  18%  { transform: scale(1.16, .8) translateY(6px); }
  38%  { transform: scale(.92, 1.1) translateY(-4px); }
  58%  { transform: scale(1.06, .95) translateY(2px); }
  78%  { transform: scale(.98, 1.02); }
  100% { transform: scale(1, 1); }
}
.fx-squish { animation: fx-squish .52s var(--ease-out); }

/* ---------- 连击火条 ---------- */
.fxcombo {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: var(--font-en); font-weight: 900; font-size: 64px;
  color: #fff;
  padding: 6px 26px; border-radius: 999px;
  background: linear-gradient(100deg, #ffc93c, #ff6b9d, #a78bfa);
  box-shadow: 0 8px 0 rgba(0,0,0,.12), 0 18px 40px rgba(232,74,128,.4);
  animation: fxcombo-go 1.1s cubic-bezier(.16, 1, .3, 1) forwards;
}
@keyframes fxcombo-go {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.3) rotate(-14deg); }
  20%  { opacity: 1; transform: translate(-50%, -50%) scale(1.16) rotate(5deg); }
  36%  { transform: translate(-50%, -50%) scale(1) rotate(-2deg); }
  74%  { opacity: 1; transform: translate(-50%, -62%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -86%) scale(.86); }
}

/* ---------- 小窗字母命中时的高光扫过 ---------- */
.fxsweep {
  position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(255,255,255,.85) 50%, transparent 70%);
  animation: fxsweep-go .8s var(--ease-out) forwards;
}
@keyframes fxsweep-go {
  0%   { transform: translateX(-120%); }
  100% { transform: translateX(120%); }
}

/* ---------- 画出来的星星 ----------
   之前粒子用的是 emoji ⭐，在不同系统上长得完全不一样，而且一眼就是随手拼的。
   改成 clip-path 切出来的五角星，和整站是一套语言。 */
.fxp--star2 {
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
