/* Oink! Mahjong — effects layer (js/ui/fx.js): particle canvas, word stamps, screen flash.
   The layer covers the 1600x900 stage at its origin and never takes pointer events. */

.fx-layer {
  position: absolute;
  left: 0;
  top: 0;
  width: 1600px;
  height: 900px;
  pointer-events: none;
  overflow: visible;
}
.fx-layer > * { pointer-events: none; }

.fx-canvas {
  position: absolute;
  left: 0;
  top: 0;
  width: 1600px;
  height: 900px;
  display: block;
  z-index: 2;
}

.fx-flash {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  z-index: 1;
}

/* ---- word stamps: chocolate outline, white rim, glossy colour fill ---- */
.fx-stamp {
  --fx-size: 64px;
  --fx-tilt: -8deg;
  --fx-color: #e5484d;
  --fx-hi: #f29b9e;
  position: absolute;
  width: 0;
  height: 0;
  z-index: 3;
}
.fx-stamp-in {
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  transform: translate(-50%, -50%) rotate(var(--fx-tilt));
  font-family: 'Fredoka', 'Nunito', 'Arial Rounded MT Bold', system-ui, sans-serif;
  font-weight: 700;
  font-size: var(--fx-size);
  line-height: 1;
  letter-spacing: .02em;
  white-space: nowrap;
  filter: drop-shadow(0 calc(var(--fx-size) * .09) 0 rgba(74, 44, 35, .28));
}
.fx-stamp-in > span {
  grid-area: 1 / 1;
  padding: .12em .16em;
  text-align: center;
}
.fx-stamp-back {
  color: #4a2c23;
  -webkit-text-stroke: calc(var(--fx-size) * .3) #4a2c23;
}
.fx-stamp-mid {
  color: #fff;
  -webkit-text-stroke: calc(var(--fx-size) * .16) #fff;
}
.fx-stamp-front {
  color: var(--fx-color);
  background-image: linear-gradient(to bottom, var(--fx-hi) 8%, var(--fx-color) 58%, var(--fx-color) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* squash-bounce in, hold, drift up and fade (the element is removed at ~1.25 s) */
.fx-stamp > .fx-stamp-in { animation: fx-stamp-pop 1.15s linear both; transform-origin: 50% 70%; }
@keyframes fx-stamp-pop {
  0%   { transform: translate(-50%, -50%) rotate(var(--fx-tilt)) scale(.2, .2); opacity: 0; animation-timing-function: cubic-bezier(.2, .9, .4, 1); }
  12%  { transform: translate(-50%, -50%) rotate(var(--fx-tilt)) scale(1.32, .74); opacity: 1; animation-timing-function: ease-out; }
  22%  { transform: translate(-50%, -50%) rotate(var(--fx-tilt)) scale(.86, 1.18); animation-timing-function: ease-in-out; }
  31%  { transform: translate(-50%, -50%) rotate(var(--fx-tilt)) scale(1.08, .94); animation-timing-function: ease-in-out; }
  39%  { transform: translate(-50%, -50%) rotate(var(--fx-tilt)) scale(.97, 1.03); animation-timing-function: ease-in-out; }
  46%  { transform: translate(-50%, -50%) rotate(var(--fx-tilt)) scale(1, 1); }
  78%  { transform: translate(-50%, -50%) rotate(var(--fx-tilt)) scale(1, 1); opacity: 1; animation-timing-function: ease-in; }
  100% { transform: translate(-50%, calc(-50% - 26px)) rotate(var(--fx-tilt)) scale(1.06, 1.06); opacity: 0; }
}

.fx-stamp.is-calm > .fx-stamp-in, .reduce-motion .fx-stamp > .fx-stamp-in { animation-name: fx-stamp-calm; }
@keyframes fx-stamp-calm {
  0%   { opacity: 0; }
  15%  { opacity: 1; }
  78%  { opacity: 1; }
  100% { opacity: 0; }
}

/* effects: lite (js/ui/perf.js): the word stamp keeps its back layer but drops the filter shadow */
.fx-lite .fx-stamp-in { filter: none; }
