/* =========================================================================
   Il compleanno di Niki — foglio di stile unico.
   Ordine delle sezioni: variabili, base, impianto, componenti, effetti,
   adattamenti per schermi piccoli. Ogni colore passa dalle variabili qui
   sotto: per ritoccare la palette basta questo primo blocco.
   ========================================================================= */

/* --- 1. Variabili ------------------------------------------------------ */

:root{
  /* Colori */
  --blush:       #f7dde4;   /* rosa di fondo */
  --blush-deep:  #f0c6d3;   /* rosa piu' carico, angolo in basso */
  --mint:        #e6efe0;   /* verdino, angolo in alto */
  --cream:       #fbf7ec;   /* la card */
  --cream-edge:  #f0dde0;   /* bordi chiari */
  --plum:        #6d2b47;   /* testo principale */
  --plum-soft:   #a3798a;   /* testo secondario */
  --hot:         #d81b74;   /* accento: pulsante, numeri, nome */
  --hot-deep:    #ad1259;   /* fondo del gradiente dell'accento */
  --go:          #5fb37f;   /* verde del finto sblocco */
  --go-deep:     #3f8d60;
  --shadow:      rgba(140, 70, 95, .22);

  /* Tipografia */
  --display: "Fraunces", Georgia, serif;
  --body:    "Lora", Georgia, "Times New Roman", serif;

  /* Quanto e' alto lo schermo davvero. Sul telefono `100vh` e' la finestra
     **senza** la barra degli indirizzi, che non e' quella che si vede: bastava
     quello per lasciare una striscia scoperta in fondo alla discesa. `dvh`
     segue la finestra vera, barra compresa. */
  --schermo: 100vh;
}

@supports (height: 100dvh){
  :root{ --schermo: 100dvh; }
}

/* --- 2. Base ----------------------------------------------------------- */

*,
*::before,
*::after{ box-sizing: border-box; }

html{ -webkit-text-size-adjust: 100%; }

body{
  /* Alto quanto lo schermo e senza scorrimento: ci pensa assets/js/fit.js a
     rimpicciolire il pacco quanto basta perche' entri tutto. */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  margin: 0;
  padding: 26px 18px 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow-x: hidden;

  font-family: var(--body);
  color: var(--plum);
  background:
    repeating-linear-gradient(90deg, rgba(255,255,255,.35) 0 2px, rgba(255,255,255,0) 2px 9px),
    radial-gradient(120% 90% at 15% 0%, var(--mint) 0%, rgba(230,239,224,0) 48%),
    radial-gradient(110% 100% at 85% 100%, var(--blush-deep) 0%, var(--blush) 55%, #f6ece8 100%);
}

[hidden]{ display: none !important; }

/* Schermi cosi' bassi che rimpicciolire non basterebbe: si torna a scorrere. */
body.is-troppo-basso{ height: auto; min-height: 100vh; overflow: auto; }

:focus-visible{
  outline: 2.5px dashed var(--hot);
  outline-offset: 4px;
  border-radius: 16px;
}

/* --- 3. Impianto della pagina ------------------------------------------ */

.stage{
  width: 100%;
  max-width: 1090px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;

  /* --scala la scrive il JS: 1 quando ci sta tutto, meno quando serve. */
  transform: scale(var(--scala, 1));
  transform-origin: center center;
}

/* --------------------------------------------------------------------------
   Il pacco regalo visto dall'alto.

   Un solo rettangolo (il coperchio), due nastri incrociati sopra, la rosetta
   sull'incrocio e il bigliettino appoggiato sulla destra. La posizione dei
   nastri sta in due variabili: spostando quelle si muove anche la rosetta, e
   il bordo sinistro del biglietto si riadatta da solo.
   -------------------------------------------------------------------------- */

.gift{
  position: relative;
  width: 100%;

  --nastro-x: clamp(-287px, -27vw, -60px);   /* quanto il nastro verticale sta a sinistra */
  --nastro-y: 34%;                            /* dove passa il nastro orizzontale */
  --nastro-w: 77px;
  --rosetta-w: 336px;
  --parete: 50px;          /* quanto sono alte le pareti della scatola */
}

/* La carta da regalo: crema con la trama di cuoricini appena accennata. */
.gift-lid{
  position: relative;
  /* Il bordo sinistro lascia posto al nastro; sopra e sotto c'e' la carta in
     abbondanza, che e' quello che fa sembrare grande il pacco senza toccare
     la misura del bigliettino. */
  padding: 130px 62px 130px calc(50% + var(--nastro-x) + var(--nastro-w) / 2 + 48px);
  border-radius: 32px;
  border: 1px solid var(--cream-edge);

  background-color: var(--cream);
  background-image:
    url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2752%27%20height%3D%2752%27%3E%3Cg%20fill%3D%27%23d81b74%27%20opacity%3D%27.05%27%3E%3Cpath%20d%3D%27M13%2010c-1.6-2.1-4.8-1.3-4.8%201.3%200%202.3%203.1%204.1%204.8%205.5%201.7-1.4%204.8-3.2%204.8-5.5%200-2.6-3.2-3.4-4.8-1.3z%27%2F%3E%3Cpath%20d%3D%27M39%2036c-1.6-2.1-4.8-1.3-4.8%201.3%200%202.3%203.1%204.1%204.8%205.5%201.7-1.4%204.8-3.2%204.8-5.5%200-2.6-3.2-3.4-4.8-1.3z%27%2F%3E%3Ccircle%20cx%3D%2739%27%20cy%3D%2713%27%20r%3D%271.4%27%2F%3E%3Ccircle%20cx%3D%2713%27%20cy%3D%2739%27%20r%3D%271.4%27%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"),
    linear-gradient(160deg, #fffefa 0%, var(--cream) 40%, #f4ece0 100%);
  background-size: 52px 52px, 100% 100%;
  background-repeat: repeat, no-repeat;

  /* L'ombra a terra, la luce sul bordo alto e l'ombra su quello basso:
     e' questo che fa sembrare un coperchio spesso invece di un foglio. */
  box-shadow:
    0 34px 64px -28px var(--shadow),
    0 2px 0 rgba(255,255,255,.9) inset,
    0 -16px 26px -20px rgba(140, 70, 95, .45) inset;
}

/* L'interno della scatola. Sta sotto al coperchio e si scopre quando quello
   si alza. A pacco aperto smette di essere sovrapposto e prende lui la pagina
   (vedi .gift.is-open in opening.css).

   Le quattro pareti sono un gradiente conico con gli stacchi netti sulle
   diagonali: quattro spicchi di colore diverso che, con il fondo appoggiato
   sopra al centro, restano visibili come quattro trapezi. La luce arriva da
   sinistra in alto, quindi la parete in alto e' la piu' chiara e quella in
   basso la piu' scura. */
.gift-inside{
  position: absolute;
  inset: 0;

  /* Lo z-index serve a chiudere l'interno in un piano suo: senza, il fondo
     (che ha z-index 1) scavalcherebbe il coperchio e si vedrebbe fin da
     subito, invece che solo a scatola aperta. */
  z-index: 0;

  /* Le pareti in alto e in basso sono un po' piu' strette di quelle laterali:
     e' quello che si vede guardando dentro una scatola bassa e larga. */
  padding: calc(var(--parete) * .68) var(--parete);

  border-radius: 26px;
  background: conic-gradient(from 45deg,
    #e8d8ca 0deg 90deg,     /* parete destra */
    #dcc9b9 90deg 180deg,   /* parete in basso, la piu' in ombra */
    #f0e2d4 180deg 270deg,  /* parete sinistra */
    #f8eee1 270deg 360deg); /* parete in alto, la piu' illuminata */

  /* Il filo di luce sul bordo: e' lo spessore del cartone visto di taglio. */
  box-shadow:
    inset 0 0 0 2px rgba(255,255,255,.5),
    inset 0 3px 4px -2px rgba(255,255,255,.6),
    inset 0 -4px 8px -4px rgba(140, 70, 95, .3);
}

/* Le schiariture negli angoli, dove le pareti si incontrano e prendono luce.
   Stanno sotto al fondo, cosi' toccano solo le pareti e non il testo. */
.gift-inside::after{
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  background:
    radial-gradient(circle at 0% 0%,     rgba(255,255,255,.6) 0, rgba(255,255,255,0) 26%),
    radial-gradient(circle at 100% 0%,   rgba(255,255,255,.5) 0, rgba(255,255,255,0) 26%),
    radial-gradient(circle at 0% 100%,   rgba(255,255,255,.34) 0, rgba(255,255,255,0) 24%),
    radial-gradient(circle at 100% 100%, rgba(255,255,255,.3) 0, rgba(255,255,255,0) 24%);
}

/* Il fondo della scatola: appoggiato in mezzo alle pareti, con la loro ombra
   che gli cade addosso. Sopra e' piu' scura, perche' la parete alta e' quella
   che sporge di piu' verso la luce. */
.box-floor{
  position: relative;
  z-index: 1;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 34px 32px;
  border-radius: 8px;
  background: linear-gradient(170deg, #fbf4e8 0%, #fefaf1 38%, #fdf7ec 100%);
  box-shadow:
    inset 0 20px 24px -18px rgba(140, 70, 95, .55),
    inset 0 -12px 20px -16px rgba(140, 70, 95, .3),
    inset 16px 0 26px -20px rgba(140, 70, 95, .42),
    inset -16px 0 26px -20px rgba(140, 70, 95, .42),
    0 0 0 1px rgba(140, 70, 95, .1);
}

/* I fianchi del cartone, appena in ombra. */
.gift-lid::after{
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(90deg,
    rgba(140, 70, 95, .08) 0%,
    rgba(140, 70, 95, 0) 12%,
    rgba(140, 70, 95, 0) 88%,
    rgba(140, 70, 95, .08) 100%);
  pointer-events: none;
}

/* Il nastro, in quattro lembi che si incontrano al centro. Statici formano una
   croce identica a due nastri interi; a nodo sciolto si aprono verso l'esterno.
   Il chiaro in mezzo a ogni lembo e' il riflesso sul raso. */
.ribbon{
  position: absolute;
  z-index: 3;                      /* davanti al coperchio, finche' e' annodato */
  box-shadow: 0 0 14px -6px rgba(140, 70, 95, .65);
}

/* I due lembi verticali */
.ribbon-up,
.ribbon-down{
  left: 50%;
  width: var(--nastro-w);
  margin-left: var(--nastro-x);
  transform: translateX(-50%);
  background: linear-gradient(90deg,
    #a51156 0%, #cf1a6f 20%, #f79ac6 48%, #d81b74 76%, #9d0f52 100%);
}
.ribbon-up{ top: 0; height: calc(var(--nastro-y) + var(--nastro-w) / 2); }
.ribbon-down{ top: calc(var(--nastro-y) + var(--nastro-w) / 2); bottom: 0; }

/* I due lembi orizzontali */
.ribbon-left,
.ribbon-right{
  top: calc(var(--nastro-y) + var(--nastro-w) / 2);
  height: var(--nastro-w);
  transform: translateY(-50%);
  background: linear-gradient(180deg,
    #a51156 0%, #cf1a6f 20%, #f79ac6 48%, #d81b74 76%, #9d0f52 100%);
}
.ribbon-left{ left: 0; width: calc(50% + var(--nastro-x) + var(--nastro-w) / 2); }
.ribbon-right{ left: calc(50% + var(--nastro-x) - var(--nastro-w) / 2); right: 0; }


/* Il nastro sciolto: quattro pezzi che spuntano dai bordi della scatola.
   Restano invisibili finche' il nodo tiene. Sono dietro a tutto (z-index 0),
   quindi si vede solo la parte che sporge oltre il pacco.
   Le misure vengono dalla larghezza del nastro: il disegno e' largo 170 unita'
   con la fascia di 58, quindi 170/58 = 2,93. */
.loose{
  position: absolute;
  z-index: 0;
  width: calc(var(--nastro-w) * 2.93);
  height: calc(var(--nastro-w) * 2.93);
  opacity: 0;
  pointer-events: none;
  filter: drop-shadow(0 6px 8px rgba(140, 70, 95, .3));
}

.loose-up,
.loose-down{
  left: 50%;
  margin-left: var(--nastro-x);
  transform: translateX(-50%);
}
.loose-up{ bottom: calc(100% - 40px); }
.loose-down{ top: calc(100% - 40px); }

.loose-left,
.loose-right{
  top: calc(var(--nastro-y) + var(--nastro-w) / 2);
  transform: translateY(-50%);
}
.loose-left{ right: calc(100% - 40px); }
.loose-right{ left: calc(100% - 40px); }

/* La rosetta, appoggiata esattamente sull'incrocio dei due nastri. */
.gift-bow{
  position: absolute;
  z-index: 5;
  left: 50%;
  top: var(--nastro-y);
  width: var(--rosetta-w);
  margin-left: var(--nastro-x);
  transform: translate(-50%, calc(-50% + var(--nastro-w) / 2));
  filter: drop-shadow(0 10px 12px rgba(140, 70, 95, .34));
}

/* Il bigliettino di auguri: carta piu' chiara, appena storta, con la sua ombra.
   La larghezza e' fissa: il pacco puo' crescere quanto vuole, lui resta uguale
   e si appoggia al bordo destro. */
.card{
  position: relative;
  z-index: 4;
  width: min(514px, 100%);
  margin-left: auto;
  padding: 24px 24px 22px;
  text-align: center;
  background: linear-gradient(170deg, #fffefb 0%, #fffcf4 100%);
  border: 1px solid rgba(240, 221, 224, .85);
  border-radius: 5px;
  transform: rotate(-1.1deg);
  box-shadow:
    0 16px 30px -16px rgba(140, 70, 95, .5),
    0 2px 6px -3px rgba(140, 70, 95, .25);
}

/* Lo scotch che tiene il biglietto: due strisce sugli angoli in alto. */
.tape{
  position: absolute;
  top: -11px;
  width: 76px;
  height: 22px;
  pointer-events: none;

  /* Nastro adesivo: quasi trasparente, con un riflesso storto che lo attraversa
     e i bordi appena piu' marcati, come la vera plastica lucida. */
  background: linear-gradient(118deg,
    rgba(255,255,255,.5) 0%,
    rgba(255,255,255,.14) 40%,
    rgba(255,255,255,.46) 72%,
    rgba(255,255,255,.2) 100%);
  border-top: 1px solid rgba(255,255,255,.55);
  border-bottom: 1px solid rgba(140, 70, 95, .1);
  border-radius: 1px;
  box-shadow: 0 1px 3px rgba(140, 70, 95, .16);
}
.tape-left{ left: -20px; transform: rotate(-40deg); }
.tape-right{ right: -20px; transform: rotate(40deg); }

/* Una schermata per volta: solo quella con .is-visible sta a schermo. */
.screen{
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 15px;
}
/* Niente `both` sul riempimento: l'animazione finisce e non lascia traccia.
   Se restasse, la schermata continuerebbe ad avere una trasformazione (anche
   se identica a niente), e una trasformazione fa da gabbia a tutto quello che
   ha dentro: il "no" con `position: fixed` conterebbe le sue coordinate da qui
   invece che dallo schermo, e non potrebbe scappare fuori dal bigliettino.
   Il fotogramma finale e' identico allo stato normale, quindi non serve. */
.screen.is-visible{
  display: flex;
  animation: rise .5s cubic-bezier(.2, .7, .3, 1);
}

@keyframes rise{
  from{ opacity: 0; transform: translateY(14px); }
  to  { opacity: 1; transform: none; }
}

/* --- 4. Tipografia ----------------------------------------------------- */

.eyebrow{
  margin: 0;
  font-family: var(--display);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--plum-soft);
}

h1{
  margin: 0;
  font-family: var(--display);
  font-size: clamp(23px, 4.6vw, 36px);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.015em;
  text-wrap: balance;
}
h1 .name{ color: var(--hot); }

/* Le due righe sotto il titolo: la spiegazione e la battuta. */
.lines{
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
}
.note{
  /* Larghezza tagliata sulla prima riga, che cosi' sta tutta su un rigo:
     sotto i 400px va a capo da sola, e text-wrap la spezza in parti uguali. */
  max-width: 350px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
.note > p{
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--plum-soft);
  text-wrap: balance;
}
/* La seconda riga porta l'informazione che conta: un filo piu' marcata. */
.note > .note-time{
  color: var(--plum);
  font-weight: 500;
}
.sub{
  margin: 0;
  font-size: 15.5px;
  font-style: italic;
  color: var(--plum-soft);
}

.hearts{
  margin: 0;
  font-size: 16px;
  letter-spacing: 8px;
  color: var(--hot);
}

.foot{
  margin: 0;
  font-size: 13.5px;
  letter-spacing: .05em;
  color: var(--plum-soft);
}

/* --- 5. Selettore di lingua -------------------------------------------- */

.lang{
  /* Nell'angolo in alto a destra del coperchio, dentro la sagoma del pacco. */
  position: absolute;
  top: 20px;
  right: 22px;
  z-index: 5;
  transition: opacity .3s ease;

  display: flex;
  gap: 2px;
  padding: 3px;
  background: rgba(255,255,255,.6);
  border: 1px solid var(--cream-edge);
  border-radius: 999px;
  box-shadow: 0 6px 14px -10px var(--shadow);
}

.lang button{
  padding: 6px 13px;
  border: none;
  border-radius: 999px;
  background: none;
  cursor: pointer;

  font-family: var(--display);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--plum-soft);

  transition: background .2s ease, color .2s ease;
}
.lang button[aria-pressed="true"]{ background: var(--hot); color: #fff; }
.lang button:not([aria-pressed="true"]):hover{ color: var(--plum); }

/* Durante l'apertura il coperchio vola via: il selettore si toglie di mezzo. */
.gift.is-opening .lang{ opacity: 0; pointer-events: none; }

/* --- 6. Conto alla rovescia -------------------------------------------- */

.count{
  width: 100%;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 9px;
}

.unit{
  padding: 13px 4px 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  background: #fffdf7;
  border: 1px solid var(--cream-edge);
  border-radius: 18px;
  box-shadow: 0 2px 0 rgba(255,255,255,.9) inset;
}

.unit b{
  font-family: var(--display);
  font-size: clamp(25px, 7vw, 31px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--hot);
  font-variant-numeric: tabular-nums;   /* le cifre non ballano mentre scorrono */
}

.unit span{
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--plum-soft);
}

.rule{
  width: 64px;
  height: 1px;
  margin: 2px 0 0;
  border: none;
  background: var(--cream-edge);
}

/* --- 7. Pulsante ------------------------------------------------------- */

.btn{
  padding: 15px 46px;
  border: none;
  border-radius: 999px;
  cursor: pointer;

  font-family: var(--display);
  font-size: 18px;
  font-weight: 600;
  color: #fff;
  background: linear-gradient(180deg, var(--hot), var(--hot-deep));
  box-shadow: 0 12px 22px -10px rgba(173, 18, 89, .75);

  transition: transform .18s ease, box-shadow .18s ease;
}
.btn:hover{ transform: translateY(-2px); box-shadow: 0 16px 26px -10px rgba(173, 18, 89, .8); }
.btn:active{ transform: translateY(0) scale(.97); }

/* Dall'ottavo tentativo il pulsante si spazientisce. */
.btn.is-tired{ animation: wobble .5s ease both; }

@keyframes wobble{
  0%, 100%{ transform: rotate(0); }
  25%     { transform: rotate(-2.5deg); }
  75%     { transform: rotate(2.5deg); }
}

/* Il finto sblocco (vedi FAKE_UNLOCK_AT in config.js).
   Va dichiarato dopo .is-tired: a parita' di peso vince l'ultima regola,
   quindi qui il respiro sostituisce il tremolio. */
.btn.is-fake{
  background: linear-gradient(180deg, var(--go), var(--go-deep));
  box-shadow: 0 12px 24px -10px rgba(63, 141, 96, .75);
  animation: breathe 1.7s ease-in-out infinite;
}

@keyframes breathe{
  0%, 100%{ transform: scale(1); }
  50%     { transform: scale(1.045); }
}

/* --- 8. Risposte del pulsante ------------------------------------------ */

.action{
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 11px;
}

/* Lo spazio per la risposta e' sempre alto due righe, anche quando la frase
   ne occupa una sola o non c'e' ancora nessuna frase: cosi' la card resta
   ferma invece di alzarsi e abbassarsi a ogni risposta. Il calcolo segue le
   due variabili qui sotto, quindi resta giusto anche cambiando il corpo. */
.retort{
  --retort-size: 15.5px;
  --retort-leading: 1.45;

  margin: 0;
  min-height: calc(var(--retort-size) * var(--retort-leading) * 2);
  max-width: 31ch;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--retort-size);
  line-height: var(--retort-leading);
  color: var(--plum);
}
.retort.pop{ animation: pop .34s cubic-bezier(.2, 1.5, .4, 1) both; }

@keyframes pop{
  from{ opacity: 0; transform: scale(.94) translateY(6px); }
  to  { opacity: 1; transform: none; }
}

.tally{
  margin: 0;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--plum-soft);
  font-variant-numeric: tabular-nums;
  opacity: 0;
  transition: opacity .4s ease;
}
.tally.is-visible{ opacity: .85; }

/* --- 9. Dentro la scatola ----------------------------------------------- */

/* Il fondo della scatola diventa lo sfondo di tutto il sito: un rosa solo, da
   bordo a bordo. Copre lo schermo per intero, quindi non sta dentro allo
   .stage (che e' rimpicciolito per far entrare il pacco). Sopra ci stanno il
   festone, i palloncini che salgono e, al centro, il rettangolo chiaro con
   tutto quello che si legge e si tocca. */
.inside{
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 116px 20px 30px;
  overflow: hidden;

  /* Di quanto la corda del festone fa la pancia. La usano sia la corda che
     le bandierine, cosi' restano appese al punto giusto. */
  --sag: clamp(18px, 5vh, 42px);
  background:
    radial-gradient(85% 65% at 22% 4%, #fbdce8 0%, rgba(251,220,232,0) 58%),
    linear-gradient(168deg, #f6c8dc 0%, #f1b6d0 55%, #f6c8dc 100%);
}

/* Il rettangolo chiaro al centro. */
.column{
  position: relative;
  z-index: 2;
  width: min(520px, 90%);
  max-height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 22px 24px;
  overflow-y: auto;
  text-align: center;
  border-radius: 4px;
  background:
    radial-gradient(120% 80% at 30% 10%, #fffdf6 0%, rgba(255,253,246,0) 62%),
    linear-gradient(168deg, #fdf8ee 0%, #fbf4e8 55%, #f6eddf 100%);
  border: 1px solid rgba(240, 221, 224, .9);
  box-shadow: 0 24px 50px -22px rgba(140, 70, 95, .55);
}

/* --- Il festone ---------------------------------------------------------
   Le bandierine le costruisce il JS, una per lettera, prendendo la scritta
   dalla lingua scelta. Ognuna scende di quanto scende la corda nel suo punto
   e si inclina come la corda: e' il JS a calcolarlo e a scriverlo nelle
   variabili --k (quanto scende, da 0 a 1) e --r (di quanto si inclina). */

/* Il tendone occupa tutta la larghezza, ma la corda deve stare appesa solo
   dove ci sono le bandierine: per questo dentro c'e' .string, che e' larga
   quanto la scritta, e la corda ci sta dentro. */
/* Coperto lo schermo di cuori, il festone dietro non ha piu' senso: si toglie
   di mezzo, e quando i cuori verranno spostati sotto ci sara' il rosa pulito. */
.inside.senza-festone .bunting{ display: none; }

.bunting{
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  display: flex;
  justify-content: center;
  padding-top: clamp(8px, 1.6vh, 14px);
}

.string{
  position: relative;
  max-width: 96%;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 2px;
}

/* La corda: la stessa identica parabola che il JS fa seguire alle bandierine.
   Il disegno e' alto il doppio della pancia e la curva tocca il fondo a meta',
   quindi nel punto x la corda scende di 4 * --sag * t * (1 - t): la formula
   che il JS usa per --k, cosi' passa esatta sulla punta di ogni triangolo.

   Larghezza: `width` e non `left` + `right`. Un SVG e' un elemento sostituito,
   e con la larghezza automatica si tiene quella sua intrinseca ignorando
   `right`: era per questo che la corda usciva corta, un archetto in alto a
   sinistra invece di tutta la fila. */
.rope{
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: calc(var(--sag) * 2);
  overflow: visible;         /* le due estremita' non vanno tagliate */
  z-index: -1;
  pointer-events: none;
}

.flag{
  width: clamp(24px, 5.2vh, 46px);
  height: clamp(34px, 8.4vh, 68px);
  display: flex;
  justify-content: center;
  padding-top: clamp(3px, .9vh, 8px);
  clip-path: polygon(0 0, 100% 0, 50% 100%);

  /* Appese qualche pixel sotto la corda, se no la coprirebbero tutta. */
  margin-top: 5px;
  transform-origin: top center;
  transform: translateY(calc(var(--sag) * var(--k, 0))) rotate(calc(var(--r, 0) * 1deg));

  font-family: var(--display);
  font-size: clamp(13px, 2.7vh, 23px);
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 3px rgba(140, 70, 95, .45);
}
.flag:nth-child(3n)  { background: #e0257f; }
.flag:nth-child(3n+1){ background: #f290c0; }
.flag:nth-child(3n+2){ background: #c4175f; }
.flag.gap{ background: none; width: clamp(10px, 2.4vh, 20px); }

/* --- I palloncini -------------------------------------------------------
   Salgono in continuazione dentro alla propria fascia, ognuno con la sua
   velocita' e il suo ritardo, cosi' non vanno mai in fila.

   Le misure diverse non sono un vezzo: sono la distanza. Un palloncino grande
   e' vicino, quindi sale piu' in fretta, ha il colore piu' pieno e — quando ne
   incrocia uno piccolo — gli passa davanti. Quest'ultima cosa e' lo `z-index`
   in --z, che vale quanto la larghezza. Lo `z-index: 0` qui sotto serve a
   tenere quella gara chiusa dentro ai palloncini: se no i piu' grandi
   finirebbero anche davanti al festone e al bigliettino. */

.balloons{
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.balloon{
  position: absolute;
  left: var(--x);
  bottom: -60px;
  width: var(--w);
  height: calc(var(--w) * 1.24);
  border-radius: 50% 50% 46% 46%;
  background:
    radial-gradient(circle at 32% 26%, rgba(255,255,255,.75) 0%, rgba(255,255,255,0) 46%),
    var(--c);
  opacity: var(--o, 1);      /* i lontani sono piu' slavati */
  z-index: var(--z, 1);      /* ...e passano dietro ai vicini */
  animation: sale var(--t) var(--d) linear infinite;
}

/* il filo */
.balloon::after{
  content: "";
  position: absolute;
  left: 50%;
  top: 100%;
  width: 1px;
  height: calc(var(--w) * .8);
  background: linear-gradient(180deg, rgba(140,70,95,.4), rgba(140,70,95,0));
}

@keyframes sale{
  from{ transform: translateY(0) translateX(0) rotate(-3deg); }
  50% { transform: translateY(-50vh) translateX(10px) rotate(3deg); }
  to  { transform: translateY(-100vh) translateX(0) rotate(-3deg); }
}

/* La pagina dentro la scatola. Tutto su un asse solo, centrato, con la stessa
   aria fra un pezzo e l'altro: e' una pagina che si guarda, non si legge. */
.inside .screen{
  max-width: 460px;
  gap: clamp(10px, 1.7vh, 18px);
  margin: auto;
}

.check-title{
  margin: 0;
  font-family: var(--display);
  font-size: clamp(24px, 4.4vh, 31px);
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--plum);
}

.check-text{
  margin: 0;
  max-width: 40ch;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--plum-soft);
  text-wrap: balance;
}

/* Il riquadro e' tondo: e' la forma piu' simmetrica che ci sia, e somiglia al
   mirino di un riconoscimento facciale. Dentro ci sta prima il disegno della
   fotocamera, poi il video vero. */
.viewer{
  position: relative;
  height: min(286px, 34vh);
  width: auto;
  aspect-ratio: 3 / 4;
  display: grid;
  place-items: center;
  border-radius: 22px;
  background: linear-gradient(168deg, #fffdf6 0%, #f8f0e3 100%);
  overflow: hidden;
  box-shadow:
    inset 0 0 30px -10px rgba(140, 70, 95, .25),
    0 0 0 2px var(--cream-edge),
    0 0 0 10px rgba(255, 255, 255, .55),
    0 0 0 11px rgba(240, 221, 224, .8),
    0 22px 38px -22px rgba(140, 70, 95, .5);
}

/* Il contorno del viso. Rosso finche' e' vuoto, verde quando ci si mette
   dentro qualcuno: il colore fa da istruzione, senza bisogno di spiegarlo.

   Compare e sparisce con una classe sul riquadro e non con l'attributo hidden:
   quello vale solo per gli elementi HTML, e su un <svg> non ha alcun effetto. */
.face-guide{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: none;
  pointer-events: none;
}

.viewer.is-live .face-guide{ display: block; }

.face-guide path{
  fill: rgba(214, 58, 66, .17);
  stroke: rgba(214, 58, 66, .85);
  stroke-width: 3;
  stroke-dasharray: 13 9;
  transition: fill .4s ease, stroke .4s ease;
}

.viewer.is-ok .face-guide path{
  fill: rgba(40, 150, 92, .2);
  stroke: rgba(40, 150, 92, .92);
  stroke-dasharray: none;
}

.camera{
  width: 62%;
  height: auto;
  filter: drop-shadow(0 16px 22px rgba(140, 70, 95, .26));
}

/* Il video e' specchiato: e' come ci si aspetta di vedersi. */
.cam{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scaleX(-1);
}

.viewer{ overflow: hidden; }
.camera,
.cam,
.hold{ border-radius: 22px; }

/* --- L'ultima domanda --------------------------------------------------- */

/* L'altezza non e' quella dei pulsanti: e' quella del "si" **da grande**.
   Cresce a ogni rifiuto fino a una volta e mezza abbondante, e uscendo dalla
   sua riga finirebbe appiccicato al bordo del bigliettino. */
.choices{
  position: relative;
  width: 100%;
  min-height: 104px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
}

/* Il "no" scappa: appena il cursore si avvicina salta da un'altra parte.

   Sta fuori dall'impaginazione fin da subito — `position: fixed`, con
   `left`/`top` scritti dal JS appena la schermata compare. Non e' un
   dettaglio: se diventasse fisso solo al primo salto, quel primo salto
   sarebbe un teletrasporto — da `auto` a un valore non si puo' animare — e
   solo dal secondo in poi lo si vedrebbe correre. Il posto che lascerebbe
   vuoto nella riga lo tiene .posto-no, che ha la stessa scatola. */
#no, .posto-no{
  padding: 13px 30px;
  border: none;
  border-radius: 999px;
  cursor: pointer;

  /* Su una riga sola, sempre. Staccato dall'impaginazione la larghezza gliela
     darebbe il posto in cui si trova, la scusa andrebbe a capo e il pulsante
     diventerebbe piu' alto di quanto e' stato misurato: risultato, ogni tanto
     mezzo fuori dal bordo di sotto. */
  white-space: nowrap;

  font-family: var(--display);
  font-size: 16px;
  font-weight: 600;
  color: var(--plum);

  /* Colore suo, non trasparenza: deve restare identico anche quando scappa
     fuori dal bigliettino e si ritrova il rosa dietro. Prima qui c'era un
     `var(--rose)` che fra le variabili non esiste: bastava quello a rendere
     invalido tutto lo sfondo, e il pulsante restava trasparente. */
  background: linear-gradient(180deg, #fffdf7 0%, #f6ebdd 100%);
  border: 1px solid var(--cream-edge);
  box-shadow: 0 10px 20px -12px rgba(140, 70, 95, .6);
}

/* La corsa si vede — scappa, non si teletrasporta — ma dura meno di un quarto
   di secondo e riparte a ogni mossa del cursore: guardarlo scappare e' facile,
   raggiungerlo no.
   0,24s e' la stessa durata che il JS conosce come CORSA: cambiando qui,
   cambiare anche li'. */
#no{
  position: fixed;
  z-index: 30;
  margin: 0;
  transition: left .24s cubic-bezier(.25, .9, .3, 1),
              top  .24s cubic-bezier(.25, .9, .3, 1);
}

/* Entra insieme al bigliettino, con la stessa animazione della schermata:
   scivola dentro con lui invece di comparirci sopra. */
#no.entra{
  animation: rise .5s cubic-bezier(.2, .7, .3, 1);
}

/* Il segnaposto: stessa scatola e stessa scritta, ma invisibile e
   intoccabile. Serve a tenere larga la riga finche' il "no" e' al suo posto,
   se no il "si" partirebbe gia' spostato verso il centro. */
.posto-no{
  visibility: hidden;
  pointer-events: none;
  overflow: hidden;
  white-space: nowrap;

  /* La larghezza gliela scrive il JS in pixel appena il "no" si accende: da
     `auto` non si potrebbe animare, e la chiusura si vedrebbe come uno
     scatto. */
  transition: width .34s cubic-bezier(.3, .9, .3, 1),
              padding .34s cubic-bezier(.3, .9, .3, 1),
              margin .34s cubic-bezier(.3, .9, .3, 1);
}

/* Scappato il "no", il suo posto si richiude e il "si" scivola al centro.
   Il margine negativo serve a mangiarsi anche lo spazio fra i due. */
.posto-no.is-via{
  width: 0 !important;
  padding-left: 0;
  padding-right: 0;
  margin-left: -16px;
}

#yes{
  transition: transform .3s cubic-bezier(.3, 1.4, .5, 1), box-shadow .3s ease;
  transform-origin: center;
}

/* --- La scelta del regalo ------------------------------------------------
   Tre righe larghe quanto il bigliettino invece di tre colonne: le frasi sono
   lunghe, e in colonna diventerebbero illeggibili prima ancora del telefono.
   Non sono numerate perche' non sono dei passi: sono tre strade alternative,
   e un numero suggerirebbe un ordine che non c'e'. */

.scelte{
  margin: 0;
  padding: 0;
  list-style: none;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.pick{
  width: 100%;
  padding: 13px 18px;
  cursor: pointer;

  font-family: var(--body);
  font-size: 14.5px;
  line-height: 1.35;
  color: var(--plum);
  text-align: center;

  background: linear-gradient(180deg, #fffdf7 0%, #f8efe2 100%);
  border: 1px solid var(--cream-edge);
  border-radius: 6px;
  box-shadow: 0 8px 16px -14px rgba(140, 70, 95, .8);

  /* Il colore cambia di colpo: e' la risposta al dito, e una risposta che
     sfuma sembra un ritardo. Si ammorbidiscono solo il sollevarsi e l'ombra. */
  transition: transform .18s ease, box-shadow .18s ease;
}

.pick:hover{
  transform: translateY(-2px);
  border-color: var(--hot);
  box-shadow: 0 12px 22px -14px rgba(140, 70, 95, .9);
}

/* Segnato: uno si accende, ma finche' non si conferma si puo' cambiare idea. */
.pick.is-chosen{
  color: #fff;
  background: linear-gradient(180deg, var(--hot) 0%, var(--hot-deep) 100%);
  border-color: var(--hot-deep);
  transform: translateY(-2px);
}

.scelte.is-done .pick{ cursor: default; }
.scelte.is-done .pick:not(.is-chosen){ opacity: .42; }
.scelte.is-done .pick:hover{ transform: none; box-shadow: 0 8px 16px -14px rgba(140, 70, 95, .8); }
.scelte.is-done .pick.is-chosen:hover{ transform: translateY(-2px); }

/* Finche' non c'e' niente da dire, la riga non tiene il posto. `.retort` ha
   un'altezza minima di due righe — serve altrove, perche' li' le frasi
   cambiano e il rettangolo non deve ballare — ma qui lasciava un buco sotto al
   pulsante e mandava il bigliettino fuori squadra. */
/* Un filo d'aria in fondo: senza, l'occhiello in cima respira e il pulsante
   di conferma resta appiccicato al bordo di sotto. */
#scelta{ padding-bottom: 10px; }

/* Fatto il loro lavoro, questi pulsanti spariscono ma **non lasciano il
   posto**: se lo togliessero davvero il bigliettino si accorcerebbe di colpo e
   lo si vedrebbe saltare — la conferma proprio mentre si guarda la scelta
   appena fatta, l'accensione della fotocamera proprio mentre ci si sta
   guardando dentro. */
#conferma.is-done,
#cam-start.is-done{ visibility: hidden; }

/* Il pulsante di conferma resta li' spento finche' non c'e' niente da
   confermare: si vede che il passo esiste, e si capisce che manca la scelta. */
#conferma:disabled{
  cursor: default;
  opacity: .38;
  box-shadow: none;
  transform: none;
}

/* Il conto alla rovescia del "resta ferma". Niente velo scuro sopra al video:
   il numero deve stare sul viso senza nasconderlo. */
.hold{
  position: absolute;
  inset: auto 0 10px 0;
  display: grid;
  place-items: center;
  pointer-events: none;
}
.hold span{
  min-width: 62px;
  padding: 4px 0 7px;
  border-radius: 999px;
  background: rgba(45, 15, 30, .45);
  font-family: var(--display);
  font-size: 38px;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 2px 10px rgba(45, 15, 30, .5);
  font-variant-numeric: tabular-nums;
}

.linky{
  padding: 4px 8px;
  border: none;
  background: none;
  cursor: pointer;
  font-family: var(--body);
  font-size: 13px;
  color: var(--plum-soft);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.linky:hover{ color: var(--hot); }


/* --- 10. Schermata finale ----------------------------------------------- */

.tile{
  width: 106px;
  height: 106px;
  display: grid;
  place-items: center;
  font-size: 54px;
  line-height: 1;
  background: linear-gradient(150deg, #dfe9d8, #f5d7de);
  border: 1px solid rgba(255,255,255,.85);
  border-radius: 28px;
  box-shadow: 0 14px 26px -14px var(--shadow);
}

/* --- 11. Effetti ------------------------------------------------------- */

/* Un petalo per volta, creato e rimosso da assets/js/effects.js.
   La misura esatta la decide il JS, entro un intervallo, cosi' la pioggia
   non sembra fatta di ritagli tutti uguali. */
.petal{
  position: fixed;
  top: -48px;
  z-index: 5;
  font-size: 27px;
  pointer-events: none;
  animation: fall linear forwards;
}

@keyframes fall{
  to{ transform: translateY(112vh) rotate(420deg); opacity: 0; }
}

/* L'esplosione di cuori. Il disegno lo fa un canvas (assets/js/effects.js):
   qui basta metterlo davanti a tutto e renderlo trasparente ai click, perche'
   quello che sta sotto — i pulsanti della scelta del regalo — deve continuare
   a funzionare anche mentre i cuori lo coprono. Lo spostamento lo gestisce il
   JS ascoltando il documento. */
.cuori{
  position: fixed;
  inset: 0;
  z-index: 40;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* La riga che spiega come toglierseli di torno. Sparisce alla prima spinta. */
.cuori-aiuto{
  position: fixed;
  z-index: 41;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  margin: 0;
  padding: 9px 18px;

  font-family: var(--body);
  font-size: 15px;
  font-style: italic;
  white-space: nowrap;
  color: var(--plum);

  background: rgba(255, 253, 247, .92);
  border-radius: 999px;
  box-shadow: 0 10px 24px -16px rgba(140, 70, 95, .9);

  animation: aiuto-appare .6s 1.4s ease-out both;
}

@keyframes aiuto-appare{
  from{ opacity: 0; transform: translateX(-50%) translateY(8px); }
  to  { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* Mentre si spingono i cuori non si deve selezionare mezza pagina per sbaglio. */
body.sta-spostando{ user-select: none; -webkit-user-select: none; }

/* --- 11 bis. Il fondo del mare -----------------------------------------
   Si arriva qui scegliendo il primo regalo, l'esperienza.

   La transizione e' una discesa vera, non una dissolvenza: dal fondo dello
   schermo sale una massa di bolle cosi' fitta da non lasciar vedere niente
   (assets/js/effects.js), e al riparo di quella tenda la pagina scorre verso
   il basso — la festa se ne va per di sopra, e da sotto arriva prima la
   colonna d'acqua e poi il paese. Quando le bolle si diradano siamo gia'
   arrivati.

   Il movimento e' uno solo: due elementi che scorrono alla stessa velocita'
   e con la stessa andatura, come le due meta' di una pellicola. */

/* La festa se ne va per di sopra, e con lei i cuori: sono roba sua, e restano
   fermi dove stanno mentre le bolle ci passano davanti. Se il loro velo
   restasse fermo sullo schermo, diradate le bolle se li ritroverebbe appesi
   sopra al fondo del mare.

   L'andatura e' quasi una linea retta, appena addolcita ai due capi: a un
   quarto del tempo si e' fatto un quinto di strada, a meta' tempo sei di
   dieci. Prima la curva era una S ripida, e il primo mezzo secondo non si
   muoveva niente: allungare la discesa allungava solo l'attesa, e sembrava che
   il sito si fosse impuntato invece che stesse scendendo. */
body.in-discesa .inside,
body.in-discesa canvas.cuori{
  animation: discesa-via var(--discesa, 2.4s) cubic-bezier(.35, .12, .5, .92) both;
}

@keyframes discesa-via{
  to{ transform: translateY(calc(var(--schermo, 100vh) * -2)); }
}

.mare{
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  height: calc(var(--schermo) * 2);   /* sopra l'acqua, sotto il paese */
  z-index: 60;

  /* Parte appena sotto al bordo dello schermo e sale di due schermate: a meta'
     strada si e' in mezzo all'acqua, alla fine si e' arrivati. */
  transform: translateY(var(--schermo));
  animation: discesa-arriva var(--discesa, 2.4s) cubic-bezier(.35, .12, .5, .92) both;
}

@keyframes discesa-arriva{
  from{ transform: translateY(var(--schermo)); }
  to  { transform: translateY(calc(var(--schermo) * -1)); }
}

/* La colonna d'acqua: l'intermezzo fra le due pagine. Due colori e basta, dal
   rosa acceso in cima all'azzurro in fondo. */
.colonna{
  height: var(--schermo, 100vh);
  background: linear-gradient(180deg, #fc3b64 0%, #2bc9df 100%);
}

.fondo{
  position: relative;
  height: var(--schermo, 100vh);
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow: hidden;
  background: #46f1d5;
}

.fondale{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center bottom;
}

/* Su uno schermo alto e stretto la foto, tagliata per riempire, mostrerebbe
   solo la casa in mezzo: il paese sparirebbe. Allora la si fa entrare tutta,
   appoggiata in basso, e l'acqua sopra la continua — il colore di fondo e'
   quello della sua prima riga, quindi l'attacco non si vede. */
@media (max-aspect-ratio: 5 / 4){
  .fondale{ object-fit: contain; }
  .fondo{ background: linear-gradient(180deg, #2fd6c9 0%, #46f1d5 100%); }
}

/* La tenda di bolle: sopra a tutto, anche alla discesa che deve nascondere. */
.tenda-bolle{
  position: fixed;
  inset: 0;
  z-index: 70;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* La domanda e la data. Stanno in alto, nell'acqua libera sopra ai tetti del
   paese, e arrivano quando la discesa e' finita e le bolle si sono gia'
   diradate. Un soffio dopo la fine, qualunque durata abbia la discesa. */
.mare-scritte{
  position: relative;
  z-index: 2;
  margin: max(18px, 10vh) 0 0;
  padding: 0 22px;
  width: 100%;
  max-width: 1000px;
  text-align: center;

  animation: titolo-emerge .8s calc(var(--discesa, 2.4s) + .2s) cubic-bezier(.2, 1.5, .4, 1) both;
}

/* Gialla con il bordo scuro, come i cartelli dei cartoni. La misura e' la piu'
   grande che regge una frase lunga senza spezzarla in cinque righe: e' una
   domanda da leggere, non piu' una parola sola da urlare. */
.mare-titolo{
  margin: 0;

  font-family: var(--display);
  font-size: clamp(27px, 5.4vw, 64px);
  font-weight: 700;
  letter-spacing: .01em;
  line-height: 1.06;
  text-wrap: balance;
  color: #ffd83d;
  -webkit-text-stroke: clamp(1.5px, .32vw, 3.5px) #0a3f63;
  paint-order: stroke fill;
  text-shadow: 0 8px 0 rgba(10, 63, 99, .3);
}

/* La data: piccola e defilata, un asterisco in fondo alla domanda. */
.mare-data{
  margin: clamp(10px, 1.6vh, 18px) 0 0;

  font-family: var(--body);
  font-size: clamp(13px, 1.6vw, 20px);
  font-style: italic;
  color: #eafcff;
  text-shadow: 0 2px 0 rgba(10, 63, 99, .45);
}

@keyframes titolo-emerge{
  from{ opacity: 0; transform: translateY(26px) scale(.82); }
  to  { opacity: 1; transform: none; }
}

/* --- I biglietti in fondo al mare ---------------------------------------
   Due, a ventaglio: quello dietro e' solo la sua sagoma, e serve a far capire
   che ce ne sono due. Sono disegnati, non una fotografia dello schermo: cosi'
   restano nitidi a qualunque misura, cambiano lingua insieme al resto e i
   bordi si possono fare da biglietto vero. */

.biglietti{
  /* Appoggiati sulla sabbia, fra la porta della casa di pietra e la strada.
     Si misura dal basso perche' la foto e' ancorata li': qualunque sia la
     forma dello schermo, la strada resta l'ultimo decimo dell'immagine e la
     sabbia quello appena sopra. */
  position: absolute;
  left: 50%;
  bottom: 19.5%;
  transform: translateX(-50%);
  z-index: 2;
  animation: biglietti-arrivano .8s calc(var(--discesa, 2.4s) + .55s) cubic-bezier(.2, 1.4, .4, 1) both;
}

/* Il `translateX(-50%)` va ripetuto in tutti e due i fotogrammi: e' quello che
   centra i biglietti, e un'animazione che scrive `transform` se lo mangia. */
@keyframes biglietti-arrivano{
  from{ opacity: 0; transform: translateX(-50%) translateY(20px) scale(.92); }
  to  { opacity: 1; transform: translateX(-50%); }
}

.biglietto{
  width: min(478px, 88vw);
  display: flex;
  align-items: stretch;
  border-radius: 16px;
  overflow: hidden;

  color: #47122c;
  background: linear-gradient(180deg, #fde4ef 0%, #f9cfe2 100%);

  /* L'ombra e' quella di un cartoncino appoggiato sull'acqua. */
  box-shadow:
    0 22px 34px -20px rgba(4, 45, 70, .75),
    0 2px 0 rgba(255,255,255,.8) inset;

  /* Inclinati tutti e due dalla stessa parte, come due biglietti tenuti in
     mano: quello davanti un po' meno storto, quello dietro che spunta in
     basso a destra. */
  transform: rotate(-5deg);
}

/* Quello dietro: stesso biglietto, appena piu' storto, che spunta in basso —
   e' la piega che fanno due biglietti tenuti insieme. Un filo piu' scuro, se
   no i due si confonderebbero in una macchia sola. */
.biglietto-dietro{
  position: absolute;
  inset: 0;
  transform: rotate(-13deg) translate(16px, 48px);
  background: linear-gradient(180deg, #f6c6dd 0%, #eaadca 100%);
  box-shadow: 0 16px 26px -16px rgba(4, 45, 70, .8);
}

.biglietto-dietro .biglietto-tallone{
  background: linear-gradient(180deg, #f0bad4 0%, #e5a2c2 100%);
}

.biglietto-corpo{
  flex: 1;
  padding: 15px 18px;
  min-width: 0;
}

.biglietto-titolo{
  margin: 0 0 9px;
  font-family: var(--display);
  font-size: clamp(16px, 1.62vw, 21px);
  font-weight: 700;
  line-height: 1.18;
}

.biglietto-riga{
  margin: 0;
  display: flex;
  align-items: center;
  gap: 7px;

  font-family: var(--body);
  font-size: clamp(14px, 1.35vw, 17px);
  line-height: 1.3;
  color: #6b2a45;
}

.biglietto-riga svg{
  flex: none;
  width: 18px;
  height: 18px;
  fill: #c4175f;
}

/* Il tallone, staccato dal resto da una linea tratteggiata: e' quello che fa
   sembrare un biglietto invece di un rettangolo con dentro delle scritte. */
.biglietto-tallone{
  flex: none;
  width: clamp(86px, 8.8vw, 106px);
  padding: 12px 8px;

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;

  text-align: center;
  background: linear-gradient(180deg, #fbd3e6 0%, #f4bad4 100%);
  border-left: 2px dashed rgba(140, 70, 95, .45);
}

.biglietto-giorno{
  font-family: var(--display);
  font-size: clamp(26px, 2.6vw, 34px);
  font-weight: 700;
  line-height: 1;
  color: #c4175f;
}

.biglietto-mese{
  font-family: var(--body);
  font-size: clamp(11.5px, 1.1vw, 14px);
  letter-spacing: .16em;
  color: #8c4462;
}

.biglietto-ora{
  margin-top: 4px;
  font-family: var(--body);
  font-size: clamp(13.5px, 1.25vw, 16px);
  font-weight: 500;
  color: #47122c;
}

/* --- Le due stanze di lato -----------------------------------------------
   Dietro alla seconda e alla terza scelta non c'e' una discesa ma uno
   spostamento: la festa esce da una parte e la stanza nuova entra dall'altra,
   alla stessa velocita', come guardarsi intorno. Un movimento solo, e niente
   da nascondere: qui non serve nessuna tenda. */

.stanza{
  position: fixed;
  inset: 0;
  z-index: 60;
  overflow: hidden;
  animation-duration: var(--viaggio, 1.4s);
  animation-timing-function: cubic-bezier(.4, .1, .3, 1);
  animation-fill-mode: both;
}

/* Verso destra: la festa se ne va a sinistra, la stanza arriva da destra. */
body.verso-destra .inside,
body.verso-destra canvas.cuori{
  animation: esce-a-sinistra var(--viaggio, 1.4s) cubic-bezier(.4, .1, .3, 1) both;
}
#giallo{ transform: translateX(100vw); animation-name: arriva-da-destra; }

/* Verso sinistra: l'esatto contrario. */
body.verso-sinistra .inside,
body.verso-sinistra canvas.cuori{
  animation: esce-a-destra var(--viaggio, 1.4s) cubic-bezier(.4, .1, .3, 1) both;
}
#cucina{ transform: translateX(-100vw); animation-name: arriva-da-sinistra; }

@keyframes esce-a-sinistra{ to{ transform: translateX(-100vw); } }
@keyframes esce-a-destra { to{ transform: translateX(100vw); } }
@keyframes arriva-da-destra  { from{ transform: translateX(100vw); }  to{ transform: none; } }
@keyframes arriva-da-sinistra{ from{ transform: translateX(-100vw); } to{ transform: none; } }

/* La stanza gialla: il giallo si vede solo nella striscia che la foto non
   copre, ed e' la stessa luce della lampadina accesa nella foto. */
.stanza-gialla{
  background:
    radial-gradient(90% 70% at 24% 8%, #fff3c2 0%, rgba(255,243,194,0) 62%),
    linear-gradient(168deg, #ffe27a 0%, #ffd23f 55%, #ffc61f 100%);
}

/* --- Le scene ------------------------------------------------------------
   Una foto di stanza non e' uno sfondo ritagliato dal CSS ma una **scena**: un
   rettangolo che tiene la forma della foto, grande abbastanza da coprire la
   finestra, appoggiato in basso e lasciato sbordare. Serve perche' quello che
   sta sopra alla foto — i fumetti, il tic e il tac, i pulsanti — ci sta dentro:
   posizionato in percentuale della scena resta attaccato al suo pezzo di
   disegno qualunque sia il taglio, mentre in percentuale della finestra
   scivolerebbe via appena cambia la forma dello schermo.

   Appoggiata **in basso**, cosi' il bordo inferiore della foto tocca sempre il
   fondo della finestra e il taglio, quando serve, se lo mangia il soffitto:
   e' li' che non c'e' niente da vedere. E in basso con `bottom: 0`, non con un
   allineamento: un allineamento di griglia, quando l'elemento e' piu' grande
   del suo spazio, se ne dimentica e lo lascia sbordare dalla parte sbagliata —
   e la foto finiva alzata, col pavimento tagliato fuori. */
.stanza-cucina{ background: #e8d6bd; }

.scena{
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  aspect-ratio: 2000 / 1116;
}

/* Finestra piu' alta della foto: la scena si scala sull'altezza e sborda di
   lato. Il taglio si porta via la destra della cucina, e i fumetti — che si
   contano sulla finestra — vanno rifatti: larghi quasi quanto lo schermo e
   impilati in alto, sopra alla mamma che resta sotto. */
@media (max-aspect-ratio: 2000 / 1116){
  .scena{
    width: auto;
    height: 100%;

    /* Si sposta a sinistra quanto basta per mettere in mezzo allo schermo il
       punto della foto che conta (`--mira`), ma **non piu' di quanto sborda**,
       se no dall'altra parte si aprirebbe una striscia scoperta. Le tre righe
       qui sotto sono esattamente questo: quanto vorrei, quanto posso, e il
       minore dei due. */
    left: calc(-1 * clamp(0px, var(--vorrei), var(--posso)));

    --larga: calc(var(--schermo, 100vh) * 2000 / 1116);
    --mira: .5;
    --vorrei: calc(var(--larga) * var(--mira) - 50vw);
    --posso: max(0px, calc(var(--larga) - 100vw));
  }

  /* In cucina il mezzo non e' il mezzo: lei e Patrisio stanno al 42%. */
  .scena-cucina{ --mira: .42; }

  .fumetto{
    font-size: clamp(11px, 2.6vw, 20px);
  }

  .fumetto-mamma{
    left: 6%;
    top: 3%;
    width: 68%;
  }

  .fumetto-patrisio{
    left: 6%;
    top: 36%;
    width: 52%;
  }

  .fumetto-fuoricampo{
    left: 6%;
    top: 14%;
    width: 62%;
    font-size: clamp(13px, 3vw, 24px);
  }

  /* Schermo stretto: la camera si taglia ai lati e i due non stanno piu' dove
     stavano. I fumetti si impilano, larghi quasi quanto lo schermo. */
  .fumetto-parte{
    left: 5%;
    top: 3%;
    width: 62%;
  }

  .fumetto-resta,
  .fumetto-evviva{
    left: 33%;
    top: 26%;
    width: 62%;
  }

  .fumetto-eccomi{
    left: 5%;
    top: 3%;
    width: 62%;
  }

  .fumetto-compagna{
    left: 5%;
    top: 3%;
    width: 66%;
  }

  .fumetto-grazie{
    left: 33%;
    top: 4%;
    width: 62%;
  }

  .fumetto-cucciola{
    left: 5%;
    top: 4%;
    width: 62%;
  }

}

.sfondo{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Le inquadrature dopo la prima stanno tutte qui sopra, spente, e si accendono
   a turno. Immagini sovrapposte invece di una che cambia `src`: cosi' il cambio
   e' una dissolvenza e non un lampo bianco mentre il browser va a prendere il
   file. Una volta accesa, ognuna resta accesa: la seguente le va sopra e la
   copre, e cosi' durante la dissolvenza non si vede mai in trasparenza la
   cucina di partenza. */
.sfondo-dopo{
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .8s ease;
}

/* L'ultima inquadratura non copre il muro: ci sta appesa. Una cornice di legno
   con dentro il passe-partout chiaro, appesa in mezzo alla parete e un po'
   sotto al centro, all'altezza a cui si guarda un quadro —
   l'orologio resta dietro, e il caffe' e' un quadro nella cucina invece di una
   cucina nuova. */
.quadro{
  inset: auto;
  left: 50%;
  top: 58.25%;
  translate: -50% -50%;
  margin: 0;

  width: 58%;
  padding: 1.6%;
  background: #fdf7e9;

  border: .85em solid #7c4a2a;
  border-radius: 3px;

  box-shadow:
    0 2.4em 3.6em -1.4em rgba(52, 26, 12, .6),
    0 .3em .9em -.4em rgba(52, 26, 12, .45),
    inset 0 0 0 .14em rgba(255, 255, 255, .5);
}

.quadro img{
  display: block;
  width: 100%;
  height: auto;
  box-shadow: 0 0 0 1px rgba(74, 43, 30, .25);
}

/* Quale lastra e' accesa lo decide `cambiaScenaCucina` in `main.js`, una
   riga: sono accese quelle fino all'inquadratura di adesso. Prima la regola
   stava qui, scena per scena, e aggiungendo la quinta foto e' successo quello
   che doveva: alla quarta si accendevano tutte, e la moka — che e' l'ultima e
   sta sopra a tutte — arrivava con tre inquadrature di anticipo. */

/* Chi parla in questa inquadratura resta; tutto il resto se ne va. Il pulsante,
   premuto, ha finito il suo lavoro e non torna piu'. */
#cucina .fumetto,
#cucina .caffe{
  transition: opacity .45s ease;
}

#cucina:not([data-scena="1"]) .fumetto-mamma,
#cucina:not([data-scena="1"]) .caffe,
#cucina:not([data-scena="2"]) .fumetto-patrisio,
#cucina:not([data-scena="4"]) .fumetto-fuoricampo,
#cucina:not([data-scena="4"]) .vai-caffe{
  opacity: 0;
  pointer-events: none;
}

/* L'ultima inquadratura resta un secondo in silenzio — l'orologio, il caffe'
   che non arriva — e poi arriva la voce dall'altra stanza. Se arrivasse
   insieme alla foto quel secondo di attesa non ci sarebbe, ed e' lui la
   battuta.

   Un'animazione e non una transizione col ritardo: l'animazione tiene il suo
   fotogramma di partenza per tutto il ritardo (`both`), e quel fotogramma
   spegne anche i click — se no per un secondo ci sarebbe un pulsante invisibile
   ma premibile. */
#cucina[data-scena="4"] .fumetto-fuoricampo{
  animation: arriva-la-voce .5s ease-out 1s both;
}

/* Il pulsante arriva allo stesso modo e poi si mette a respirare come l'altro:
   due animazioni sullo stesso elemento, che non si pestano i piedi perche'
   muovono cose diverse — l'una l'opacita', l'altra la scala. */
#cucina[data-scena="4"] .vai-caffe{
  animation:
    arriva-la-voce .5s ease-out 1s both,
    respira 2.6s ease-in-out 1.5s infinite alternate;
}

/* Si muove con `translate`, non con `transform`, cosi' non si mangia il
   sollevamento del pulsante quando ci passi sopra. */
@keyframes arriva-la-voce{
  from{ opacity: 0; translate: 0 .5em; pointer-events: none; }
  to  { opacity: 1; translate: 0 0;    pointer-events: auto; }
}

@media (prefers-reduced-motion: reduce){
  @keyframes arriva-la-voce{
    from{ opacity: 0; pointer-events: none; }
    to  { opacity: 1; pointer-events: auto; }
  }
}

/* Il fumetto di Patrisio lascia passare avanti la cucina nuova, se no i due
   movimenti si accavallano e non si legge ne' l'una ne' l'altro — ma non la
   aspetta fino in fondo: l'inquadratura dura tre secondi e la battuta va letta
   in quelli. */
#cucina[data-scena="2"] .fumetto-patrisio{
  transition-delay: .4s;
}

/* --- I fumetti della cucina ---------------------------------------------
   Due, tutti e due della mamma: il primo a Patrisio, il secondo fra se' e se'.
   La coda e' un quadrato girato con due lati soli, cosi' i suoi bordi
   proseguono quelli della nuvoletta senza tagliarla.

   Stanno nella stanza e non dentro alla scena: cosi' la loro misura e il loro
   posto si contano sulla finestra, che e' quello che serve per non farli
   uscire dai bordi. Alle forme di schermo normali il taglio della foto e' di
   pochi punti percentuali e restano attaccati alla mamma lo stesso; su uno
   schermo stretto, dove il taglio e' grosso, ci pensa il blocco piu' in
   basso a rimetterli a posto. */

.fumetto{
  position: absolute;
  margin: 0;
  padding: .95em 1.15em;

  font-family: var(--body);
  font-size: clamp(11px, 1.12vw, 19px);
  line-height: 1.34;
  color: #40261a;

  background: #fffdf6;
  border: .17em solid #4a2b1e;
  border-radius: 1.5em;
  box-shadow: 0 .5em 1.4em -.6em rgba(74, 43, 30, .55);
}

/* La coda: due triangoli sovrapposti, uno scuro e uno chiaro. Quello scuro fa
   il bordo, quello chiaro il riempimento — e coprendo il bordo di sotto della
   nuvoletta la attacca al resto senza una cucitura. Sono triangoli veri,
   ritagliati: prima era un quadrato girato e storto, ed e' proprio quello che
   si vedeva. La punta si sposta con --punta.

   I due triangoli partono **dagli stessi due angoli in alto**, tutti e due
   larghi quanto la coda. E' questo che fa sparire il lato di sopra: quello
   chiaro copre quello scuro esattamente, e del triangolo scuro restano solo i
   due fianchi, che si aprono scendendo verso la punta. Prima quello chiaro era
   stretto dentro (11%-89%) e ai lati della bocca avanzavano due trattini scuri
   orizzontali: si vedeva il lato di sopra del triangolo, e la coda sembrava
   appiccicata sotto alla nuvoletta invece che aperta dentro. */
.fumetto::before,
.fumetto::after{
  content: "";
  position: absolute;
  top: calc(100% - .22em);
  width: 2.1em;
  height: 1.3em;
}

.fumetto::before{
  background: #4a2b1e;
  clip-path: polygon(0 0, 100% 0, var(--punta, 14%) 100%);
}

.fumetto::after{
  background: #fffdf6;
  clip-path: polygon(0 0, 100% 0, calc(var(--punta, 14%) + 6%) 80%);
}

/* Quello della mamma: in alto a sinistra, con la coda all'estremita' destra —
   da li' scende dritta su di lei, che sta appena sotto. */
.fumetto-mamma{
  left: 4%;
  top: 5%;
  width: 36%;
  --punta: 78%;
}
.fumetto-mamma::before,
.fumetto-mamma::after{
  left: auto;
  right: 10%;
}

/* Quello di Patrisio: piu' in basso e piu' stretto, appena sopra la sua testa,
   con la coda che scende a sinistra verso di lui mentre corre via. */
.fumetto-patrisio{
  left: 3.5%;
  top: 39%;
  width: 25%;
  --punta: 34%;
}
.fumetto-patrisio::before,
.fumetto-patrisio::after{
  left: 22%;
  right: auto;
}

/* --- I fumetti della camera ---------------------------------------------
   Uno per parte, come sono nella foto: lei sulla porta a sinistra, lui seduto
   sul letto a destra. Le due code si guardano.

   Sono quattro in tutto, ma due per volta: due quando lei esce e due quando
   torna. In mezzo, per tutto il giorno che passa, non parla nessuno. Gli ultimi
   due stanno negli stessi posti dei primi, perche' nella foto lei e Patrisio
   sono tornati dov'erano — un giorno dopo. */

#giallo .fumetto{ transition: opacity .45s ease; }

#giallo:not([data-scena="1"]) .fumetto-parte,
#giallo:not([data-scena="1"]) .fumetto-resta,
#giallo:not([data-scena="8"]) .fumetto-eccomi,
#giallo:not([data-scena="8"]) .fumetto-evviva,
#giallo:not([data-scena="9"]) .fumetto-compagna,
#giallo:not([data-scena="9"]) .accontenta,
#giallo:not([data-scena="10"]) .fumetto-grazie,
#giallo:not([data-scena="10"]) .sbircia,
#giallo:not([data-scena="11"]) .fumetto-cucciola{
  opacity: 0;
  pointer-events: none;
}

/* Alla fine si lascia entrare prima lei: si vede che e' tornata, e poi si
   sente. Arrivando insieme alla foto la battuta anticiperebbe l'immagine. */
#giallo[data-scena="8"] .fumetto-eccomi{ transition-delay: .8s; }
#giallo[data-scena="8"] .fumetto-evviva{ transition-delay: 1.5s; }

/* Nel primo piano si lascia respirare un momento la faccia, e poi parla: e'
   una cosa che gli costa dire. */
#giallo[data-scena="9"] .fumetto-compagna{ transition-delay: 1s; }

/* Il pulsante arriva dopo la battuta — prima si legge quello che chiede, poi
   si puo' dirgli di si' — e poi respira come gli altri due. */
#giallo[data-scena="9"] .accontenta{
  animation:
    arriva-la-voce .5s ease-out 2s both,
    respira 2.6s ease-in-out 2.5s infinite alternate;
}

/* Stessa cosa quando entra la carrozzina: prima lui ringrazia, e poi si puo'
   andare a guardare cosa c'e' dentro. */
#giallo[data-scena="10"] .fumetto-grazie{ transition-delay: .8s; }

#giallo[data-scena="10"] .sbircia{
  animation:
    arriva-la-voce .5s ease-out 2s both,
    respira 2.6s ease-in-out 2.5s infinite alternate;
}

/* In fondo alla carrozzina si lascia guardare la faccia per un secondo intero
   prima che parli: e' tutta li' la battuta. */
#giallo[data-scena="11"] .fumetto-cucciola{ transition-delay: 1s; }

.fumetto-parte{
  left: 4%;
  top: 5%;
  width: 30%;
  --punta: 78%;
}
.fumetto-parte::before,
.fumetto-parte::after{
  left: auto;
  right: 10%;
}

.fumetto-resta{
  left: 60%;
  top: 24.9%;
  width: 30%;
  --punta: 60%;
}
.fumetto-resta::before,
.fumetto-resta::after{
  left: 18%;
  right: auto;
}

.fumetto-eccomi{
  left: 4%;
  top: 5%;
  width: 30%;
  --punta: 78%;
}
.fumetto-eccomi::before,
.fumetto-eccomi::after{
  left: auto;
  right: 10%;
}

.fumetto-evviva{
  left: 58%;
  top: 22.9%;
  width: 32%;
  --punta: 60%;
}
.fumetto-evviva::before,
.fumetto-evviva::after{
  left: 18%;
  right: auto;
}

/* Quando arriva la carrozzina: lui e' sul letto a destra, e il fumetto gli sta
   sopra, con la coda che scende verso di lui. */
.fumetto-grazie{
  left: 52%;
  top: 23.7%;
  width: 34%;
  --punta: 40%;
}
.fumetto-grazie::before,
.fumetto-grazie::after{
  left: 12%;
  right: auto;
}

/* Dentro alla carrozzina: lei sta in mezzo, e il fumetto le sta in alto a
   sinistra, sul manico e sullo sfondo sfocato, con la coda che scende verso
   quella faccia li'. */
.fumetto-cucciola{
  left: 10.8%;
  top: 8%;
  width: 32%;
  --punta: 78%;
}
.fumetto-cucciola::before,
.fumetto-cucciola::after{
  left: auto;
  right: 10%;
}

/* Il primo piano: lui riempie mezza foto e non c'e' spazio se non in alto a
   sinistra, sullo sfondo sfocato. La coda scende a destra, verso la bocca. */
.fumetto-compagna{
  left: 3%;
  top: 6%;
  width: 38%;
  --punta: 82%;
}
.fumetto-compagna::before,
.fumetto-compagna::after{
  left: auto;
  right: 8%;
}

/* Quello di Patrisio dall'altra stanza: la coda esce dal bordo sinistro dello
   schermo, che e' dove sta lui — cioe' da nessuna parte che si veda. Le
   maiuscole e il corpo piu' grande fanno il resto: e' un urlo. */
.fumetto-fuoricampo{
  left: 6%;
  top: 17%;
  width: 33%;

  font-size: clamp(13px, 1.35vw, 23px);
  font-weight: 700;
  letter-spacing: .01em;
  --punta: 0%;
}
.fumetto-fuoricampo::before,
.fumetto-fuoricampo::after{
  left: 7%;
  right: auto;
}

/* --- Il tic e il tac -----------------------------------------------------
   Sull'inquadratura dell'orologio non succede niente: e' proprio quello il
   punto, il caffe' non arriva. Due parole sole, ai lati del quadrante, danno
   il tempo che passa: tic, tac, tic, tac, uno al secondo.

   Quattro battute con due sole parole: ognuna delle due si ripete due volte, e
   il giro dura due secondi — la parola si vede nel primo e lascia il posto
   all'altra nel secondo. Il tic parte dopo un secondo, il tac dopo due, e da li'
   si alternano da soli.

   Non c'e' JavaScript: l'animazione parte da sola quando entra in scena
   l'orologio (`data-scena="3"`) e ognuna ha il suo ritardo. Quando si cambia
   inquadratura la regola non vale piu' e spariscono con lei.

   Stanno dentro alla scena, e non nella stanza come i fumetti: il loro posto e'
   in percentuale **della foto**, cosi' restano attaccati al quadrante
   qualunque sia il taglio dello schermo. */

.tictac{
  position: absolute;
  z-index: 4;
  opacity: 0;

  font-family: var(--display);
  font-size: clamp(20px, 2.6vw, 44px);
  font-weight: 700;
  letter-spacing: .06em;
  color: #6b3f27;
  text-shadow: 0 .06em 0 rgba(255, 248, 235, .85);
}

.tic{ left: 36.5%; top: 33%; transform: rotate(-7deg); }
.tac{ left: 62%;   top: 52%; transform: rotate(6deg); }

#cucina[data-scena="3"] .tic{ animation: tictac 2s ease-out 1s 2 both; }
#cucina[data-scena="3"] .tac{ animation: tictac 2s ease-out 2s 2 both; }

/* Un giro dura due secondi: la parola arriva con un piccolo scatto, sta poco
   meno di un secondo e se ne va: il secondo secondo e' dell'altra. */
@keyframes tictac{
  0%   { opacity: 0; scale: .72; }
  9%   { opacity: 1; scale: 1.08; }
  16%  { scale: 1; }
  34%  { opacity: 1; }
  45%  { opacity: 0; scale: 1.04; }
  100% { opacity: 0; scale: 1.04; }
}

@media (prefers-reduced-motion: reduce){
  @keyframes tictac{
    0%   { opacity: 0 }
    9%   { opacity: 1 }
    34%  { opacity: 1 }
    45%  { opacity: 0 }
    100% { opacity: 0 }
  }
}

/* --- Il pulsante del caffe' ----------------------------------------------
   Grande, tondo e rosso, appoggiato sul muro sopra ai cucchiai di legno.
   Respira: si allarga e si stringe piano, come chi aspetta. E' l'unica cosa in
   movimento in una stanza ferma, quindi l'occhio ci va da solo — che e'
   esattamente quello che deve fare.

   Il posto e' in percentuale **della foto**, non della finestra, perche' e' ai
   cucchiai che deve stare sopra: sta dentro alla scena, come il tic e il tac,
   e cosi' non si stacca da loro qualunque sia il taglio dello schermo. */

.caffe,
.vai-caffe,
.accontenta,
.sbircia{
  position: absolute;
  z-index: 5;

  width: clamp(118px, 13vw, 186px);
  aspect-ratio: 1;
  padding: 0 .9em;
  border-radius: 50%;
  cursor: pointer;

  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;

  font-family: var(--display);
  font-size: clamp(13px, 1.15vw, 18px);
  font-weight: 700;
  line-height: 1.16;
  color: #fff6f4;
  text-shadow: 0 1px 2px rgba(90, 8, 12, .55);

  background:
    radial-gradient(circle at 34% 28%, #ff6b62 0%, rgba(255,107,98,0) 58%),
    linear-gradient(168deg, #e0252b 0%, #c0161d 55%, #970f16 100%);
  border: 3px solid #fff3ee;

  box-shadow:
    0 18px 34px -14px rgba(120, 10, 16, .75),
    0 0 0 6px rgba(224, 37, 43, .22),
    inset 0 3px 0 rgba(255, 255, 255, .3);

  animation: respira 2.6s ease-in-out infinite alternate;
  transition: filter .18s ease;
}

/* Quello per farlo, sul piano di lavoro. */
.caffe{ left: 65.5%; top: 38%; }

/* Quello per andarselo a bere, in basso a destra sotto all'orologio: lo stesso
   pulsante, e si capisce che e' la stessa cosa che continua. */
.vai-caffe{ left: 75.2%; top: 71.5%; }

/* E quello per accontentarlo, nel primo piano: a destra della faccia, dove lo
   sfondo e' sfocato e non c'e' niente da coprire. */
.accontenta{ left: 78%; top: 42%; }

/* Quello per guardare dentro alla carrozzina: in basso a destra, sul letto,
   lontano dalla carrozzina — che e' quello che si va a scoprire. */
.sbircia{ left: 78%; top: 75.8%; }

@keyframes respira{
  from{ transform: scale(1);    box-shadow: 0 18px 34px -14px rgba(120,10,16,.75), 0 0 0 6px rgba(224,37,43,.22), inset 0 3px 0 rgba(255,255,255,.3); }
  to  { transform: scale(1.075); box-shadow: 0 22px 40px -14px rgba(120,10,16,.8), 0 0 0 16px rgba(224,37,43,0), inset 0 3px 0 rgba(255,255,255,.3); }
}

.caffe:hover,
.vai-caffe:hover,
.accontenta:hover,
.sbircia:hover{ filter: brightness(1.06); }
.caffe:active,
.vai-caffe:active,
.accontenta:active,
.sbircia:active{ filter: brightness(.94); }

/* Chi ha chiesto al sistema meno animazioni non lo vede respirare: resta li',
   grande e rosso, che si fa notare lo stesso. */
@media (prefers-reduced-motion: reduce){
  .caffe,
  .vai-caffe,
  .accontenta,
  .sbircia{ animation: none; }

  /* Questi pero' l'animazione se la tengono: e' quella che li fa arrivare dopo
     la battuta, e col fotogramma di partenza gli tiene spenti i click. */
  #cucina[data-scena="4"] .vai-caffe{ animation: arriva-la-voce .5s ease-out 1s both; }
  #giallo[data-scena="9"] .accontenta{ animation: arriva-la-voce .5s ease-out 2s both; }
  #giallo[data-scena="10"] .sbircia{ animation: arriva-la-voce .5s ease-out 2s both; }
}

/* --- Il pulsante per tornare a scegliere ---------------------------------
   Ce n'e' uno in ognuna delle tre stanze, in basso a sinistra. La forma e' la
   stessa per tutti e tre — cambiano solo i colori, presi da quelli della
   stanza in cui sta: uno che si vede ma non ruba la scena. */

.torna{
  position: absolute;
  left: clamp(16px, 2.6vw, 38px);
  bottom: clamp(16px, 3vh, 34px);
  z-index: 5;

  padding: .62em 1.15em;
  border-radius: 999px;
  cursor: pointer;

  font-family: var(--body);
  font-size: clamp(12.5px, 1.05vw, 16px);
  font-weight: 500;
  white-space: nowrap;

  transition: transform .18s ease, box-shadow .18s ease, opacity .18s ease;
}

.torna:hover{ transform: translateY(-2px); }
.torna:active{ transform: translateY(0); }

/* In fondo al mare: crema e blu profondo, come i biglietti e la scritta. */
.torna-mare{
  color: #0a3f63;
  background: linear-gradient(180deg, #fffdf7 0%, #eaf6fa 100%);
  border: 2px solid rgba(10, 63, 99, .45);
  box-shadow: 0 10px 20px -12px rgba(4, 45, 70, .9);
}
.torna-mare:hover{ box-shadow: 0 14px 24px -12px rgba(4, 45, 70, .95); }

/* Nella stanza gialla: ambra scura su bianco caldo. */
.torna-giallo{
  color: #8a5a06;
  background: linear-gradient(180deg, #fffdf3 0%, #fff0be 100%);
  border: 2px solid rgba(138, 90, 6, .4);
  box-shadow: 0 10px 20px -12px rgba(138, 90, 6, .7);
}
.torna-giallo:hover{ box-shadow: 0 14px 24px -12px rgba(138, 90, 6, .8); }

/* In cucina: gli stessi colori dei fumetti, cosi' sembra parte del disegno. */
.torna-cucina{
  color: #40261a;
  background: #fffdf6;
  border: 2px solid #4a2b1e;
  box-shadow: 0 10px 20px -12px rgba(74, 43, 30, .8);
}
.torna-cucina:hover{ box-shadow: 0 14px 24px -12px rgba(74, 43, 30, .9); }

/* Il metro delle prove: c'e' solo aprendo il sito con ?misura in fondo
   all'indirizzo, e dice quanto e' grande la finestra in pixel CSS. Sta sopra a
   tutto e non prende i click, cosi' non da' fastidio a niente. */
.metro{
  position: fixed;
  right: 10px;
  bottom: 10px;
  z-index: 999;
  padding: 5px 11px;

  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 12px;
  letter-spacing: .04em;
  color: #fff;

  background: rgba(20, 12, 16, .72);
  border-radius: 999px;
  pointer-events: none;
}

/* --- 12. Schermi stretti ----------------------------------------------- */

/* Sotto una certa larghezza l'incrocio sbilenco non ci sta piu': i nastri
   tornano al centro, si alzano, e il biglietto occupa tutta la larghezza. */
@media (max-width: 620px){
  .gift{ --nastro-x: 0px; --nastro-w: 46px; --nastro-y: 13%; --rosetta-w: 176px; }
  .gift-lid{ padding: 128px 20px 40px; border-radius: 22px; }
  .card{ width: 100%; margin-left: 0; }
  .gift{ --parete: 26px; }
  .gift-inside{ border-radius: 22px; }
  .box-floor{ padding: 26px 18px; }
  .lang{ top: 14px; right: 14px; }
  h1{ font-size: clamp(23px, 6.2vw, 34px); }
}

@media (max-width: 400px){
  .gift{ --nastro-w: 38px; --nastro-y: 12%; --rosetta-w: 144px; }
  .gift-lid{ padding: 104px 12px 26px; border-radius: 18px; }
  .gift{ --parete: 18px; }
  .gift-inside{ border-radius: 18px; }
  .box-floor{ padding: 20px 12px; }
  .lang{ top: 10px; right: 10px; padding: 2px; }
  .lang button{ padding: 4px 10px; font-size: 11px; }
  .card{ padding: 20px 14px 18px; }
  .tape{ width: 66px; height: 21px; top: -11px; }
  .tape-left{ left: -18px; }
  .tape-right{ right: -18px; }
  .count{ gap: 6px; }
  .unit{ padding: 11px 2px 9px; border-radius: 15px; }
  .unit span{ font-size: 9px; letter-spacing: .05em; }
  .eyebrow{ font-size: 10.5px; letter-spacing: .1em; }
}

/* --- 13. Chi ha chiesto meno animazioni -------------------------------- */

@media (prefers-reduced-motion: reduce){
  *{
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}
