/* Öt világ hangjai — teljes képernyős plakát.
   Háttér: feldolgozott kép. Fölötte húrok, folyékony feliratok, kezek.

   A rétegek sorban érkeznek: előbb a cím, utána a dátum, majd a húrok és a
   kezek. Egyszerre indítva mind a képkockakeretet is szétfeszítené, és a
   feliratok megjelenése akadozna. */

:root {
  --pad: clamp(18px, 2.6vw, 36px);
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", "IBM Plex Mono", Menlo, Consolas, monospace;
  --sans: "Geist", system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --toggle-h: clamp(.68rem, 3.7vw, 2.3rem); /* a „jegyek" felirat magassága */
  --name-h: clamp(.8rem, 5vw, 3rem);     /* a szerzők neve — a dátum is ehhez igazodik */
  --addr-h: clamp(.5rem, 2.6vw, 1.05rem);   /* a helyszín sorainak magassága */
  --paper: #d1b0b0;
  --ink: #0f0f12;
  --ease: cubic-bezier(.16, 1, .3, 1);
  /* A fiók ezen nyílik: van nekifutása, aztán hosszan kifut. Túllendülés itt
     nem látszana: a doboz a szöveg szélességénél megáll, akármeddig nő az
     átmenet értéke. */
  --ease-slide: cubic-bezier(.33, .9, .25, 1);
  /* Az érkezés: lendülettel jön föl a lap széle mögül, és a helyén hosszan
     fékez. Túl nem fut rajta — ott a doboz elemelkedne az aljától. */
  --ease-back: cubic-bezier(.22, .95, .26, 1);
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: #d9c6c8;            /* amíg a kép be nem tölt */
  font-family: var(--mono);
  overflow: hidden;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.hero {
  position: relative;
  height: 100vh;
  height: 100svh;                 /* mobil címsorral együtt is teljes képernyő */
  overflow: hidden;
}

#hero {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* --- Kezek és húrok ---------------------------------------------------- */

.hand,
.strings {
  position: absolute;
  pointer-events: none;
  user-select: none;
}

/* A húrok maguk fogadják a mutatót, hogy a böngésző a tényleges alakzatra
   vizsgálja a találatot */
.string { pointer-events: auto; }

/* A két kép ugyanannak a vásznak a rétege, ezért alapból fedik egymást;
   az eltolás bontja szét őket a plakát szerinti helyükre.
   A `translateZ(0)` tartja őket külön kompozitor-rétegen. */
/* A `visibility` és a `will-change` csak a helyükre érkezéskor kapcsol be:
   addig a két nagy kép nem kap kompozitor-réteget. Rétegként a képernyő teljes
   méretét foglalnák, és a feliratok megjelenése alatt vinnék a sávszélességet. */
.hand {
  z-index: 2;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity .9s ease;
}

.hand.is-in { opacity: 1; visibility: visible; will-change: opacity; }

/* A beúszás a külső dobozé, az egérkövetés a képé. Egy elemen a kettő
   ugyanazt az attribútumot írná, és az egyik mindig eldobná a másikat. */
.hand img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: 50% 50%;
  will-change: transform;
}

/* A kezek nem úsznak be: ott vannak, ahol lenniük kell, és csak előjönnek. Az
   elmozdulást a mutatókövetés és a saját lebegésük viszi, az pedig a benti
   képen megy, nem ezen az elemen. */
.hand-left { transform: translate(7%, 11%) scale(1.24) translateZ(0); }
.hand-right { transform: translate(15%, -14%) scale(1.16) translateZ(0); }

/* Rétegsorrend: húrok leghátul, rájuk a feliratok, elöl a két kéz */
.strings {
  z-index: 0;
  top: 50%;
  left: 68%;
  width: 54vh;
  height: 148%;
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, -50%) translateZ(0);
  transition: opacity .95s ease;
}

.strings.is-in {
  opacity: .78;
  visibility: visible;
  will-change: opacity;
}

/* A húr a jobb kézzel együtt mozog (js/main.js). A beúszás a külső dobozé,
   ez a mozgás a rajzé — egy elemen a kettő ugyanazt az attribútumot írná. */
.strings-svg {
  display: block;
  width: 100%;
  height: 100%;
  will-change: transform;
}

/* --- Feliratok --------------------------------------------------------- */

/* Minden mozgás JS-ből jön (js/title.js): a szűrőértékek nem animálhatók
   CSS-ből, és így a szín, az olvadás és a fény egy órán fut. */

.liquid {
  position: absolute;
  z-index: 1;
  margin: 0;
  line-height: 0;
  /* A szűrő minden képkockán változik: saját réteg kell neki, különben a
     környezetét is újrafestetné.

     `contain: paint` NEM használható: az az elem dobozára vágná a festést, a
     szűrő kiégése viszont szándékosan túlnyúlik rajta. */
  will-change: filter;
  pointer-events: none;           /* ne fogja el a húrok elől a mutatót */
  /* Amíg nem jön el a sora, nincs a képernyőn. A szűrő induló értékeivel
     kirajzolva állna itt, és a megjelenés kezdetén ugrana szét. */
  opacity: 0;
}

.liquid.is-live { opacity: 1; }

.liquid-stack {
  position: relative;
  display: block;
}

/* A haló abszolút pozicionált, ez pedig nem: sorrend ide nem elég, mert a
   pozicionált elem akkor is fölé fest. Ezért kap ez is helyet a sorban. */
.liquid-svg {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* A tág kiégés. Nem az animált szűrő állítja elő, hanem ez a réteg, egyszer;
   képkockánként csak az átlátszósága változik, azt pedig a kompozitor intézi,
   újrarajzolás nélkül. A `will-change` biztosítja a saját réteget — enélkül a
   felirat minden újrarajzolása ezt a nagy elmosást is újraszámoltatná. */
.liquid-halo {
  position: absolute;
  z-index: 0;
  left: 0;
  top: 0;
  width: 100%;
  height: auto;
  overflow: visible;
  opacity: 0;
  will-change: opacity;
  pointer-events: none;
}

.liquid-halo use { fill: #fff; }   /* csak az alfája számít */

/* A rétegek csak az alfát használják; a színt a szűrő végén a feFlood adja,
   ezért a kitöltés itt csak átlátszatlan legyen */
.liquid-svg .mark { fill: #fff; }

.title {
  top: 50%;
  left: 50%;
  width: min(88vw, 56rem);
  transform: translate(-50%, -62%);
}

/* Bal felső sarok: az időpont, alatta a helyszín. A doboz viszi a paddingot,
   a két felirat pedig teljes szélességben ül benne. */
.top-left {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  padding: 1em;
  width: min(52vw, 24rem);
}

/* A dátum és a helyszín együtt egy hivatkozás. Az <a> csak összefogja őket:
   se szín, se aláhúzás, a rajzok maguk a felület. */
.fb-event {
  display: block;
  color: inherit;
  text-decoration: none;
}

/* A `.liquid` alapból nem fogadja a mutatót (a húroknak hagyja); a három rajz
   viszont visszakapja, hogy a hivatkozásra rá lehessen menni. A találati
   felület a rajz doboza, nem a bal felső sarok teljes szélessége. */
.fb-event .liquid-stack {
  pointer-events: auto;
  cursor: pointer;
}

.date,
.address {
  position: static;
  margin: 0;
  width: 100%;
}

/* A dátum betűi akkorák, mint a szerzők nevéé. A két rajz kerete más — a
   nevekben a betű a doboz 77%-a, a dátumban 15,7% —, ezért nem a dobozuk
   egyezik, hanem a betűméretük: 0,7708 / 0,1567 = 4,92-szeres magasság. A
   helyszín nem tartozik ide, az marad kisebb. */
.date .liquid-stack {
  display: inline-block;
  vertical-align: bottom;
}

.date .liquid-svg {
  width: auto;
  height: calc(var(--name-h) * 4.92);
}

.date .liquid-halo {
  width: 100%;
  height: 100%;
}

/* A dátum svg-jének viewBoxa maga is tartalmaz keretet: a rajz körül 88,83
   egység, ami a doboz szélességének 11,75%-a, magasságának 22,22%-a. A rajzot
   tehát ennyivel kifelé toljuk, hogy az kerüljön a padding szélére, ne a doboz.
   A címnél ez nem számít, azt a közepére igazítjuk. */
.date .liquid-stack { transform: translate(-11.75%, -22.22%); }

/* A helyszín két sora. Magassággal méretezünk, hogy a betűméretük egyezzen; a
   második sor rajza alacsonyabb, ezért az arányát külön kapja. */
.address .liquid-stack {
  display: inline-block;
  vertical-align: bottom;
}

.address .liquid-svg {
  width: auto;
  height: var(--addr-h);
}

.address .liquid-halo {
  width: 100%;
  height: 100%;
}

.address-1 .liquid-svg { height: calc(var(--addr-h) * .774); }

/* A dátum dobozának alsó 44,44%-a a viewBox kerete, tehát üres. Az első sort
   ennyivel húzzuk fel, különben akkora hézag maradna, mint maga a dátum.
   Százalékban a doboz szélességéhez mérve: 0,4444 × (399,73 / 756,02). */
.address-2 { margin-top: calc(-23.5% + .5em); }
.address-1 { margin-top: .2em; }

/* Asztali méret alatt a húr az ablak *szélességéhez* méretezik, nem a
   magasságához. Álló formátumban a magasság sokszorosa a szélességnek, tehát a
   vh-alapú méret ott a képernyőnél is szélesebb köteget adna; a vw-alapú
   nagyjából annyit foglal a képből, mint asztali nézetben. */
@media (max-width: 46rem) {
  .strings { width: 56vw; }
}

@media (prefers-reduced-motion: reduce) {
  .hand, .strings { transition: none; }
}

/* --- Előadók ----------------------------------------------------------- */

/* A jegyek a bal alsó sarokban, a nevek a jobb alsóban. Az `<a>` csak
   összefogja: se szín, se aláhúzás, a rajz maga a felület. */
.tickets {
  display: block;
  color: inherit;
  text-decoration: none;
}

.tickets .liquid-stack {
  pointer-events: auto;
  cursor: pointer;
}

.tickets-label {
  left: 0;
  bottom: 0;
  margin: 0;
  padding: 1em;
}

.tickets-label .liquid-stack,
.performer .liquid-stack {
  display: inline-block;
  vertical-align: bottom;
}

/* Magassággal méretezünk, nem szélességgel: mind a hat rajz ugyanolyan magas,
   így lesz egyforma a betűméretük. A magasság az ablak *szélességéhez* kötött,
   mert a leghosszabb név tízszer olyan széles, mint amilyen magas — függőleges
   mértékkel keskeny ablakban kilógna. */
.tickets-label .liquid-svg {
  width: auto;
  height: var(--toggle-h);
}

.performer .liquid-svg {
  width: auto;
  height: var(--name-h);
}

.tickets-label .liquid-halo,
.performer .liquid-halo {
  width: 100%;
  height: 100%;
}

/* A nevek a jobb alsó sarokban, végig láthatóan. Szándékosan nincs z-indexük:
   azzal saját rétegsort nyitnának, és a benti nevek nem tudnának a kezek fölé
   emelkedni. Így a rétegsorrendet a nevek maguk viszik, a kezekkel egy sorban. */
.performer-names {
  position: absolute;
  right: 0;
  bottom: 0;
  padding: 1em;
  text-align: right;
  pointer-events: none;
}

/* A nevek a kezek alatt futnak (kéz: 2), a mutató alatt lévő viszont föléjük
   emelkedik — különben a kéz eltakarná épp azt, amit olvasni akarunk. */
.performer {
  position: relative;
  z-index: 1;
  margin: 0;
  line-height: 0;
}

.performer:hover { z-index: 3; }

/* A névre kattintva az ő darabja szólal meg. A találati felület maga a rajz
   doboza, nem a teljes sor szélessége. */
.performer .liquid-stack {
  pointer-events: auto;
  cursor: pointer;
}

/* A nevek ugyanúgy viselkednek, mint az „előadók" felirat: a .liquid tartja
   őket rejtve, amíg el nem jön a soruk. Halványítás nincs rajtuk — az a
   `liquid` rejtését is felülírta volna, és a nevek a betöltéstől ott ültek
   volna halványan a sarokban. */

/* A nevek mérete a feliratéval egyezik: mindkettő a --toggle-h magasságot
   kapja a fenti közös szabályból. */

/* --- Lejátszó ----------------------------------------------------------- */

/* Fehérrel, a jobb felső sarokban. A neve fölötte áll: a sáv csak azt mutatja,
   hol tartunk, a lényeg az, hogy kinek a darabját halljuk. */

/* A név és a sáv egy sorban fut. Keskeny ablakban egymás alá kerülnek: mellé
   téve vagy a dátumra futnának rá, vagy mindkettőből olvashatatlan csík lenne. */
.player {
  position: absolute;
  z-index: 4;
  top: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: .9em;
  padding: 1em;
  width: min(64vw, 27rem);
  font-family: var(--sans);
  color: #fff;
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 1.1s ease .4s, transform 1.3s var(--ease) .4s;
  pointer-events: none;
}

.player.is-in {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

/* Egy sorban, körbejárva. A név hossza darabonként más, a doboz viszont fix:
   ami nem fér ki, az befut. Két egyforma példány fut egymás után, és a szalag a
   feléig csúszik el — ott a második példány pontosan ott áll, ahol az első
   indult, tehát a visszaugrás nem látszik. */
.player-now {
  flex: none;
  overflow: hidden;
  width: min(44%, 11.5rem);
  margin: 0;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .5);
  /* A két szélén elhalványul, hogy a szöveg ne vágva érjen a doboz széléhez */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}

.player-marquee {
  display: flex;
  width: max-content;
  /* Saját réteget kérünk: enélkül a szalag a főszálon mozogna, és minden
     akadás rajta is látszana */
  will-change: transform;
  /* Az időt a JS méri ki a szöveg hosszából, hogy a sebesség állandó legyen */
  animation: player-marquee var(--marquee-t, 12s) linear infinite;
}

.player-item {
  display: flex;
  align-items: baseline;
  gap: 0 .5em;
  padding-right: 2.6em;
  white-space: nowrap;
}

@keyframes player-marquee {
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .player-marquee { animation: none; }
}

.player-who {
  font-size: clamp(.72rem, 1.5vw, .88rem);
  font-weight: 500;
  letter-spacing: .02em;
  text-transform: uppercase;
}

.player-piece {
  font-size: clamp(.66rem, 1.35vw, .8rem);
  opacity: .78;
}

.player-bar {
  flex: 1;
  display: flex;
  align-items: center;
  gap: .6em;
  min-width: 0;
}



/* A sáv: halvány alap, tömör kitöltés. Fogó nincs rajta — nem tekerhető, csak
   mutatja, hol tartunk. */
.player-track {
  position: relative;
  flex: 1;
  height: 3px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .38);
}

.player-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  border-radius: 3px;
  background: #fff;
}

.player-mute {
  flex: none;
  display: grid;
  place-items: center;
  width: 2.1em;
  height: 2.1em;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}

.player-mute svg {
  width: 1.4em;
  height: 1.4em;
  fill: none;
  stroke: #fff;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .5));
}

.player-mute .player-cone { fill: #fff; }
.player-mute .player-cross { display: none; }

.player.is-muted .player-wave { display: none; }
.player.is-muted .player-cross { display: block; }
.player.is-muted .player-mute svg { opacity: .7; }

.player-mute:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* Amíg a hangra várunk, az egész lap kattintható — mert tényleg az: bárhol
   éri a mozdulat, az oldja fel. A mutató alakja mondja ezt el a leghamarabb,
   még a felirat elolvasása előtt. Csak addig, amíg a hang meg nem jön. */
.wants-sound, .wants-sound .hero, .wants-sound canvas { cursor: pointer; }

/* Amikor a címke látszik, ő maga a mutató: a nyíl elmarad alóla. Így a szó nem
   a nyíl mellett lóg, hanem az van a kezünkben, ami a dolgot megnevezi — a
   neveknél a „meghallgatom", a dátumon a „Facebook esemény", hang nélkül a
   „kattints a hangért".

   A `!important` itt nem lustaság: a nyilat olyan szabályok fölött kell
   levenni, amelyek épp azt mondják ki, hogy az adott folt kattintható
   (`cursor: pointer`), és ezek az elemeken ülnek, nem a gyökéren. */
.cue-cursor, .cue-cursor * { cursor: none !important; }

/* A hívogató felirat a némítógomb mellett — az érintős ág.

   Egérrel a mondanivaló a mutató mellett megy (lásd `.cue` ragadós módja): ott
   az a jó, mert bárhová lehet kattintani, és a felirat mindig ott van, ahová a
   szem néz. Érintésre viszont nincs mutató, amihez ragadhatna, ezért ott ez a
   címke áll a sávban. Ugyanaz a mondat, két készülékhez.

   Csak akkor van kitéve, ha a böngésző elutasította a hangot. */
.player-ask {
  display: none;
  align-items: center;
  margin-right: .55em;
  padding: .3em .55em .34em;
  /* Fordított doboz: a sáv maga sötét, tehát a lapon megszokott fekete címke
     itt láthatatlan volna. Világos alapon sötét betű — a sávon ez az egyetlen
     ilyen folt, tehát oda néz a szem. */
  background: #fff;
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 600;
  font-size: clamp(.55rem, 1.05vw, .68rem);
  letter-spacing: .015em;
  line-height: 1.2;
  white-space: nowrap;
  animation: ask-in .5s ease both;
}

@media (hover: none) {
  .player.is-blocked .player-ask { display: flex; }
}

@keyframes ask-in {
  from { opacity: 0; transform: translateX(6px); }
  to   { opacity: 1; transform: none; }
}

/* Amikor a böngésző nem engedte magától a hangot. Ilyenkor a némítógomb nem
   csak egy állapotot mutat, hanem az egyetlen út a zenéhez — tehát szólnia kell
   magáról. Lassan lélegzik: elég ahhoz, hogy a szem odataláljon, kevés ahhoz,
   hogy zavarjon. Az első mozdulatra megszűnik, akárhol érte a lapot. */
.player.is-blocked .player-mute svg {
  opacity: 1;
  animation: mute-breathe 2.4s ease-in-out infinite;
}

@keyframes mute-breathe {
  0%, 100% { transform: scale(1);    opacity: .72; }
  50%      { transform: scale(1.14); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  /* Mozgás nélkül is látszania kell, hogy ez itt kér valamit: akkor álljon
     teljes fényben, a többi felirat halványabb világában. */
  .player.is-blocked .player-mute svg { animation: none; opacity: 1; }
}

/* --- A mutató melletti címke ------------------------------------------- */

/* Amíg egy szerző nevén állunk, a mutató mellett ott a szó, ami megmondja, mi
   történik kattintásra. Szögletes fekete doboz — a lapon minden más lágy, ez
   szándékosan nem az: ez nem a kép része, hanem utasítás. */
.cue {
  position: fixed;
  z-index: 6;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  gap: .4em;
  padding: .3em .5em .34em;
  background: var(--ink);
  color: #fff;
  font-family: var(--sans);
  font-size: clamp(.55rem, 1.1vw, .7rem);
  letter-spacing: .015em;
  line-height: 1.2;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity .16s ease;
  will-change: transform;
}

.cue.is-on { opacity: 1; }

/* Az ikon a szöveg betűjével együtt méretezik, hogy a kettő egy mérethez
   tartozzon. A két rajz közül mindig csak az van kitéve, amelyikről szó van. */
.cue-icon {
  flex: none;
  width: 1.15em;
  height: 1.15em;
  fill: currentColor;
}

.cue .cue-play,
.cue .cue-link,
.cue .cue-sound,
.cue .cue-ticket { display: none; }

.cue.is-play .cue-play,
.cue.is-link .cue-link,
.cue.is-sound .cue-sound,
.cue.is-ticket .cue-ticket { display: inline; }

/* Érintésre nincs lebegés, tehát a címkének sincs értelme */
@media (hover: none) {
  .cue { display: none; }
}

/* --- Érintős jelzés ----------------------------------------------------- */

/* Ugyanaz a szögletes fekete doboz, mint a mutató mellett — érintős nézetben
   viszont nincs mutató, tehát egyszer felvillan a nevek fölött, és többé nem
   jön vissza. Ismételgetve zavaró lenne; egyszer viszont el kell mondani. */
.tap-hint {
  display: none;
  align-items: center;
  margin: 0 0 .5em;
  padding: .3em .45em .34em .5em;
  background: var(--ink);
  color: #fff;
  font-family: var(--sans);
  font-size: clamp(.55rem, 1.1vw, .7rem);
  letter-spacing: .015em;
  line-height: 1.2;
  white-space: nowrap;
  opacity: 0;
  transition: opacity .55s ease;
}

@media (max-width: 46rem) {
  .tap-hint { display: inline-flex; }
}

.tap-hint.is-on { opacity: 1; }


/* --- Telefonos nézet ---------------------------------------------------- */

/* Álló, keskeny képen más a sorrend: elöl a lejátszó, mert azért van itt az
   oldal; alatta az időpont és a helyszín; a nevek pedig alul, olvasható
   méretben. Az „előadók" felirat elmarad — a koppintásjelzés úgyis megmondja,
   mit kezdjünk a nevekkel, és a hely elfogy nélküle is. */
@media (max-width: 46rem) {
  :root {
    --addr-h: clamp(.6rem, 3.4vw, 1.3rem);
  }

  /* A jegyek telefonon *nem* tüntethetők el — a látogatók java a
     Facebook-eseményről érkezik, telefonról, és épp ezért. A bal alsó sarokban
     viszont nincs helyük: ott a leghosszabb név majdnem a teljes szélességet
     elfoglalja. Ezért átkerülnek a jobb felső sarokba, a lejátszó sávja alá,
     szemközt a dátummal — és akkora betűvel, mint az: a rajzuk ugyanúgy
     kitölti a saját keretét, mint a neveké, tehát azonos magasság azonos
     betűméretet jelent. */
  .tickets-label {
    left: auto;
    bottom: auto;
    right: 0;
    top: 0;
    padding: .8em;
    /* A dátum első sorával egy magasságban. Fix mérték, nem a névmagassághoz
       kötött: a dátum függőleges helyét a bal felső doboz belső margója szabja
       meg, az pedig nem skálázódik a betűmérettel — mérve háromszázhúsz és
       négyszázharminc képpont között alig két képpontot mozdul. Aránnyal
       számolva a keskeny telefonokon elcsúszna. */
    margin-top: 3.53rem;
  }

  /* Valamivel kisebb, mint a dátum betűi. A rajz négy és háromnegyedszer olyan
     széles, mint amilyen magas, tehát a mellette maradó hely szabja meg,
     meddig lehet nőni: a `16` osztónál a dátum és a jegyek között minden
     telefonszélességen marad legalább tizenhárom képpont. */
  .tickets-label .liquid-svg {
    height: min(calc((100vw - 2em) / 16), var(--name-h));
  }

  /* A lejátszó a teljes szélességet kapja, legfelül, fekete sávon. A sáv a
     lap széléig ér — a padding belül van —, mint a készítő jelzésének
     négyzete. */
  .player {
    left: 0;
    right: 0;
    top: 0;
    width: auto;
    /* Alacsonyabb sáv: a magasságát a némítógomb és a padding adja, mindkettő
       szűkebb itt. Vízszintesen marad több levegő. */
    padding: .5em .9em;
    background: var(--ink);
    isolation: isolate;

    /* Úgy érkezik, mint a készítő jele: nem halványodik be, hanem becsúszik —
       csak ez fentről, a lap széle mögül. A hero levágja, amíg odakint van. */
    opacity: 1;
    transform: translateY(-100%);
    transition: transform .9s var(--ease);
  }

  /* Váltáskor egy fehér függöny húz át a sávon, balról jobbra. Tömör, éles
     szélű lap: nem elhalványuló pászma, hanem egy mozdulat. Egyszer megy át,
     gyorsan. */
  .player::after {
    content: '';
    position: absolute;
    inset: 0;
    /* Sötét szürke, nem fehér: a különbségképzés így nem fordítja ki teljesen,
       amin áthalad, csak megemeli. A sáv feketéje szürkébe vált, a szöveg
       kicsit tompul — mozdulat, nem villanás. Az `isolation` tartja a
       keveredést a lejátszón belül; enélkül a mögötte lévő képre is ráhatna. */
    background: #33333a;
    mix-blend-mode: difference;
    transform: translateX(-100%);
    pointer-events: none;
  }

  /* Erős be-ki lassítás: a függöny nem egyenletesen sétál át, hanem indul,
     átcsap, és lefékez. A korábbi lágyabb görbével inkább csúszott, mint
     mozdult. */
  .player.is-flash::after {
    animation: player-sweep .46s cubic-bezier(.83, 0, .17, 1) 1;
  }

  @keyframes player-sweep {
    from { transform: translateX(-100%); }
    to   { transform: translateX(100%); }
  }

  .player-now { width: min(46%, 13rem); }

  /* Az időpont és a helyszín a lejátszó alá kerül, nagyobban */
  .top-left {
    top: 3.5em;
    width: 76vw;
  }

  /* A cím svg-jének viewBoxa 23%-nyi keretet visz, tehát a *rajz* ennél
     jóval keskenyebb: 112vw-nél a betűk kb. 86vw-t foglalnak. */
  .title { width: 112vw; }

  /* A kezek valamivel nagyobbak: keskeny képen kevesebb látszik belőlük */
  /* A bal kéz kilóghat jobbra, de a bal széle — a mandzsetta vége — maradjon
     bent. A tinta a kép 3,7%-ánál kezdődik, tehát a nagyítás a doboz közepe
     körül kitolja: az eltolás alsó határa 1,58 × (0,5 − 0,037) − 0,5 = 23,2%.
     Balrébb csak úgy mehetne, ha kisebb lenne — 24% a kettő között. */
  /* A bal kéz a saját bal széléről nagyít, nem a doboz közepéről: így akkorára
     nőhet, amekkorára kell, a mandzsettája mégsem csúszik le a képernyőről.
     A -8,8% a határ: a rajz tintája a kép 3,79%-ánál kezdődik, ennél balrébb
     tolva a mandzsetta széle már a képernyőn kívülre kerülne. */
  .hand-left {
    transform-origin: 0 50%;
    transform: translate(-8.8%, 6%) scale(1.95) translateZ(0);
  }

  .hand-right { transform: translate(9%, -13%) scale(1.85) translateZ(0); }

  /* A kezek és a húr mozgását itt a böngésző viszi, nem a JS. Képkockánként
     írt eltolás a főszálon fut, és minden akadás meglátszik rajta; kulcskockás
     animációként viszont a kompozitoron megy, függetlenül attól, hogy a szűrők
     épp mit csinálnak. A húr a jobb kézzel azonos ütemet kap, hogy együtt
     maradjanak. */
  .hand-left img { animation: drift-left 23s ease-in-out infinite; }
  .hand-right img,
  .strings-svg { animation: drift-right 31s ease-in-out infinite; }

  /* Nincs lebegés, ami a mutató alatti nevet a kéz fölé emelné — telefonon
     tehát mindegyik ott van. Különben a nagyobbra vett kéz eltakarná őket. */
  .performer { z-index: 3; }

  /* A címke a neveken ül, tehát fölöttük kell lennie. Azonos z-indexnél a
     DOM-sorrend dönt, és a címke elöl van a jelölésben — így alá került. */
  .tap-hint { z-index: 4; }

  /* A nevek méretét a leghosszabb szabja meg: a „Szlovicsák Krisztina" rajza
     10,71-szer olyan széles, mint amilyen magas, tehát ekkora magasságnál tölti
     ki a képernyőt a paddingon belül. A többi név és a dátum ehhez igazodik.
     A felső korlát a szélesebb készülékeknek szól, ahol különben aránytalanul
     nagyra nőne. */
  :root { --name-h: min(calc((100vw - 2em) / 10.71), 3rem); }

  .performer + .performer { margin-top: .2em; }

  /* Az időpont a lejátszó sávja alatt kezdődjön, egy kis levegővel */
  .top-left { top: 3.1rem; }

  /* A némítógomb ujjal is eltalálható legyen */
  .player-mute {
    width: 2em;
    height: 2em;
    margin-right: -.35em;
  }

  .player-mute svg { width: 1.35em; height: 1.35em; }

  /* Nyolc folyékony felirat nyolc kompozitor-réteget kérne. Telefonon ez több
     kárt okoz — memóriát és sávszélességet —, mint amennyit használ.
     A megjelenésük itt nem a szűrőből jön, hanem egyszerű átúszásból. */
  .liquid {
    will-change: auto;
    transition: opacity .9s ease;
  }

  /* Telefonon nincs körbejárás: a név és a cím egyszerűen ki van írva. Egy
     mozgó szalag ott csak még egy dolog, ami akadhat. */
  .player-now {
    flex: none;
    width: auto;
    max-width: 100%;
    overflow: visible;
    -webkit-mask-image: none;
    mask-image: none;
  }

  .player-marquee {
    animation: none;
    will-change: auto;
  }

  .player-item { padding-right: 0; }
  .player-item + .player-item { display: none; }

  /* Ha a szöveg a képernyő felénél is szélesebb, nem fér el a vonal mellett:
     olyankor fölé kerül, a vonal pedig teljes szélességben alá. */
  .player.is-stacked {
    display: block;
  }

  .player.is-stacked .player-now {
    max-width: none;
    margin: 0 0 .5em;
  }

  .player.is-stacked .player-bar { width: 100%; }
}

/* --- Sötét indulás ------------------------------------------------------ */

/* Az oldal sötétből világosodik ki. A réteg mindenek fölött van, még a
   lejátszón is: az egész kép együtt jön elő, nem darabonként. */
.veil {
  position: absolute;
  z-index: 9;
  inset: 0;
  background: #07070a;
  pointer-events: none;
  opacity: 1;
  transition: opacity 1.5s ease;
}

.veil.is-out { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .veil { transition: opacity .4s ease; }
}

/* --- A kezek saját mozgása telefonon ------------------------------------ */

@keyframes drift-left {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg); }
  22%  { transform: translate3d(20px, 8px, 0) rotate(1.3deg); }
  47%  { transform: translate3d(7px, -11px, 0) rotate(-.7deg); }
  71%  { transform: translate3d(-16px, 5px, 0) rotate(-1.1deg); }
  100% { transform: translate3d(0, 0, 0) rotate(0deg); }
}

@keyframes drift-right {
  0%   { transform: translate3d(0, 0, 0); }
  28%  { transform: translate3d(-13px, 6px, 0); }
  55%  { transform: translate3d(9px, -8px, 0); }
  80%  { transform: translate3d(14px, 4px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .hand-left img,
  .hand-right img,
  .strings-svg { animation: none; }
}

/* --- A készítő jelzése -------------------------------------------------- */

/* Alapból egy fekete négyzet a jellel, semmi más. Mutatóra — érintésen az első
   koppintásra — jobbra kihúzódik, és balról előjön a szöveg: a négyzet a fogó,
   a szöveg a fiók. A doboz bal széle marad a helyén, tehát a mozgás jobbra
   megy, ahogy egy fiók is. */
.credit {
  /* A sáv vastagsága: ez a fekete négyzet oldala is. Egy helyen van megadva,
     mert a kettő nem térhet el egymástól. */
  --credit-bar: 2.47rem;
  position: absolute;
  z-index: 5;
  /* A negyed fordulat a bal alsó sarok körül a sávot a saroktól balra viszi;
     ennyivel toljuk vissza, hogy a bal éllel essen egybe. */
  left: var(--credit-bar);
  /* A felirat doboza a saját magassága plusz kétszer 1rem padding; ennyivel
     följebb. `em` itt rossz volna: az a jel apró betűmérete, nem a lapé. */
  bottom: calc(var(--toggle-h) + 2.6rem);
  display: inline-flex;
  align-items: stretch;
  /* A jel a forrásban a felirat után áll; fordított sorrendben ő kerül a sáv
     alsó végére, és a felirat nő ki fölötte. */
  flex-direction: row-reverse;
  /* Az egész sáv negyed fordulatot kap balra, a bal alsó sarka körül: a doboz
     így a lap bal pereméhez simul, a felirat pedig fölfelé nő ki alóla, és vele
     fordul a szöveg is. A jel és a doboz külön fordítása ezért nem kell — a
     szirmok a sáv hossza mentén feszülnek, a falak arra engednek, ahol van hely. */
  transform-origin: left bottom;
  transform: rotate(-90deg);
  font-family: var(--sans);
  /* A felirat mérete végig nagyjából ugyanaz: 10 és 12 képpont között. A jel
     nő a két végén, a szöveg nem — az olvashatóságához ennyi elég. */
  font-size: clamp(.62rem, 1.2vw, .74rem);
  letter-spacing: .02em;
  text-decoration: none;
  color: #fff;
  /* Utoljára érkezik: akkor, amikor már minden más a helyén van */
  visibility: hidden;
}

.credit.is-in { visibility: visible; }

/* A négyzet mérete nem a szöveghez kötött: az kisebb lett, a jel nem.
   Megjelenéskor a lap pereme mögül jön elő. A sáv el van fordítva, ezért a
   saját `translateY`-ja a képernyőn balra mutat — oda, ahol a lap széle van. */
.credit-badge {
  flex: none;
  /* A sáv mérete a dobozé, nem a jelé: enélkül a kifeszülő virág szélesebbre
     nyitná a rácsot, mint a négyzet, és a nyugvó jel jobbra csúszna benne. */
  display: grid;
  grid-template: minmax(0, 1fr) / minmax(0, 1fr);
  place-items: center;
  width: var(--credit-bar);
  height: var(--credit-bar);
  transform: translateY(-120%);
  transition: transform 1.05s var(--ease-back);
}

.credit.is-in .credit-badge { transform: none; }

/* A doboz nem tömör háttér, hanem rajz: így meg tud hajolni. Két oldala
   kidomborodik ott, ahol a szirom nekifeszül — a szirom nem lóg ki, hanem
   kinyomja maga előtt a falat, mint valami gumit. Ugyanaz a hat köbös
   szakasz minden állapotban, csak az oldalfalak közepe mozdul. */
/* A rajz és a jel egymáson ül, nem egymás alatt */
.credit-badge > * { grid-area: 1 / 1; }

.credit-box {
  justify-self: stretch;
  align-self: stretch;
  width: 100%;
  height: 100%;
  /* a dudor túlér a rajz keretén; enélkül a saját ablaka vágná le */
  overflow: visible;
}

.credit-box-shape {
  fill: var(--ink);
  d: path("M0,0 C33,0,67,0,100,0 C100,22,100,28,100,50 C100,72,100,78,100,100 C67,100,33,100,0,100 C0,78,0,72,0,50 C0,28,0,22,0,0 Z");
}

.credit.is-in .credit-box-shape { animation: credit-bulge 9s infinite; }

.credit:hover .credit-box-shape,
.credit.is-open .credit-box-shape { animation: none; }

@keyframes credit-bulge {
  0%, 71% { d: path("M0,0 C33,0,67,0,100,0 C100,22,100,28,100,50 C100,72,100,78,100,100 C67,100,33,100,0,100 C0,78,0,72,0,50 C0,28,0,22,0,0 Z"); animation-timing-function: cubic-bezier(.55, .06, .25, 1); }
  88%     { d: path("M0,0 C33,0,67,0,100,0 C100,22,126,28,126,50 C126,72,100,78,100,100 C67,100,33,100,0,100 C0,78,-26,72,-26,50 C-26,28,0,22,0,0 Z"); animation-timing-function: linear; }
  89.5%   { d: path("M0,0 C33,0,67,0,100,0 C100,22,126,28,126,50 C126,72,100,78,100,100 C67,100,33,100,0,100 C0,78,-26,72,-26,50 C-26,28,0,22,0,0 Z"); animation-timing-function: cubic-bezier(.32, 0, .15, 1); }
  91.5%   { d: path("M0,0 C33,0,67,0,100,0 C100,22,95,28,95,50 C95,72,100,78,100,100 C67,100,33,100,0,100 C0,78,5,72,5,50 C5,28,0,22,0,0 Z"); animation-timing-function: ease-in-out; }
  93.5%   { d: path("M0,0 C33,0,67,0,100,0 C100,22,103,28,103,50 C103,72,100,78,100,100 C67,100,33,100,0,100 C0,78,-3,72,-3,50 C-3,28,0,22,0,0 Z"); animation-timing-function: ease-in-out; }
  95.5%   { d: path("M0,0 C33,0,67,0,100,0 C100,22,98.6,28,98.6,50 C98.6,72,100,78,100,100 C67,100,33,100,0,100 C0,78,1.4,72,1.4,50 C1.4,28,0,22,0,0 Z"); animation-timing-function: ease-in-out; }
  97.5%   { d: path("M0,0 C33,0,67,0,100,0 C100,22,100.5,28,100.5,50 C100.5,72,100,78,100,100 C67,100,33,100,0,100 C0,78,-0.5,72,-0.5,50 C-0.5,28,0,22,0,0 Z"); animation-timing-function: ease-in-out; }
  100%    { d: path("M0,0 C33,0,67,0,100,0 C100,22,100,28,100,50 C100,72,100,78,100,100 C67,100,33,100,0,100 C0,78,0,72,0,50 C0,28,0,22,0,0 Z"); }
}

/* A jel: egyetlen rajz, ami időnként kifeszül. A két állapot a művész két
   rajza — a nyugvó és a kinyújtott szirmú —, ugyanabban a koordinátatérben,
   szakaszról szakaszra egymásnak feleltetve. Tizenöt végpontból kettő tér el:
   a bal és a jobb szirom csúcsa. Ezért a `d` átmenete nem valami általános
   torzulás, hanem pontosan az, amit a két rajz mond: a két oldalsó szirom
   nyúlik ki, a virág többi része áll.

   A doboz a legszélesebb állapothoz van szabva, tehát a kifeszült szirom a
   négyzet faláig ér, de nem lóg túl rajta — nekifeszül, nem kimászik. */
.credit-mark {
  width: 3.44rem;
  height: auto;
  /* A doboz a nyugvó virágra van szabva; kifeszülve a jel túlnő rajta, ezért
     az elem szélesebb a négyzetnél. A nagyítás a rajzolattal egy ütemben megy,
     ugyanazokkal a kulcskockákkal, a jel közepe a doboz közepe. */
  transform-origin: center;
  scale: .84;
}

/* A nyugvó alak a `d` attribútumban is ott van: ha a böngésző nem animálja a
   `d`-t (Firefox), akkor is a helyes rajzot látni, csak mozdulatlanul. */
.credit-body {
  d: path("M30.9664,9.7039 C34.4664,7.7039,34.4664,2.7039,30.9664,0.7039 C27.6856,-1.1709,23.702,0.9085,23.2158,4.4707 C22.7191,0.9085,18.6534,-1.1709,15.4664,0.7039 C11.9664,2.7039,11.9664,7.7039,15.4664,9.7039 C11.9664,7.7039,7.6664,10.2039,7.6664,14.2039 C7.6664,18.2039,11.9664,20.7039,15.4664,18.7039 C11.9664,20.7039,11.9664,25.7039,15.4664,27.7039 C18.7463,29.5781,22.7285,27.5003,23.2164,23.9397 C23.2164,23.9397,23.2164,23.9397,23.2164,23.9397 C23.2164,23.9397,23.2164,23.9397,23.2164,23.9397 C23.7042,27.5003,27.6864,29.5781,30.9664,27.7039 C34.4664,25.7039,34.4664,20.7039,30.9664,18.7039 C34.4664,20.7039,38.7664,18.2039,38.7664,14.2039 C38.7664,10.2039,34.4664,7.7039,30.9664,9.7039 Z");
}

/* Kilenc másodpercből két és fél a mozdulat, a többi állás — ez felhívás akar
   lenni, nem nyugtalanság. A nyúlás hosszú és nehézkes: másfél másodpercen át
   feszül ki, a végén már alig halad, mintha a doboz falának feszülne. Utána
   egyetlen tizedmásodperc alatt csapódik vissza — a nyugalmi méret alá —, és
   csillapodva leng ki magát. A hosszú erőlködés és a rövid visszacsapódás
   aránya az, amitől rugalmasnak látszik.

   Amint a felhasználó odaér, elhallgat: onnantól fölösleges hívogatni. */
.credit.is-in .credit-body { animation: credit-strain 9s infinite; }
.credit.is-in .credit-mark { animation: credit-swell 9s infinite; }

.credit:hover .credit-body,
.credit:hover .credit-mark,
.credit.is-open .credit-body,
.credit.is-open .credit-mark { animation: none; }

@keyframes credit-strain {
  0%, 71% { d: path("M30.9664,9.7039 C34.4664,7.7039,34.4664,2.7039,30.9664,0.7039 C27.6856,-1.1709,23.702,0.9085,23.2158,4.4707 C22.7191,0.9085,18.6534,-1.1709,15.4664,0.7039 C11.9664,2.7039,11.9664,7.7039,15.4664,9.7039 C11.9664,7.7039,7.6664,10.2039,7.6664,14.2039 C7.6664,18.2039,11.9664,20.7039,15.4664,18.7039 C11.9664,20.7039,11.9664,25.7039,15.4664,27.7039 C18.7463,29.5781,22.7285,27.5003,23.2164,23.9397 C23.2164,23.9397,23.2164,23.9397,23.2164,23.9397 C23.2164,23.9397,23.2164,23.9397,23.2164,23.9397 C23.7042,27.5003,27.6864,29.5781,30.9664,27.7039 C34.4664,25.7039,34.4664,20.7039,30.9664,18.7039 C34.4664,20.7039,38.7664,18.2039,38.7664,14.2039 C38.7664,10.2039,34.4664,7.7039,30.9664,9.7039 Z"); animation-timing-function: cubic-bezier(.55, .06, .25, 1); }
  88%     { d: path("M30.9664,9.7039 C34.8703,8.6993,34.4664,2.7039,30.9664,0.7039 C27.6856,-1.1709,23.702,0.9085,23.2158,4.4707 C22.7296,0.9085,18.746,-1.1709,15.4653,0.7039 C11.9653,2.7039,11.5613,8.6993,15.4653,9.7039 C4.9091,6.9874,0,10.2039,0,14.2039 C0,18.2039,3.8182,22.6419,15.4653,18.7039 C11.6465,19.995,11.9653,25.7039,15.4653,27.7039 C18.7452,29.5781,22.7274,27.5003,23.2153,23.9397 C23.2154,23.9407,23.2157,23.9415,23.2158,23.9424 C23.2159,23.9415,23.2162,23.9407,23.2164,23.9397 C23.7042,27.5003,27.6864,29.5781,30.9664,27.7039 C34.4664,25.7039,34.7852,19.995,30.9664,18.7039 C42.6135,22.6419,46.4316,18.2039,46.4316,14.2039 C46.4316,10.2039,41.5226,6.9874,30.9664,9.7039 Z"); animation-timing-function: linear; }
  89.5%   { d: path("M30.9664,9.7039 C34.8703,8.6993,34.4664,2.7039,30.9664,0.7039 C27.6856,-1.1709,23.702,0.9085,23.2158,4.4707 C22.7296,0.9085,18.746,-1.1709,15.4653,0.7039 C11.9653,2.7039,11.5613,8.6993,15.4653,9.7039 C4.9091,6.9874,0,10.2039,0,14.2039 C0,18.2039,3.8182,22.6419,15.4653,18.7039 C11.6465,19.995,11.9653,25.7039,15.4653,27.7039 C18.7452,29.5781,22.7274,27.5003,23.2153,23.9397 C23.2154,23.9407,23.2157,23.9415,23.2158,23.9424 C23.2159,23.9415,23.2162,23.9407,23.2164,23.9397 C23.7042,27.5003,27.6864,29.5781,30.9664,27.7039 C34.4664,25.7039,34.7852,19.995,30.9664,18.7039 C42.6135,22.6419,46.4316,18.2039,46.4316,14.2039 C46.4316,10.2039,41.5226,6.9874,30.9664,9.7039 Z"); animation-timing-function: cubic-bezier(.32, 0, .15, 1); }
  91.5%, 100% { d: path("M30.9664,9.7039 C34.4664,7.7039,34.4664,2.7039,30.9664,0.7039 C27.6856,-1.1709,23.702,0.9085,23.2158,4.4707 C22.7191,0.9085,18.6534,-1.1709,15.4664,0.7039 C11.9664,2.7039,11.9664,7.7039,15.4664,9.7039 C11.9664,7.7039,7.6664,10.2039,7.6664,14.2039 C7.6664,18.2039,11.9664,20.7039,15.4664,18.7039 C11.9664,20.7039,11.9664,25.7039,15.4664,27.7039 C18.7463,29.5781,22.7285,27.5003,23.2164,23.9397 C23.2164,23.9397,23.2164,23.9397,23.2164,23.9397 C23.2164,23.9397,23.2164,23.9397,23.2164,23.9397 C23.7042,27.5003,27.6864,29.5781,30.9664,27.7039 C34.4664,25.7039,34.4664,20.7039,30.9664,18.7039 C34.4664,20.7039,38.7664,18.2039,38.7664,14.2039 C38.7664,10.2039,34.4664,7.7039,30.9664,9.7039 Z"); }
}

/* A rugó: a visszacsapódás a nyugalmi méret alá húz, onnan lengve áll meg.
   Az elfordulás ugyanezt a lengést járja, néhány fokban: a nyúlás közben
   alig háromfoknyit csavarodik, aztán a nullán túl leng vissza. Ennyi épp
   csak érzékelhető — annyi, amitől élő a mozdulat, nem gépies.
   A kitérések egyre kisebbek — .08, .045, .025, .008 —, ez adja a csillapodást.
   A nyúlás közben a nagyítás együtt megy a rajzolattal; a lengés utána már
   csak a méreté, a szirmok addigra visszahúzódtak. */
@keyframes credit-swell {
  0%, 71% { rotate: 0deg; scale: .84; animation-timing-function: cubic-bezier(.55, .06, .25, 1); }
  88%     { rotate: 3.4deg; scale: 1; animation-timing-function: linear; }
  89.5%   { rotate: 3.4deg; scale: 1; animation-timing-function: cubic-bezier(.32, 0, .15, 1); }
  91.5%   { rotate: -1.9deg; scale: .76; animation-timing-function: ease-in-out; }
  93.5%   { rotate: 1.05deg; scale: .885; animation-timing-function: ease-in-out; }
  95.5%   { rotate: -.45deg; scale: .815; animation-timing-function: ease-in-out; }
  97.5%   { rotate: .18deg; scale: .848; animation-timing-function: ease-in-out; }
  100%    { rotate: 0deg; scale: .84; }
}

@media (prefers-reduced-motion: reduce) {
  .credit.is-in .credit-body,
  .credit.is-in .credit-mark { animation: none; }
}

/* Telefon fölött a sáv a képernyő közepére kerül: ott a bal él üres — a dátum
   fölötte, az „előadók" felirat alatta —, és a fiók fölfelé is elfér. A doboz
   kerül középre, nem a sáv: a felirat abból nő ki. */
@media (min-width: 46.01rem) {
  .credit {
    /* Itt nem az alsó vége áll fixen, hanem a közepe: a sáv a saját középpontja
       körül fordul, és a nyíló felirat két irányba egyszerre nő ki alóla, tehát
       a fekete a képernyő közepén marad. A `--credit-y` a középpont magassága. */
    top: var(--credit-y, 50%);
    bottom: auto;
    left: calc(var(--credit-bar) / 2);
    transform-origin: center;
    transform: translate(-50%, -50%) rotate(-90deg);
  }
}

/* Telefonon kisebb: ott a sarokban kevesebb a hely, és a nevek is nagyok */
@media (max-width: 46rem) {
  .credit { --credit-bar: 2.18rem; }
  .credit-mark { width: 2.99rem; }
}

/* Nulla szélességről nyílik: összecsukva a négyzeten kívül semmi nem foglal
   helyet, tehát tényleg csak a jel látszik. A szöveg nem halványodik, hanem
   kicsúszik a képből: a doboz vágja. */
.credit-text {
  display: flex;
  align-items: center;
  max-width: 0;
  padding: 0;
  overflow: hidden;
  white-space: nowrap;
  background: var(--ink);
  transition: max-width .62s var(--ease-slide), padding .62s var(--ease-slide);
}

/* A felirat nem mozog külön: a doboz nyílik ki alóla. Halványabb a jelnél —
   a lényeg a link, nem a szöveg hangsúlya. */
.credit-label { color: rgba(255, 255, 255, .78); }

.credit.is-open .credit-text,
.credit:hover .credit-text {
  /* a mért felirathossz; a tartalék érték csak akkor él, ha a script nem futott */
  max-width: var(--credit-w, 18em);
  padding: 0 .7em 0 .8em;
}


@media (prefers-reduced-motion: reduce) {
  .credit-text,
  .credit-label { transition: none; }
}

/* Telefonon az „előadók" felirat nincs kirakva, a nevek viszont a bal szélig
   érnek: a jelzés a listájuk fölé kerül. Az alapszabály után kell állnia,
   különben azonos súlynál a sorrend dönt ellene. */
@media (max-width: 46rem) {
  .credit { bottom: 12rem; }
}
