/* ==========================================================================
   epozvanka.sk — VSTUPNÁ ANIMÁCIA „VÝSTREL A DOPAD"

   Celé CSS tohto modulu žije pod `.vs[data-vstup="dopad"]`. Nikdy na :root —
   inak by si štyri animácie navzájom prepisovali paletu a piata by rozbila
   tie predošlé.

   Farby prídu z motora ako --vs-* na .vs. Záložné hodnoty tu zámerne NIE SÚ:
   keď paleta chýba, motor vrstvu vôbec nepostaví. Nikde nie je miešanie
   farieb funkciou zo CSS Color 5 — Chrome pod 111 by zahodil celú
   deklaráciu. Animuje sa výhradne transform a opacity.

   FÁZY VLASTNÍ MOTOR: data-faza="pokoj" → "hraj" → "koniec" na .vs.
   Preto sú akčné animácie viazané na `:not([data-faza="pokoj"])`, nie na
   [data-faza="hraj"]: pri prepnutí do „koniec" by inak animácie zmizli aj
   s výplňou `both` a hotová scéna by sa v tej istej snímke rozpadla.

   ČO TRVÁ DLHŠIE AKO 0,5 s A PREČO
   Limit platí na ÚDER, na jeden súvislý pohyb. Rig obálky (1,5 s) aj rig
   karty (1,33 s) sú dlhšie, lebo majú vnútri DRŽANIE — deväť snímok úplného
   pokoja, kým karta letí. Rozdeliť ich na dve animácie sa nedá: obe by
   hýbali tým istým transformom a druhá by prvú prepísala spätnou výplňou.
   ========================================================================== */

/* ── javisko ──────────────────────────────────────────────────────────
   Pevný pomer strán. Bez neho by sa všetky percentá v dráhe karty menili
   s výškou okna a partitúra by na každom telefóne sedela inak.
   Šírka je zastropovaná aj výškou okna, nech sa rám vojde aj na telefón
   na šírku; 20 px rezervy drží posunutý rám vnútri vrstvy. */
.vs[data-vstup="dopad"] .dp {
  position: relative;
  width: min(calc(var(--vs-sirka) - 20px), calc(var(--vs-vyska, 100vh) * 0.58));
  aspect-ratio: 5 / 7;
  overflow: hidden;
  border-radius: 10px;
  border: 5px solid var(--vs-ink);
  /* STATICKÝ, nulové rozostrenie, nikdy sa neanimuje. */
  box-shadow: 10px 10px 0 var(--vs-ink);
  background: var(--vs-bg);
}

.vs[data-vstup="dopad"] .dp__otras { position: absolute; inset: 0; }
.vs[data-vstup="dopad"] .dp__svg { display: block; width: 100%; height: 100%; }

/* ── pozadie ──────────────────────────────────────────────────────────
   Lúče sú jediná vec na scéne, ktorá sa točí plynule — je to pozadie, nie
   úder. Otočenie je presne o rozostup dvoch lúčov, takže slučka nemá šev. */
.vs[data-vstup="dopad"] .dp__pozadie { position: absolute; inset: -6%; pointer-events: none; }
.vs[data-vstup="dopad"] .dp__luce {
  position: absolute; inset: 0;
  animation: dp-luce 6s linear infinite;
}
@keyframes dp-luce { to { transform: rotate(45deg); } }
.vs[data-vstup="dopad"] .dp__disk { position: absolute; left: 12%; top: 22%; width: 76%; height: 54%; }

/* ── obálka ───────────────────────────────────────────────────────────
   Vrstvenie zodpovedá skutočnej anatómii obálky:
   zadok → (KARTA) → predné vrecko → statická zavretá chlopňa → pečať.
   Karta je medzi zadkom a vreckom, takže na začiatku ju vrecko schová bez
   jediného triku s viditeľnosťou. */
.vs[data-vstup="dopad"] .dp__ob { position: absolute; left: 12%; top: 62%; width: 76%; height: 33%; }
.vs[data-vstup="dopad"] .dp__ob--zad { z-index: 2; }
.vs[data-vstup="dopad"] .dp__ob--pred { z-index: 4; }

/* Pred ťuknutím sa obálka jemne hompáľa. Je to dych scény, nie úder —
   preto plynulo. Obrazovka nesmie nikdy stáť. */
.vs[data-vstup="dopad"] .dp__idle {
  position: absolute; inset: 0;
  animation: dp-hupka calc(16 * var(--f1)) ease-in-out infinite;
}
@keyframes dp-hupka {
  0%   { transform: translateY(0); }
  25%  { transform: translateY(-3px); }
  50%  { transform: translateY(0); }
  75%  { transform: translateY(2px); }
  100% { transform: translateY(0); }
}
.vs[data-vstup="dopad"] .dp__akcia {
  position: absolute; inset: 0;
  transform-origin: 50% 100%;
  perspective: 900px;
}

.vs[data-vstup="dopad"] .dp__zad,
.vs[data-vstup="dopad"] .dp__pred,
.vs[data-vstup="dopad"] .dp__chlopna,
.vs[data-vstup="dopad"] .dp__krytie { position: absolute; left: 0; width: 100%; }
.vs[data-vstup="dopad"] .dp__zad { top: 0; height: 100%; }
.vs[data-vstup="dopad"] .dp__chlopna {
  top: 0; height: 57.4%; z-index: 2;
  transform-origin: 50% 0%;
  transform-style: preserve-3d;
}
.vs[data-vstup="dopad"] .dp__chl-lic,
.vs[data-vstup="dopad"] .dp__chl-rub { position: absolute; inset: 0; backface-visibility: hidden; }
.vs[data-vstup="dopad"] .dp__chl-rub { transform: rotateX(180deg); }
.vs[data-vstup="dopad"] .dp__pred { top: 31%; height: 69%; }
.vs[data-vstup="dopad"] .dp__krytie { top: 0; height: 57.4%; z-index: 5; }
.vs[data-vstup="dopad"] .dp__pecat {
  position: absolute; left: 42.5%; top: 42.6%; width: 15%; aspect-ratio: 1; z-index: 6;
}

/* BOIL — tri takmer zhodné kresby vrecka sa striedajú po dvoch snímkach.
   Toto je jediné miesto, kde steps(1) ostáva aj mimo úderu: je to výmena
   KRESBY, nie pohyb, a plynulý prechod medzi dvoma kresbami by bol
   rozmazaná dvojexpozícia. Samostatné vrstvy s will-change, aby išlo
   o výmenu kompozitných vrstiev, nie o prekresľovanie SVG. */
.vs[data-vstup="dopad"] .dp__boil {
  position: absolute; inset: 0;
  will-change: opacity;
  animation: dp-boil calc(6 * var(--f1)) steps(1) infinite;
}
.vs[data-vstup="dopad"] .dp__boil:nth-child(2) { animation-delay: calc(-2 * var(--f1)); }
.vs[data-vstup="dopad"] .dp__boil:nth-child(3) { animation-delay: calc(-4 * var(--f1)); }
@keyframes dp-boil { 0% { opacity: 1; } 33.34% { opacity: 0; } 100% { opacity: 0; } }

/* ── karta ────────────────────────────────────────────────────────────
   Rig má tri vrstvy, každá rieši jednu vec a dá sa ladiť samostatne:
   .dp__k-let  = posun (svetový priestor)
   .dp__k-tvar = squash & stretch (tiež svetový — šmuh musí ísť v smere
                 letu, nie v smere natočenia karty)
   .dp__k-otoc = prevrat okolo vlastnej osi (lokálny priestor)
   Poradie je zámerné: keby bol .dp__k-tvar vnútri .dp__k-otoc, natiahnutie
   by sa točilo spolu s kartou a šmuh by ukazoval do strany. */
.vs[data-vstup="dopad"] .dp__karta {
  position: absolute; left: 16%; top: 35%; width: 68%; height: 46%; z-index: 3;
  pointer-events: none;
}
.vs[data-vstup="dopad"] .dp__k-let,
.vs[data-vstup="dopad"] .dp__k-tvar,
.vs[data-vstup="dopad"] .dp__k-otoc { position: absolute; inset: 0; }
.vs[data-vstup="dopad"] .dp__k-let { transform: translateY(96%); will-change: transform; }
.vs[data-vstup="dopad"] .dp__k-tvar { transform-origin: 50% 100%; }  /* bod dotyku so zemou */

/* Zem zároveň kryje spodok karty, ktorý spod vrecka prečnieva. */
.vs[data-vstup="dopad"] .dp__podlaha {
  position: absolute; left: -4%; right: -4%; top: 92.5%; height: 14%; z-index: 5;
  background: var(--vs-ox3);
  border-top: 5px solid var(--vs-ink);
  pointer-events: none;
}

/* ── mená ─────────────────────────────────────────────────────────────
   Samostatná vrstva NAD kartou aj nad obálkou. Nededí squash papiera,
   takže text ostáva ostrý — je to produkt, za ktorý niekto zaplatil. */
.vs[data-vstup="dopad"] .dp__napis {
  position: absolute; left: 16%; top: 35%; width: 68%; height: 46%; z-index: 7;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.06em;
  padding: 11% 13% 20%;
  pointer-events: none;
}
.vs[data-vstup="dopad"] .dp__napis > * { opacity: 0; will-change: transform, opacity; }
/* max-width + nowrap je to, čo vôbec umožní meranie: pri pretečení je
   element orezaný na vnútro rámca a scrollWidth ho prezradí. */
.vs[data-vstup="dopad"] .dp__meno {
  font-family: "Archivo Black", "Arial Black", Impact, var(--vs-sans);
  font-weight: 900;
  font-size: 34px;
  line-height: 0.94;
  letter-spacing: -0.025em;
  color: var(--vs-ink);
  max-width: 100%;
  white-space: nowrap;
}
.vs[data-vstup="dopad"] .dp__spojka {
  font-family: var(--vs-serif);
  font-style: italic;
  font-size: 16px;
  line-height: 1;
  color: var(--vs-akcent);
  margin: 0.04em 0;
}
.vs[data-vstup="dopad"] .dp__datum {
  margin-top: 0.7em;
  font-family: var(--vs-sans);
  /* 11 px — a je to DÁTUM udalosti, teda údaj, kvôli ktorému hosť pozvánku
     otvára. Spodok je 12 px. */
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border: 3px solid var(--vs-ink);
  box-shadow: 3px 3px 0 var(--vs-ink);   /* statický */
  padding: 0.42em 0.7em 0.34em;
  border-radius: 3px;
  max-width: 100%;
  white-space: nowrap;
  /* farba pozadia aj textu prichádza z JS — musí sa dopočítať tak, aby
     bola čitateľná na sýtej aj bledej farbe motívu */
}
.vs[data-vstup="dopad"] .dp__srdce {
  position: absolute; left: 41%; top: -8.5%; width: 18%; height: 18.5%; z-index: 9;
  pointer-events: none;
}

/* ══════════════════════════════════════════════════════════════════════
   PARTITÚRA — spustí ju motor prepnutím data-faza z „pokoj"

   Kadencia sa mení PO INTERVALOCH cez animation-timing-function vnútri
   keyframu. Percentá sú násobky 100/n, aby snímky sedeli na hodinách na
   milisekundu.
     steps(1)            náraz, prasknutie, otras, výmena kresby
     steps(2, jump-none) let a posun — jedna snímka partitúry na dva
                         medzikroky, teda 24 fps (0,0833 s × 24 ≈ 2)
     ease-out / linear   doznenie po náraze, vis v najvyššom bode
   ══════════════════════════════════════════════════════════════════════ */

/* ── obálka: nápřah, odraz, dlhý hold, náraz ──────────────────────────
   18 snímok = 1,5 s, ale vnútri je 8 snímok úplného pokoja (f5–f13), kým
   karta letí. Držanie je súčasť pohybu — bez neho splynie všetko do kaše. */
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__akcia {
  animation: dp-ob calc(18 * var(--f1)) both;
}
@keyframes dp-ob {
  0%      { transform: scale(1, 1) rotate(0deg);        animation-timing-function: steps(1); }      /* f0 */
  5.556%  { transform: scale(1.14, .84) rotate(-2deg);  animation-timing-function: steps(1); }      /* f1 NÁPŘAH */
  11.11%  { transform: scale(.88, 1.16) rotate(1.5deg); animation-timing-function: steps(1); }      /* f2 ODRAZ */
  16.67%  { transform: scale(1.08, .94) rotate(-1deg);  animation-timing-function: ease-out; }      /* f3 */
  22.22%  { transform: scale(.98, 1.02) rotate(.4deg);  animation-timing-function: ease-out; }      /* f4 */
  27.78%  { transform: scale(1, 1) rotate(0deg);        animation-timing-function: steps(1); }      /* f5 → HOLD */
  77.78%  { transform: scale(1.18, .80) rotate(0deg);   animation-timing-function: steps(1); }      /* f14 TRESK */
  83.33%  { transform: scale(.93, 1.09) rotate(0deg);   animation-timing-function: steps(1); }      /* f15 */
  88.89%  { transform: scale(1.09, .94) rotate(0deg);   animation-timing-function: ease-out; }      /* f16 2. dotyk */
  94.44%  { transform: scale(.98, 1.02) rotate(0deg);   animation-timing-function: ease-out; }      /* f17 */
  100%    { transform: scale(1, 1) rotate(0deg); }                                                  /* f18 */
}

/* ── chlopňa: 0 → -190° za dve snímky, potom dosad ────────────────────
   Vedomý extrém: pri tomto tempe sa otvorenie číta ako ÚDER, nie ako
   otáčanie. Samotný prelet je pohyb, preto ide na 24 fps; prestrel a dosad
   sú doznenie, preto plynulo. */
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__chlopna {
  animation: dp-chlopna calc(4 * var(--f1)) both;
}
@keyframes dp-chlopna {
  0%   { transform: rotateX(0deg);    animation-timing-function: steps(2, jump-none); }
  25%  { transform: rotateX(-108deg); animation-timing-function: steps(2, jump-none); }
  50%  { transform: rotateX(-190deg); animation-timing-function: ease-out; }
  75%  { transform: rotateX(-168deg); animation-timing-function: ease-out; }
  100% { transform: rotateX(-177deg); }
}
/* Výmena kresby — jedna snímka, tvrdo. */
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__krytie {
  animation: dp-zmizni var(--f1) steps(1) both;
}
@keyframes dp-zmizni { 0% { opacity: 1; } 100% { opacity: 0; } }

/* ── pečať odletí ─────────────────────────────────────────────────────
   Celé je to let cez plochu, preto celé na 24 fps. */
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__pecat {
  animation: dp-pecat calc(4 * var(--f1)) both;
}
@keyframes dp-pecat {
  0%   { transform: translate(0, 0) rotate(0deg) scale(1); opacity: 1;
         animation-timing-function: steps(2, jump-none); }
  25%  { transform: translate(-14%, -90%) rotate(-70deg) scale(1.1); opacity: 1;
         animation-timing-function: steps(2, jump-none); }
  50%  { transform: translate(-58%, -230%) rotate(-190deg) scale(.9); opacity: 1;
         animation-timing-function: steps(2, jump-none); }
  75%  { transform: translate(-110%, -330%) rotate(-320deg) scale(.7); opacity: .7;
         animation-timing-function: steps(2, jump-none); }
  100% { transform: translate(-170%, -430%) rotate(-430deg) scale(.5); opacity: 0; }
}

/* Jednosnímkový šmuh po chlopni. */
.vs[data-vstup="dopad"] .dp__snuh {
  position: absolute; left: 0; top: -60%; width: 100%; height: 64%; z-index: 7;
  opacity: 0; pointer-events: none;
}
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__snuh {
  animation: dp-snuh calc(3 * var(--f1)) steps(1) both;
}
@keyframes dp-snuh { 0% { opacity: 0; } 33.34% { opacity: 1; } 66.67% { opacity: 0; } 100% { opacity: 0; } }

/* ── KARTA: posun ─────────────────────────────────────────────────────
   Všetky tri vrstvy rigu majú v tých istých percentách tú istú časovaciu
   funkciu. Keby sa posun kreslil na 24 fps a tvar na 12, rozišli by sa
   a okraj karty by sa chvel. */
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__k-let {
  animation: dp-k-let calc(16 * var(--f1)) calc(2 * var(--f1)) both;
}
@keyframes dp-k-let {
  0%      { transform: translateY(96%);  animation-timing-function: steps(2, jump-none); }  /* f2 v obálke */
  6.25%   { transform: translateY(28%);  animation-timing-function: steps(2, jump-none); }  /* f3 VÝSTREL */
  12.5%   { transform: translateY(-24%); animation-timing-function: steps(2, jump-none); }  /* f4 */
  18.75%  { transform: translateY(-58%); animation-timing-function: steps(2, jump-none); }  /* f5 */
  25%     { transform: translateY(-74%); animation-timing-function: steps(2, jump-none); }  /* f6 */
  31.25%  { transform: translateY(-83%); animation-timing-function: steps(2, jump-none); }  /* f7 prestrel apexu */
  37.5%   { transform: translateY(-80%); animation-timing-function: linear; }               /* f8 → VIS */
  56.25%  { transform: translateY(-77%); animation-timing-function: steps(2, jump-none); }  /* f11 začína padať */
  62.5%   { transform: translateY(-63%); animation-timing-function: steps(2, jump-none); }  /* f12 */
  68.75%  { transform: translateY(-33%); animation-timing-function: steps(2, jump-none); }  /* f13 */
  75%     { transform: translateY(0%);   animation-timing-function: steps(1); }             /* f14 TRESK */
  81.25%  { transform: translateY(-18%); animation-timing-function: steps(1); }             /* f15 odraz */
  87.5%   { transform: translateY(0%);   animation-timing-function: ease-out; }             /* f16 2. dotyk */
  93.75%  { transform: translateY(-5%);  animation-timing-function: ease-out; }             /* f17 doznenie */
  100%    { transform: translateY(0%); }                                                    /* f18 */
}

/* ── KARTA: squash & stretch ──────────────────────────────────────────
   Objem sa drží (scaleX × scaleY ≈ 1). f3 a f4 sú ŠMUHY — posun na snímku
   presahuje polovicu šírky karty, takže bez natiahnutia by to strobovalo.
   f14 je náraz a trvá PRESNE jednu snímku. Dve už vyzerajú ako chyba. */
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__k-tvar {
  animation: dp-k-tvar calc(16 * var(--f1)) calc(2 * var(--f1)) both;
}
@keyframes dp-k-tvar {
  0%      { transform: scale(1.22, .74); animation-timing-function: steps(2, jump-none); }  /* f2 stlačená v obálke */
  6.25%   { transform: scale(.48, 1.95); animation-timing-function: steps(2, jump-none); }  /* f3 ŠMUH */
  12.5%   { transform: scale(.62, 1.62); animation-timing-function: steps(2, jump-none); }  /* f4 ŠMUH */
  18.75%  { transform: scale(.84, 1.20); animation-timing-function: steps(2, jump-none); }  /* f5 */
  25%     { transform: scale(1.06, .94); animation-timing-function: steps(2, jump-none); }  /* f6 */
  31.25%  { transform: scale(.97, 1.03); animation-timing-function: steps(2, jump-none); }  /* f7 */
  37.5%   { transform: scale(1, 1);      animation-timing-function: linear; }               /* f8 */
  50%     { transform: scale(1.02, .98); animation-timing-function: linear; }               /* f10 mikroživot vo vise */
  56.25%  { transform: scale(.99, 1.01); animation-timing-function: steps(2, jump-none); }  /* f11 */
  62.5%   { transform: scale(.93, 1.09); animation-timing-function: steps(2, jump-none); }  /* f12 naťahuje sa do pádu */
  68.75%  { transform: scale(.82, 1.26); animation-timing-function: steps(2, jump-none); }  /* f13 */
  75%     { transform: scale(1.46, .62); animation-timing-function: steps(1); }             /* f14 NÁRAZ */
  81.25%  { transform: scale(.86, 1.18); animation-timing-function: steps(1); }             /* f15 */
  87.5%   { transform: scale(1.18, .88); animation-timing-function: ease-out; }             /* f16 */
  93.75%  { transform: scale(.96, 1.04); animation-timing-function: ease-out; }             /* f17 */
  100%    { transform: scale(1, 1); }                                                       /* f18 */
}

/* ── KARTA: prevrat okolo vlastnej osi ────────────────────────────────── */
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__k-otoc {
  animation: dp-k-otoc calc(16 * var(--f1)) calc(2 * var(--f1)) both;
}
@keyframes dp-k-otoc {
  0%      { transform: rotate(0deg);    animation-timing-function: steps(2, jump-none); }   /* f2 */
  6.25%   { transform: rotate(-105deg); animation-timing-function: steps(2, jump-none); }   /* f3 */
  12.5%   { transform: rotate(-215deg); animation-timing-function: steps(2, jump-none); }   /* f4 */
  18.75%  { transform: rotate(-300deg); animation-timing-function: steps(2, jump-none); }   /* f5 */
  25%     { transform: rotate(-348deg); animation-timing-function: steps(2, jump-none); }   /* f6 */
  31.25%  { transform: rotate(-368deg); animation-timing-function: steps(2, jump-none); }   /* f7 prestrel */
  37.5%   { transform: rotate(-360deg); animation-timing-function: linear; }                /* f8 */
  50%     { transform: rotate(-358deg); animation-timing-function: linear; }                /* f10 chvenie v najvyššom bode */
  56.25%  { transform: rotate(-360deg); animation-timing-function: steps(2, jump-none); }   /* f11 */
  62.5%   { transform: rotate(-364deg); animation-timing-function: steps(2, jump-none); }   /* f12 nakláňa sa do pádu */
  68.75%  { transform: rotate(-370deg); animation-timing-function: steps(2, jump-none); }   /* f13 */
  75%     { transform: rotate(-360deg); animation-timing-function: steps(1); }              /* f14 na náraz je narovnaná */
  81.25%  { transform: rotate(-354deg); animation-timing-function: steps(1); }              /* f15 */
  87.5%   { transform: rotate(-361deg); animation-timing-function: ease-out; }              /* f16 */
  93.75%  { transform: rotate(-359deg); animation-timing-function: ease-out; }              /* f17 */
  100%    { transform: rotate(-360deg); }                                                   /* f18 */
}

/* ── otras scény ──────────────────────────────────────────────────────
   Toto je čistý náraz — celé na steps(1). Plynulý otras nie je otras. */
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__otras {
  animation: dp-otras calc(4 * var(--f1)) steps(1) calc(14 * var(--f1)) both;
}
@keyframes dp-otras {
  0%   { transform: translate(0, 9px) rotate(.7deg); }
  25%  { transform: translate(-7px, -6px) rotate(-.5deg); }
  50%  { transform: translate(5px, 4px) rotate(.35deg); }
  75%  { transform: translate(-2px, -2px) rotate(-.15deg); }
  100% { transform: translate(0, 0) rotate(0deg); }
}

/* ── efekty nárazu ────────────────────────────────────────────────────
   POZOR na fill-mode: `both` by počas oneskorenia vykreslil 0 % keyframe,
   takže hviezda aj pruhy by boli na scéne od ťuknutia. `forwards` necháva
   platiť základné opacity:0 a zapne sa až v snímke 14. */
.vs[data-vstup="dopad"] .dp__efekty { position: absolute; inset: 0; z-index: 6; pointer-events: none; }
.vs[data-vstup="dopad"] .dp__efekty > * { position: absolute; opacity: 0; will-change: transform, opacity; }
/* Rozmery sú explicitné v oboch osiach: .dp__svg má height:100 %, čo by sa
   pri chýbajúcej výške riešilo voči celej scéne a obláčik by skončil inde,
   než kde karta dopadla. */
.vs[data-vstup="dopad"] .dp__hviezda { left: 31%; top: 60%; width: 38%; height: 27.2%; }
/* Obláčiky sedia nízko, pri hrane vrecka — tam, kde karta „dopadla". Vyššie
   by sa v čase, keď dosadá prvé meno, prekryli s menami, a mená sú to, čo si
   zákazník kúpil. */
.vs[data-vstup="dopad"] .dp__prach--a { left: 4%; top: 69%; width: 28%; height: 12%; }
.vs[data-vstup="dopad"] .dp__prach--b { left: 35%; top: 71%; width: 30%; height: 13%; }
.vs[data-vstup="dopad"] .dp__prach--c { left: 66%; top: 69%; width: 27%; height: 11.6%; }
.vs[data-vstup="dopad"] .dp__pruh { top: 75%; height: 1.9%; background: var(--vs-ink); border-radius: 3px; }
.vs[data-vstup="dopad"] .dp__pruh--l { left: 13%; width: 17%; transform-origin: 100% 50%; }
.vs[data-vstup="dopad"] .dp__pruh--p { right: 13%; width: 17%; transform-origin: 0% 50%; }

/* hviezda: 2 snímky, potom je preč. Dlhšie by prekryla papier práve vo
   chvíli, keď naň dosadá prvé meno — a mená sú to, čo si zákazník kúpil. */
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__hviezda {
  animation: dp-hviezda calc(2 * var(--f1)) steps(1) calc(14 * var(--f1)) forwards;
}
@keyframes dp-hviezda {
  0%   { transform: scale(.35) rotate(-10deg); opacity: 1; }
  50%  { transform: scale(1.12) rotate(6deg); opacity: 1; }
  100% { transform: scale(1.45) rotate(11deg); opacity: 0; }
}
/* pruhy: rázová vlna do strán, 3 snímky, tvrdo */
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__pruh {
  animation: dp-pruh calc(3 * var(--f1)) steps(1) calc(14 * var(--f1)) forwards;
}
@keyframes dp-pruh {
  0%      { transform: scaleX(.08); opacity: 1; }
  33.34%  { transform: scaleX(1); opacity: 1; }
  66.67%  { transform: scaleX(1.45); opacity: 0; }
  100%    { transform: scaleX(1.45); opacity: 0; }
}
/* prach: doznievajúci dym, nie úder — preto plynulo. Obláčiky sú posunuté
   o snímku, aby nevyleteli naraz. */
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__prach {
  animation: dp-prach calc(5 * var(--f1)) linear calc(14 * var(--f1)) forwards;
}
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__prach--b { animation-delay: calc(15 * var(--f1)); }
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__prach--c { animation-delay: calc(16 * var(--f1)); }
/* Dym sa rozplynie skôr, než dosadne prvé meno. Papierový obláčik na
   papierovej karte by inak ostal ako škrabanec cez mená. */
@keyframes dp-prach {
  0%   { transform: translate(0, 0) scale(.25); opacity: 1; }
  25%  { transform: translate(-5%, -10%) scale(.72); opacity: .95; }
  50%  { transform: translate(-11%, -17%) scale(1.02); opacity: .7; }
  75%  { transform: translate(-17%, -22%) scale(1.26); opacity: .34; }
  100% { transform: translate(-23%, -26%) scale(1.45); opacity: 0; }
}

/* ── konfety ──────────────────────────────────────────────────────────
   0,75 s je viac než pol sekundy, a je to zámer: konfeta nie je ÚDER, je to
   dobiehajúci odpad po údere. Fyzicky musí doletieť a spadnúť. Zároveň je
   to jediná vec, ktorá sa hýbe počas záverečného pokoja, takže finálny
   záber nie je zamrznutý. Je to LET, takže sa krokuje na 24 fps.
   Nádoba nesmie zdediť opacity:0 z .dp__efekty > * — schovaný je každý
   jednotlivý kúsok, nie celá nádoba. */
.vs[data-vstup="dopad"] .dp__konfety { position: absolute; inset: 0; opacity: 1; }
.vs[data-vstup="dopad"] .dp__konf {
  position: absolute; left: 48%; top: 73%;
  opacity: 0;
  border: 2px solid var(--vs-ink);
  will-change: transform, opacity;
}
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__konf {
  animation: dp-konf calc(9 * var(--f1)) calc(14 * var(--f1)) forwards;
}
@keyframes dp-konf {
  0%   { transform: translate(0, 0) rotate(0deg) scale(.5); opacity: 1;
         animation-timing-function: steps(4, jump-none); }
  22%  { transform: translate(calc(var(--dx) * .40), var(--dy)) rotate(calc(var(--rot) * .3)) scale(1); opacity: 1;
         animation-timing-function: steps(6, jump-none); }
  55%  { transform: translate(calc(var(--dx) * .78), calc(var(--dy) * .45)) rotate(calc(var(--rot) * .65)) scale(1); opacity: 1;
         animation-timing-function: steps(8, jump-none); }
  100% { transform: translate(var(--dx), var(--pad)) rotate(var(--rot)) scale(.85); opacity: 0; }
}

/* ── mená dosadajú ────────────────────────────────────────────────────
   Dve mená, ktoré dosadnú s odstupom, sú nekonečne živšie než dve naraz.
   Pád je pohyb (24 fps), squash a spätný ráz sú úder (steps(1)), usadenie
   je doznenie (plynulo). */
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__napis > * {
  animation: dp-dosad calc(5 * var(--f1)) both;
}
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__meno--a { animation-delay: calc(16 * var(--f1)); }
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__spojka  { animation-delay: calc(17 * var(--f1)); }
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__meno--b { animation-delay: calc(18 * var(--f1)); }
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__srdce   { animation-delay: calc(19 * var(--f1)); }
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__datum   { animation-delay: calc(20 * var(--f1)); }
@keyframes dp-dosad {
  0%   { transform: translateY(-140%) scale(1.05, .92); opacity: 0;
         animation-timing-function: steps(2, jump-none); }
  20%  { transform: translateY(0) scale(.82, 1.22); opacity: 1;
         animation-timing-function: steps(1); }
  40%  { transform: translateY(0) scale(1.30, .72); opacity: 1;
         animation-timing-function: steps(1); }                        /* squash */
  60%  { transform: translateY(-14%) scale(.94, 1.08); opacity: 1;
         animation-timing-function: ease-out; }
  80%  { transform: translateY(0) scale(1.04, .97); opacity: 1;
         animation-timing-function: ease-out; }
  100% { transform: translateY(0) scale(1, 1); opacity: 1; }
}

/* Po dosadnutí srdce jemne tepe — jediná vec okrem konfiet a lúčov, ktorá
   drží finálny záber živý. Tep je dych, nie úder, preto plynulo.
   Pravidlo musí stáť ZA dp-dosad: vo fáze „koniec" platia obe a rozhoduje
   poradie v súbore. */
.vs[data-vstup="dopad"][data-faza="koniec"] .dp__srdce {
  opacity: 1;
  animation: dp-tep calc(12 * var(--f1)) ease-in-out infinite;
}
@keyframes dp-tep {
  0%      { transform: scale(1); }
  8.33%   { transform: scale(1.16, .9); }
  16.67%  { transform: scale(.96, 1.06); }
  25%     { transform: scale(1); }
  100%    { transform: scale(1); }
}

/* ── výzva ────────────────────────────────────────────────────────────
   Obrazovka pred ťuknutím nikdy nestojí. Výzva mizne tvrdým strihom. */
.vs[data-vstup="dopad"] .dp__vyzva {
  position: absolute; left: 0; right: 0; top: 5%; z-index: 9;
  margin: 0;
  text-align: center;
  font-family: var(--vs-sans);
  font-size: clamp(11px, 3.1vw, 14px);
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  /* Farba výzvy sa neberie z dizajnu, ale z čitateľnosti — motor ju
     dopočíta ako čiernu alebo bielu podľa toho, ktorá je na podklade scény
     lepšie vidieť (--vs-vyzva v js/vstup.js). Predtým tu stála farba
     odvodená od dizajnu a v mnohých dizajnoch splynula s podkladom: výzva
     na obrazovke bola, ale hosť ju nevidel. */
  color: var(--vs-vyzva, var(--vs-ink));
  /* Bolo 0.85 natrvalo — nie ako súčasť pulzu, ten mení len posun. Zrážalo
     to tri dizajny pod hranicu 4,5 : 1. Priehľadnosť pri texte, ktorý hosťovi
     hovorí, čo má spraviť, nemá čo robiť. */
  opacity: 1;
  transition: opacity var(--f1) steps(1);
  animation: dp-vyzva calc(12 * var(--f1)) ease-in-out infinite;
}
@keyframes dp-vyzva {
  0%   { transform: translateY(0); }
  25%  { transform: translateY(-4px); }
  50%  { transform: translateY(0); }
  75%  { transform: translateY(2px); }
  100% { transform: translateY(0); }
}
.vs[data-vstup="dopad"]:not([data-faza="pokoj"]) .dp__vyzva { opacity: 0; animation: none; }

/* ── obmedzený pohyb ──────────────────────────────────────────────────
   Nie „rýchlejšia animácia", ale rovno VÝSLEDOK. Kto si toto nastavil,
   nechce sledovať let — chce vidieť mená. Motor takej vrstve vypne všetky
   animácie, takže koncové pózy sa musia dopísať ručne. */
.vs[data-bez-pohybu="ano"][data-vstup="dopad"] .dp__k-let { transform: translateY(0) !important; }
.vs[data-bez-pohybu="ano"][data-vstup="dopad"] .dp__k-tvar,
.vs[data-bez-pohybu="ano"][data-vstup="dopad"] .dp__k-otoc { transform: none !important; }
.vs[data-bez-pohybu="ano"][data-vstup="dopad"] .dp__chlopna { transform: rotateX(-177deg) !important; }
.vs[data-bez-pohybu="ano"][data-vstup="dopad"] .dp__krytie,
.vs[data-bez-pohybu="ano"][data-vstup="dopad"] .dp__pecat,
.vs[data-bez-pohybu="ano"][data-vstup="dopad"] .dp__snuh,
.vs[data-bez-pohybu="ano"][data-vstup="dopad"] .dp__efekty,
.vs[data-bez-pohybu="ano"][data-vstup="dopad"] .dp__vyzva { opacity: 0 !important; }
.vs[data-bez-pohybu="ano"][data-vstup="dopad"] .dp__napis > * { opacity: 1 !important; transform: none !important; }
