/* ==========================================================================
   epozvanka.sk — VSTUP „FOTOGRAFICKÁ OBÁLKA"

   Skutočná obálka cez celú obrazovku: fotografická šablóna papiera
   s razbou, vosková pečať s ŽIVÝM monogramom páru. Po ťuknutí sa pečať
   odlepí, štyri klopy sa v perspektíve roztvoria smerom k divákovi
   a zvnútra sa vyleje teplé svetlo.

   CELÉ CSS ŽIJE POD `.vs[data-vstup="obalka"]` — farby šablóny podá JS
   ako --vso-* na .vso, paletu stránky motor ako --vs-* na .vs.

   POHYB: plynulý, nie krokovaný. Fotografia pri 12 fps vyzerá rozbito —
   toto je zámerná výnimka z motívu „odtlačok". Animuje sa VÝHRADNE
   transform a opacity: žiara pečate aj svetlo zvnútra sú predkreslené
   vrstvy, ktorým sa mení len priehľadnosť (žiadny box-shadow, filter ani
   background v @keyframes).

   3D: perspektíva je na javisku, každá klopa je vlastný preserve-3d
   kontext s pántom (transform-origin) na svojej vonkajšej hrane — pánt
   počíta JS v px, lebo rezy idú z rohov OBRÁZKA, nie javiska. Klopy sa
   otvárajú SMEROM K DIVÁKOVI (kladné z), aby ich vnútro obálky na dne
   nikdy neprekrylo. Rub je predtočený o 180° okolo pántu a zrkadlený
   cez pánt, takže po preklopení sadne presne na líce.
   ========================================================================== */

.vs[data-vstup="obalka"] .vso {
  position: absolute;
  inset: 0;
  font-family: var(--vs-serif);
}

/* Podklad vo farbe papiera cez celú vrstvu — na monitore ostáva okolo
   javiska pás a nesmie mať inú farbu než obálka. */
.vs[data-vstup="obalka"] .vso__pozadie {
  position: absolute;
  inset: 0;
  background: var(--vso-papier);
}

/* ── javisko ─────────────────────────────────────────────────────────
   Na telefóne celá obrazovka; na monitore sa šírka zastaví, aby sa
   z obálky nestal výrez papiera cez tri metre. Výška z --vs-vyska
   (motor ju meria cez visualViewport), nie z vh. */
.vs[data-vstup="obalka"] .vso__javisko {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: min(100vw, calc(var(--vs-vyska, 100vh) * 0.78));
  transform: translateX(-50%);
  overflow: hidden;
  background: var(--vso-papier);
}

/* Perspektívny obal KAŽDEJ klopy zvlášť, ohnisko v jej pánte (px dopĺňa
   JS). S jednou perspektívou v strede javiska klopa otvárajúca sa
   k divákovi rástla smerom od stredu a vyletela z obrazu; s ohniskom
   v pánte rastie cez telo obálky — ako keď ju dvíhaš pred očami. */
.vs[data-vstup="obalka"] .vso__pant {
  position: absolute;
  inset: 0;
  perspective: 1100px;
}

/* Vnútro obálky na dne (z = 0) a svetlo v ňom. Svetlo je predkreslený
   radiálny prechod — v pokoji neviditeľný, pri otváraní sa rozsvieti
   cez opacity. */
.vs[data-vstup="obalka"] .vso__vnutro {
  position: absolute;
  inset: 0;
  background: var(--vso-vnutro);
  transform: translateZ(0);
  /* Kartička vychádza z obálky s miernym náklonom — perspektíva pre ňu. */
  perspective: 1200px;
}
.vs[data-vstup="obalka"] .vso__svetlo {
  position: absolute;
  inset: -20%;
  background: radial-gradient(60% 50% at 50% 50%, var(--vso-svetlo) 0%, rgba(255, 216, 154, 0.55) 30%, rgba(255, 216, 154, 0) 70%);
  opacity: 0;
  will-change: opacity;
}

/* ── kartička vo vnútri ──────────────────────────────────────────────
   Kresba oblúka (obrázok) a na nej živý text. V pokoji je zmenšená na
   0,84, mierne naklonená a schovaná pod klopami; svetlo svieti ZA ňou,
   v páse okolo. Pod obrázkom stojí farba stredu kresby — kým sa nenačíta,
   mená sú na plnej farbe a čitateľné.

   EFEKTY (všetko predkreslené vrstvy, hýbe sa LEN transform a opacity):
     bloom  — rozmazaná kópia kresby (filter je statický), zhasína = doostrenie
     nádych — kresba sa pomaly zmenší z 1,08 na 1 (Ken Burns)
     text   — riadky nabiehajú zdola po jednom
     žiara  — radiálny prechod za menami sa rozsvieti a potom dýcha
     lesk   — svetlý pás prebehne cez riadok mena (overlay)
     častice — lupene padajú / iskry blikajú, v slučke */
.vs[data-vstup="obalka"] .vso__karta {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--vso-karta-stred);
}
.vs[data-vstup="obalka"] .vso__karta-obr,
.vs[data-vstup="obalka"] .vso__karta-bloom {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity calc(4 * var(--f1)) linear;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
}
.vs[data-vstup="obalka"] .vso__karta-obr {
  will-change: opacity;
}
.vs[data-vstup="obalka"] .vso--karta .vso__karta-obr { opacity: 1; }
/* Kým obálka nedorazí, kartička sa NEKRESLÍ. Krémová obálka má 209 kB,
   jej kartička 108 kB — na mobilnej sieti príde kresba skôr a hosť by
   videl otvorené vnútro ešte pred zalepenou obálkou. Odmerané s pozdržanou
   odpoveďou: v 921 ms bola kartička s kresbou aj pečaťou viditeľná, obálka
   dorazila až v 8 371 ms. Trieda `vso--nacitane` sa pridáva aj pri chybe
   obrázka, takže sa nič nezasekne. */
.vs[data-vstup="obalka"] .vso:not(.vso--nacitane) .vso__karta { visibility: hidden; }
/* Rozmazaná kópia: filter sa NIKDY neanimuje, je nastavený raz; mení sa
   len opacity. Zväčšená, aby rozmazaný okraj neukázal podklad. */
.vs[data-vstup="obalka"] .vso__karta-bloom {
  filter: blur(16px) saturate(1.15);
  transform: scale(1.12);
  will-change: opacity;
}
.vs[data-vstup="obalka"] .vso--karta .vso__karta-bloom { opacity: 0.8; }
.vs[data-vstup="obalka"] .vso__karta-ziara {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 120%;
  aspect-ratio: 1 / 0.72;
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, var(--vso-karta-ziara) 0%, var(--vso-karta-ziara) 18%, rgba(255, 255, 255, 0) 72%);
  opacity: 0;
  pointer-events: none;
  will-change: opacity;
}
.vs[data-vstup="obalka"] .vso__castice {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.vs[data-vstup="obalka"] .vso__castica {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: var(--s);
  height: calc(var(--s) * 1.4);
  opacity: 0;
  will-change: transform, opacity;
}
.vs[data-vstup="obalka"] .vso__castice--lupene .vso__castica { top: -8%; }
.vs[data-vstup="obalka"] .vso__castica svg { display: block; width: 100%; height: 100%; overflow: visible; }
.vs[data-vstup="obalka"] .vso__karta-text {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 100%;
  padding: 0 6%;
  box-sizing: border-box;
  transform: translate(-50%, -50%);
  text-align: center;
  color: var(--vso-karta-text2);
}
.vs[data-vstup="obalka"] .vso__karta-text p { margin: 0; }
.vs[data-vstup="obalka"] .vso__karta-kicker {
  font-family: var(--vs-sans);
  font-weight: 600;
  font-size: clamp(10px, 2.8vw, 13px);
  letter-spacing: 0.32em;
  text-transform: uppercase;
  margin-bottom: 0.9em !important;
}
/* Riadok NEOREZÁVA. Kým mal `overflow: hidden` s `line-height: 1,02`,
   bral diakritiku aj doťahy: odmerané na 393 px pri písme 53 px — „Žofia"
   prišla o 20 px mäkčeňa, „Gregor" o 73 px slučky g, „Ágnes" o 96 px.
   Písmo mena má obsahovú výšku 1,094 em, riadok 1,02 → half-leading je
   záporný a orez ~2 px hore aj dole; na iOS s Iowan Old Style ešte viac.
   Je to tá istá mína ako „riadkový rozstup nadpisov" v CLAUDE.md, len na
   menách, ktoré sú samotný produkt. Padding v em sa navyše počítal
   zo 16 px riadka, nie z písma mena — teda 0,64 px namiesto 2 px. */
.vs[data-vstup="obalka"] .vso__karta-riadok {
  position: relative;
  display: flex;
  justify-content: center;
  padding: 0.06em 0;
  line-height: 1.06;
}
/* Riadky textu čakajú schované, kým kartička nevyjde z obálky. */
.vs[data-vstup="obalka"] .vso__karta-text > * {
  opacity: 0;
  transform: translateY(14px);
  will-change: transform, opacity;
}
/* Lesk je dieťa KARTIČKY, nie riadka — mieša sa teda s kresbou, nie
   s prázdnym riadkom. Pás pokrýva stredné pásmo, kde stoja mená. */
.vs[data-vstup="obalka"] .vso__lesk {
  position: absolute;
  top: 30%;
  bottom: 26%;
  left: 0;
  width: 42%;
  background: linear-gradient(100deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.85) 50%, rgba(255, 255, 255, 0) 100%);
  mix-blend-mode: overlay;
  transform: translateX(-140%);
  opacity: 0;
  pointer-events: none;
  will-change: transform, opacity;
}
/* Meno je inline-block BEZ šírky — sadzba meria scrollWidth a blok by
   meral šírku kartičky (rovnaká mína ako pri monograme). Veľkosť písma
   zapisuje JS v px. */
.vs[data-vstup="obalka"] .vso__karta-meno {
  display: inline-block;
  width: auto;
  white-space: nowrap;
  font-family: var(--vs-serif);
  font-weight: 400;
  color: var(--vso-karta-text);
}
/* Jediný dlhý názov sa smie zalomiť — nastaví to JS až vtedy, keď sa ani
   na najmenšom písme nezmestí. `nowrap` v kartičke s `overflow: hidden`
   by ho inak odrezal po oboch stranách. */
.vs[data-vstup="obalka"] .vso__karta-meno--zalom {
  white-space: normal;
  max-width: var(--vso-karta-sirka, 100%);
  line-height: 1.08;
}
/* Riadok nad menami je voľné pole z editora — do šírky čistého stredu
   kresby, inak sa zalomí cez ozdoby po bokoch. */
.vs[data-vstup="obalka"] .vso__karta-kicker,
.vs[data-vstup="obalka"] .vso__karta-datum {
  max-width: var(--vso-karta-sirka, 100%);
  margin-inline: auto;
}
.vs[data-vstup="obalka"] .vso__karta-spojka {
  font-family: var(--vs-serif);
  font-style: italic;
  font-size: clamp(18px, 5.5vw, 26px);
  line-height: 1.2;
}
.vs[data-vstup="obalka"] .vso__karta-datum {
  font-family: var(--vs-serif);
  font-style: italic;
  font-size: clamp(15px, 4.4vw, 20px);
  letter-spacing: 0.04em;
  margin-top: 1em !important;
}

/* ── klopy ───────────────────────────────────────────────────────────
   Každá klopa je celé javisko; trojuholník z nej robí clip-path na líci
   a rube (počíta JS). Kým sa obrázok nenačíta, líce je priehľadné
   a vidno farbu papiera — nikdy prázdna vrstva. */
.vs[data-vstup="obalka"] .vso__klopa {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  will-change: transform;
  /* Klopy ležia tesne NAD vnútrom, aby sa v pokoji nemiešali s jeho
     plochou (z-fighting) — pri z = 0 by prehliadač náhodne kreslil raz
     jedno, raz druhé. */
  transform: translateZ(1px);
}
.vs[data-vstup="obalka"] .vso__lic,
.vs[data-vstup="obalka"] .vso__rub {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.vs[data-vstup="obalka"] .vso__lic {
  opacity: 0;
  transition: opacity calc(4 * var(--f1)) linear;
}
.vs[data-vstup="obalka"] .vso--nacitane .vso__lic { opacity: 1; }
/* Motor dáva .vs img max-width: 100 % — tu ho polohuje JS v px a obrázok
   je zámerne väčší než javisko (cover), takže sa strop musí zrušiť. */
.vs[data-vstup="obalka"] .vso__lic img {
  position: absolute;
  max-width: none;
  display: block;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
}
.vs[data-vstup="obalka"] .vso__rub {
  background: var(--vso-vnutro);
}
/* Rub predtočený o 180° okolo pántu klopy. Os podľa klopy. */
.vs[data-vstup="obalka"] .vso__klopa--horna .vso__rub,
.vs[data-vstup="obalka"] .vso__klopa--dolna .vso__rub { transform: rotateX(180deg); }
.vs[data-vstup="obalka"] .vso__klopa--lava .vso__rub,
.vs[data-vstup="obalka"] .vso__klopa--prava .vso__rub { transform: rotateY(180deg); }

/* ── pečať ───────────────────────────────────────────────────────────
   Stred v px zapisuje JS (bod, kde sa stretávajú záhyby). Vosk je obrázok
   s priehľadným pozadím, monogram živý text. Pečať leží nad klopami. */
.vs[data-vstup="obalka"] .vso__pecat {
  position: absolute;
  width: var(--vso-pecat, 140px);
  height: var(--vso-pecat, 140px);
  margin-left: calc(var(--vso-pecat, 140px) / -2);
  margin-top: calc(var(--vso-pecat, 140px) / -2);
  transform: translateZ(3px);
  transform-style: preserve-3d;
  will-change: transform, opacity;
}
.vs[data-vstup="obalka"] .vso__vosk {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  display: block;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
  /* Vosk sa vrhá na papier — tieň je STATICKÝ (drop-shadow sa neanimuje,
     animuje sa celá pečať transformom, tieň sa vezie s ňou). */
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.28));
}
/* Predkreslená žiara okolo pečate: v pokoji tichá, pri ťuknutí sa
   rozsvieti — cez opacity, nie cez box-shadow. */
.vs[data-vstup="obalka"] .vso__ziara {
  position: absolute;
  inset: -55%;
  border-radius: 50%;
  background: radial-gradient(circle, var(--vso-svetlo) 0%, rgba(255, 216, 154, 0.5) 32%, rgba(255, 216, 154, 0) 68%);
  opacity: 0;
  will-change: opacity;
}
/* Monogram: písmo štýlu v kurzíve, stupeň meria JS (ctx.sadzba). Lícna
   plocha vosku je mierne nad geometrickým stredom — kvapka je dole. */
.vs[data-vstup="obalka"] .vso__mono {
  position: absolute;
  left: 50%;
  top: 46%;
  /* inline-block bez šírky: JS meria scrollWidth textu, nie pečate */
  display: inline-block;
  width: auto;
  transform: translate(-50%, -50%);
  text-align: center;
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--vso-monogram);
  white-space: nowrap;
  line-height: 1;
}

/* ── výzva ───────────────────────────────────────────────────────────
   Vlastná plná pilulka vo farbe papiera: na fotografii sa kontrast textu
   nedá zmerať, na pilulke áno. Farba textu z čitateľnosti (--vs-vyzva),
   nie z dizajnu. */
.vs[data-vstup="obalka"] .vso__vyzva {
  position: absolute;
  left: 50%;
  top: 86%;
  transform: translateX(-50%);
  margin: 0;
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--vso-papier);
  color: var(--vs-vyzva);
  font-family: var(--vs-sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-indent: 0.24em;
  text-transform: uppercase;
  white-space: nowrap;
  z-index: 5;
  will-change: transform, opacity;
}

/* ══════════════════════════════════════════════════════════════════════
   POKOJ — obrazovka nesmie stáť, ale fotografia nesmie ani skákať.
   Pečať ticho dýcha, výzva jemne pulzuje.
   ══════════════════════════════════════════════════════════════════════ */
@keyframes vso-dych {
  0%, 100% { transform: translateZ(3px) scale(1); }
  50%      { transform: translateZ(3px) scale(1.025); }
}
.vs[data-vstup="obalka"][data-faza="pokoj"] .vso__pecat {
  animation: vso-dych 3.6s ease-in-out infinite both;
}
@keyframes vso-vyzva-pulz {
  0%, 100% { transform: translateX(-50%) translateY(0);   opacity: 0.86; }
  50%      { transform: translateX(-50%) translateY(-4px); opacity: 1; }
}
.vs[data-vstup="obalka"][data-faza="pokoj"] .vso__vyzva {
  animation: vso-vyzva-pulz 2.6s ease-in-out infinite both;
}

/* ══════════════════════════════════════════════════════════════════════
   OTVORENIE — partitúra v snímkach (1 snímka = var(--f1) = 83,33 ms)

     f0–f1    výzva zhasne
     f0–f3    žiara pečate sa rozsvieti
     f2–f6    pečať sa odlepí (zdvihne, natočí, zmizne)
     f3–f17   horná klopa (do f12 dvíhanie k divákovi, potom odchod)
     f6–f20   ľavá a pravá klopa
     f9–f23   dolná klopa
     f6–f20   svetlo zvnútra sa rozleje
     f18–f34  doostrenie (rozmazaná kópia zhasne)
     f24–f44  text nabieha po riadkoch (kicker, meno, &, meno, dátum)
     f26–f36  žiara za menami sa rozsvieti, od f36 dýcha v slučke
     f28–∞    častice (lupene / iskry) v slučke
     f38–f48  lesk prebehne cez mená, potom každé 4 s
     potom motor drží kartičku PAUZA ms a odkryje stránku

   Selektor :not([data-faza="pokoj"]) drží partitúru cez „hraj" aj
   „koniec" — inak by sa po dobehnutí hotová scéna rozpadla do pokoja.
   ══════════════════════════════════════════════════════════════════════ */
@keyframes vso-vyzva-prec { to { opacity: 0; transform: translateX(-50%) translateY(8px); } }
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__vyzva {
  animation: vso-vyzva-prec var(--f1) linear both;
}

@keyframes vso-ziara-in {
  0%   { opacity: 0; }
  60%  { opacity: 1; }
  100% { opacity: 0.85; }
}
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__ziara {
  animation: vso-ziara-in calc(3 * var(--f1)) ease-out both;
}

/* Pečať sa ODLEPÍ: krátke prisadnutie (nápřah), potom zdvih k divákovi,
   mierne natočenie a rozplynutie. Vzdialenosť v Z nesie perspektíva. */
@keyframes vso-pecat-prec {
  0%   { transform: translateZ(3px)  scale(1)    rotate(0deg);  opacity: 1; animation-timing-function: cubic-bezier(.4, 0, .6, 1); }
  18%  { transform: translateZ(0px)  scale(0.96) rotate(-2deg); opacity: 1; animation-timing-function: cubic-bezier(.15, .7, .3, 1); }
  /* odskok: pečať sa odlepí a letí k divákovi, PLNÁ až do dvoch tretín —
     rozplynúť sa smie až keď je už mimo obálky, inak vyzerá ako duch */
  66%  { transform: translateZ(180px) scale(1.12) rotate(6deg);  opacity: 1; animation-timing-function: cubic-bezier(.4, 0, 1, 1); }
  100% { transform: translateZ(420px) scale(1.3)  rotate(12deg); opacity: 0; }
}
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__pecat {
  animation: vso-pecat-prec calc(5 * var(--f1)) linear calc(2 * var(--f1)) both;
}

/* Klopy sa otvárajú K DIVÁKOVI: znamienka sú tak, aby pri každej hrane
   išla voľná strana do kladného z. Konečný uhol 168°, nie 180° — úplne
   plochá klopa splynie s okrajom a otvorená obálka stratí hĺbku.

   DVE ETAPY V JEDNEJ KRIVKE: to, čo hosť naozaj vidí, je dvíhanie od 0°
   do ~88° — klopa rastie k nemu a odhaľuje vnútro. Za 90° už je hranou
   a vzápätí mimo obrazu. Jedna plynulá krivka na celých 168° preletela
   viditeľnú časť za tri snímky; preto 62 % času patrí dvíhaniu (pomalý
   nábeh, aby sa pohyb „zachytil"), zvyšok odchodu. */
@keyframes vso-klopa-horna {
  0%   { transform: translateZ(1px) rotateX(0deg);   animation-timing-function: cubic-bezier(.5, 0, .55, 1); }
  62%  { transform: translateZ(1px) rotateX(88deg);  animation-timing-function: cubic-bezier(.3, 0, .7, 1); }
  100% { transform: translateZ(1px) rotateX(168deg); }
}
@keyframes vso-klopa-dolna {
  0%   { transform: translateZ(1px) rotateX(0deg);   animation-timing-function: cubic-bezier(.5, 0, .55, 1); }
  62%  { transform: translateZ(1px) rotateX(-88deg); animation-timing-function: cubic-bezier(.3, 0, .7, 1); }
  100% { transform: translateZ(1px) rotateX(-168deg); }
}
@keyframes vso-klopa-lava {
  0%   { transform: translateZ(1px) rotateY(0deg);   animation-timing-function: cubic-bezier(.5, 0, .55, 1); }
  62%  { transform: translateZ(1px) rotateY(-88deg); animation-timing-function: cubic-bezier(.3, 0, .7, 1); }
  100% { transform: translateZ(1px) rotateY(-168deg); }
}
@keyframes vso-klopa-prava {
  0%   { transform: translateZ(1px) rotateY(0deg);   animation-timing-function: cubic-bezier(.5, 0, .55, 1); }
  62%  { transform: translateZ(1px) rotateY(88deg);  animation-timing-function: cubic-bezier(.3, 0, .7, 1); }
  100% { transform: translateZ(1px) rotateY(168deg); }
}

/* Pomalý nábeh, plynulý dobeh: prvá tretina otvárania je to, čo hosť
   naozaj vidí (klopa sa dvíha a rastie k nemu), zvyšok je už len odchod
   z obrazu. Rýchla krivka to zlisovala do troch snímok. */
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__klopa--horna {
  animation: vso-klopa-horna calc(14 * var(--f1)) linear calc(3 * var(--f1)) both;
}
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__klopa--lava {
  animation: vso-klopa-lava calc(14 * var(--f1)) linear calc(6 * var(--f1)) both;
}
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__klopa--prava {
  animation: vso-klopa-prava calc(14 * var(--f1)) linear calc(6 * var(--f1)) both;
}
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__klopa--dolna {
  animation: vso-klopa-dolna calc(14 * var(--f1)) linear calc(9 * var(--f1)) both;
}

/* Svetlo zvnútra sa rozleje s klopami. */
@keyframes vso-svetlo-in { from { opacity: 0; } to { opacity: 1; } }
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__svetlo {
  animation: vso-svetlo-in calc(14 * var(--f1)) ease-in-out calc(6 * var(--f1)) both;
}

/* Kartička vyrastie z obálky, keď sú klopy za hranou (horná od f15, bočné
   od f15, spodná od f18): pomalý dobeh, aby sa „zastavila v ruke". */
/* KARTIČKA SA NEPRIBLIŽUJE. Ležala v obálke zmenšená na 0,84 a dorastala
   na celé javisko — a kým rástla, po jej stranách bolo vidieť farbu vnútra
   obálky. Vlastník: „vidno voľné okraje, že sa ten papier približuje;
   chcem, aby už tam bol." Je preto od prvej snímky v plnej veľkosti; klopy
   ju do svojho odklopenia celú zakrývajú, takže sa objaví naraz a celá.
   To isté platí pre kresbu: pomalé priblíženie 1,08 → 1 bolo pri nehybnej
   kartičke jediné, čo sa ešte hýbalo dopredu. Doostrenie ostáva — dáva
   pocit „doostrenia do ostra" bez toho, aby papierom pohlo. */
@keyframes vso-bloom-prec { from { opacity: 0.8; } to { opacity: 0; } }
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__karta-bloom {
  animation: vso-bloom-prec calc(16 * var(--f1)) ease-in-out calc(18 * var(--f1)) both;
}

/* Text nabieha po riadkoch zdola. */
@keyframes vso-text-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__karta-text > * {
  animation: vso-text-in calc(8 * var(--f1)) cubic-bezier(.2, .7, .2, 1) both;
}
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__karta-text > :nth-child(1) { animation-delay: calc(24 * var(--f1)); }
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__karta-text > :nth-child(2) { animation-delay: calc(27 * var(--f1)); }
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__karta-text > :nth-child(3) { animation-delay: calc(30 * var(--f1)); }
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__karta-text > :nth-child(4) { animation-delay: calc(32 * var(--f1)); }
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__karta-text > :nth-child(5) { animation-delay: calc(36 * var(--f1)); }

/* Žiara za menami: rozsvieti sa a potom dýcha. Dve animácie na jednom
   prvku — druhá začína presne tam, kde prvá končí (0,85), inak by skočila. */
@keyframes vso-ziara-karta { from { opacity: 0; } to { opacity: 0.85; } }
@keyframes vso-ziara-dych { from { opacity: 0.85; } to { opacity: 0.6; } }
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__karta-ziara {
  animation:
    vso-ziara-karta calc(10 * var(--f1)) ease-out calc(26 * var(--f1)) both,
    vso-ziara-dych calc(30 * var(--f1)) ease-in-out calc(36 * var(--f1)) infinite alternate;
}

/* Lesk cez mená: prebehne raz po nabehnutí textu, potom každé 4 s. */
@keyframes vso-lesk {
  0%   { transform: translateX(-140%); opacity: 0; }
  8%   { opacity: 1; }
  30%  { transform: translateX(320%); opacity: 1; }
  31%  { opacity: 0; }
  100% { transform: translateX(320%); opacity: 0; }
}
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__lesk {
  animation: vso-lesk calc(48 * var(--f1)) cubic-bezier(.4, 0, .6, 1) calc(38 * var(--f1)) infinite;
}

/* Častice. Lupene padajú z vrchu s bočným rozkmitom a otáčaním, iskry
   blikajú na mieste v kresbe. Časy a polohy nesie každý kus v --t/--d/--x. */
@keyframes vso-lupen {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg); opacity: 0; }
  6%   { opacity: 0.95; }
  50%  { transform: translate3d(var(--sw), calc(var(--vs-vyska, 100vh) * 0.55), 0) rotate(calc(var(--r) * 3)); }
  94%  { opacity: 0.9; }
  100% { transform: translate3d(calc(var(--sw) * -0.6), calc(var(--vs-vyska, 100vh) * 1.12), 0) rotate(calc(var(--r) * 6)); opacity: 0; }
}
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__castice--lupene .vso__castica {
  animation: vso-lupen var(--t) linear calc(28 * var(--f1) + var(--d)) infinite;
}
@keyframes vso-iskra {
  0%   { transform: scale(0.3) rotate(0deg); opacity: 0; }
  40%  { transform: scale(1) rotate(20deg); opacity: 1; }
  100% { transform: scale(0.2) rotate(45deg); opacity: 0; }
}
.vs[data-vstup="obalka"]:not([data-faza="pokoj"]) .vso__castice--iskry .vso__castica {
  animation: vso-iskra calc(var(--t) * 0.35) ease-in-out calc(28 * var(--f1) + var(--d)) infinite;
}

/* ══════════════════════════════════════════════════════════════════════
   BEZ POHYBU — rovno VÝSLEDOK: otvorená obálka so svetlom a vytiahnutou
   kartičkou, bez pečate.
   Motor takej vrstve zabije všetky animácie, koncové pózy musia byť
   staticky.
   ══════════════════════════════════════════════════════════════════════ */
.vs[data-vstup="obalka"][data-bez-pohybu="ano"] .vso__vyzva,
.vs[data-vstup="obalka"][data-bez-pohybu="ano"] .vso__pecat { opacity: 0; }
.vs[data-vstup="obalka"][data-bez-pohybu="ano"] .vso__svetlo { opacity: 1; }
.vs[data-vstup="obalka"][data-bez-pohybu="ano"] .vso__karta-bloom { opacity: 0; }
.vs[data-vstup="obalka"][data-bez-pohybu="ano"] .vso__karta-ziara { opacity: 0.85; }
.vs[data-vstup="obalka"][data-bez-pohybu="ano"] .vso__karta-text > * { opacity: 1; transform: none; }
.vs[data-vstup="obalka"][data-bez-pohybu="ano"] .vso__lesk,
.vs[data-vstup="obalka"][data-bez-pohybu="ano"] .vso__castica { opacity: 0; }
.vs[data-vstup="obalka"][data-bez-pohybu="ano"] .vso__klopa--horna { transform: translateZ(1px) rotateX(168deg); }
.vs[data-vstup="obalka"][data-bez-pohybu="ano"] .vso__klopa--dolna { transform: translateZ(1px) rotateX(-168deg); }
.vs[data-vstup="obalka"][data-bez-pohybu="ano"] .vso__klopa--lava  { transform: translateZ(1px) rotateY(-168deg); }
.vs[data-vstup="obalka"][data-bez-pohybu="ano"] .vso__klopa--prava { transform: translateZ(1px) rotateY(168deg); }

/* ── ladenie v proto/obalka.html ──────────────────────────────────────
   Prepínač „ukáž rezy" zafarbí každú klopu inou farbou (podklad pod
   stlmeným obrázkom sa oreže tým istým clip-path), aby bolo vidieť, či
   rez sedí na nakreslenom záhybe. Outline by nešiel — nesleduje clip. */
.vs[data-vstup="obalka"] .vso--rezy .vso__lic img { opacity: 0.45; }
.vs[data-vstup="obalka"] .vso--rezy .vso__klopa--horna .vso__lic { background: rgba(255, 0, 90, 0.55); }
.vs[data-vstup="obalka"] .vso--rezy .vso__klopa--dolna .vso__lic { background: rgba(0, 120, 255, 0.55); }
.vs[data-vstup="obalka"] .vso--rezy .vso__klopa--lava  .vso__lic { background: rgba(0, 170, 90, 0.55); }
.vs[data-vstup="obalka"] .vso--rezy .vso__klopa--prava .vso__lic { background: rgba(255, 170, 0, 0.55); }
