/* ---------------------------------------------------------------
   Pohyb ve scéně — částice, dech, mrkání a loutky.

   Načítá to kniha i administrace, aby náhled v editoru ukazoval
   přesně tentýž pohyb, jaký pak bude v knize. Kdyby to byly dva
   soubory, dřív nebo později se rozejdou.
--------------------------------------------------------------- */

/* ---------------- pohyb ve scéně (mlha, listí, prach) ----------------
   Vrstva leží uvnitř rámu s ilustrací, takže se ořezává s ní a při
   změně velikosti okna se drží. Částice staví js/book.js, tady jsou
   jen jejich dráhy. Proměnné: --x/--y výchozí pozice, --d délka cyklu,
   --t (záporné) zpoždění, --s velikost.                                */

.fx {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 4;
}

/* mlha — pruhy, které se pomalu táhnou napříč scénou */
.fx-fog {
  position: absolute;
  top: var(--y);
  left: 0;
  width: 62%;
  height: 24%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, .55), rgba(255, 255, 255, 0));
  filter: blur(9px);
  opacity: 0;
  animation: fx-drift var(--d) linear var(--t) infinite;
}

@keyframes fx-drift {
  0%   { transform: translate(-75%, 0) scale(var(--s)); opacity: 0; }
  18%  { opacity: .15; }
  82%  { opacity: .15; }
  100% { transform: translate(185%, -7%) scale(var(--s)); opacity: 0; }
}

/* padající listí */
.fx-leaf {
  position: absolute;
  left: var(--x);
  top: -10%;
  width: calc(9px * var(--s));
  height: calc(9px * var(--s));
  border-radius: 50% 0 50% 0;
  background: linear-gradient(135deg, #cf7c2c, #8d4c1b);
  opacity: 0;
  animation: fx-fall var(--d) linear var(--t) infinite;
}

@keyframes fx-fall {
  0%   { top: -10%; transform: translateX(0) rotate(0deg); opacity: 0; }
  7%   { opacity: .85; }
  25%  { transform: translateX(11px) rotate(95deg); }
  50%  { transform: translateX(-9px) rotate(190deg); }
  75%  { transform: translateX(10px) rotate(285deg); }
  93%  { opacity: .85; }
  100% { top: 112%; transform: translateX(0) rotate(380deg); opacity: 0; }
}

/* sluneční paprsky — jen se prolínají, nikam nejdou */
.fx-ray {
  position: absolute;
  left: var(--x);
  top: -25%;
  width: calc(34px * var(--s));
  height: 155%;
  background: linear-gradient(to bottom, rgba(255, 241, 205, .45), rgba(255, 241, 205, 0));
  transform: rotate(11deg);
  filter: blur(7px);
  mix-blend-mode: screen;
  animation: fx-shimmer var(--d) ease-in-out var(--t) infinite alternate;
}

@keyframes fx-shimmer {
  from { opacity: .22; }
  to   { opacity: .62; }
}

/* prach a pyl stoupající ve světle */
.fx-mote {
  position: absolute;
  left: var(--x);
  top: 105%;
  width: calc(3px * var(--s));
  height: calc(3px * var(--s));
  border-radius: 50%;
  background: rgba(255, 248, 224, .95);
  opacity: 0;
  animation: fx-rise var(--d) linear var(--t) infinite;
}

@keyframes fx-rise {
  0%   { top: 105%; transform: translateX(0); opacity: 0; }
  12%  { opacity: .8; }
  50%  { transform: translateX(13px); }
  88%  { opacity: .55; }
  100% { top: -6%; transform: translateX(-7px); opacity: 0; }
}

/* noční můry poletující kolem */
.fx-moth {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: calc(5px * var(--s));
  height: calc(3px * var(--s));
  border-radius: 50%;
  background: rgba(242, 236, 214, .9);
  box-shadow: 0 0 7px rgba(242, 236, 214, .55);
  animation:
    fx-wander var(--d) ease-in-out var(--t) infinite,
    fx-flutter .9s steps(2, end) infinite;
}

@keyframes fx-wander {
  0%   { transform: translate(0, 0); }
  20%  { transform: translate(27px, -19px); }
  40%  { transform: translate(-15px, -36px); }
  60%  { transform: translate(21px, -54px); }
  80%  { transform: translate(-23px, -26px); }
  100% { transform: translate(0, 0); }
}

@keyframes fx-flutter {
  0%   { opacity: .35; }
  100% { opacity: .95; }
}

/* svit — měsíc za větvemi, okno v noře, cokoli svítí */
.fx-glow {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: calc(120px * var(--s));
  aspect-ratio: 1;
  background: radial-gradient(closest-side, rgba(255, 250, 224, .55), rgba(255, 250, 224, 0));
  mix-blend-mode: screen;
  animation: fx-breathe var(--d) ease-in-out var(--t) infinite alternate;
}

@keyframes fx-breathe {
  from { opacity: .3;  transform: translate(-50%, -50%) scale(.92); }
  to   { opacity: .75; transform: translate(-50%, -50%) scale(1.12); }
}

/* kdo si v systému vypnul animace, dostane knihu v klidu */
@media (prefers-reduced-motion: reduce) {
  .fx { display: none; }
  .hotspot__ring { animation: none; opacity: .5; }
  .flip { transition: none; }
}

/* ---------------- živá zvířata: dech a mrkání ---------------- */

/* druhá kopie ilustrace, vymaskovaná kolem těla; zvětšuje se
   od středu hrudníku, takže se zvíře nadechne a zase vydechne */
.al-breath {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: fill;
  filter: var(--tonovani, );
  z-index: 1;
  pointer-events: none;
  transform-origin: var(--x) var(--y);
  -webkit-mask-image: radial-gradient(ellipse var(--rx) var(--ry) at var(--x) var(--y),
                      #000 42%, rgba(0,0,0,.55) 62%, transparent 84%);
  mask-image: radial-gradient(ellipse var(--rx) var(--ry) at var(--x) var(--y),
              #000 42%, rgba(0,0,0,.55) 62%, transparent 84%);
  animation: al-breath var(--d) ease-in-out infinite alternate;
}

@keyframes al-breath {
  from { transform: scale(1); }
  to   { transform: scale(var(--amp)); }
}

/* víčko — sjede přes oko a hned zase nahoru */
.al-blink {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: var(--w);
  height: var(--h);
  margin: calc(var(--h) / -2) 0 0 calc(var(--w) / -2);
  z-index: 2;
  pointer-events: none;
  border-radius: 50%;
  background: linear-gradient(to bottom, var(--c), color-mix(in srgb, var(--c) 82%, #000));
  filter: var(--tonovani, ) blur(.6px);
  transform: rotate(var(--rot)) scaleY(0);
  transform-origin: 50% 0;
  animation: al-blink var(--d) linear var(--t) infinite;
}

@keyframes al-blink {
  0%   { transform: rotate(var(--rot)) scaleY(0); }
  1.6% { transform: rotate(var(--rot)) scaleY(1); }
  4%   { transform: rotate(var(--rot)) scaleY(1); }
  6%   { transform: rotate(var(--rot)) scaleY(0); }
  100% { transform: rotate(var(--rot)) scaleY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .al-breath, .al-blink { animation: none; }
  .al-blink { display: none; }
}

/* ---------------- loutka: zvíře jako samostatná vrstva ----------------
   Scéna je vykreslená bez zvířete, zvíře leží nad ní jako PNG
   s průhledným pozadím. Jenom tohle umí pohyb celým tělem.          */

.al-puppet {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: var(--w);
  transform: translate(-50%, -50%);
  z-index: 1;
  pointer-events: none;
}

.al-puppet__img {
  display: block;
  width: 100%;
  height: auto;
  transform-origin: var(--pivot);
  filter: var(--tonovani, );
}

.al-puppet__img.has-stin {
  filter: var(--tonovani, ) drop-shadow(3px 4px 4px rgba(40, 28, 10, .38));
}

/* klování — série rychlých úderů a pak zase klid */
.al-klovani { animation: al-klovani var(--d) linear infinite; }

@keyframes al-klovani {
  0%, 56%           { transform: rotate(0deg); }
  58%               { transform: rotate(var(--a)); }
  60%               { transform: rotate(0deg); }
  62%               { transform: rotate(var(--a)); }
  64%               { transform: rotate(0deg); }
  66%               { transform: rotate(var(--a)); }
  68%               { transform: rotate(0deg); }
  70%               { transform: rotate(var(--a)); }
  72%, 100%         { transform: rotate(0deg); }
}

/* kývání — pomalé přenášení váhy, pro zvířata, která zrovna nic nedělají */
.al-houpani { animation: al-houpani var(--d) ease-in-out infinite alternate; }

@keyframes al-houpani {
  from { transform: rotate(calc(var(--a) / -2)); }
  to   { transform: rotate(calc(var(--a) / 2)); }
}

.al-klid { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .al-klovani, .al-houpani { animation: none; }
}

/* sníh */
.fx-snow {
  position: absolute;
  left: var(--x);
  top: -6%;
  width: calc(4px * var(--s));
  height: calc(4px * var(--s));
  border-radius: 50%;
  background: rgba(255, 255, 255, .92);
  box-shadow: 0 0 3px rgba(255, 255, 255, .6);
  opacity: 0;
  animation: fx-snih var(--d) linear var(--t) infinite;
}

@keyframes fx-snih {
  0%   { top: -6%; transform: translateX(0); opacity: 0; }
  8%   { opacity: .9; }
  30%  { transform: translateX(14px); }
  60%  { transform: translateX(-12px); }
  90%  { opacity: .85; }
  100% { top: 106%; transform: translateX(8px); opacity: 0; }
}
