/* =============================================================================
   Vinile — la homepage.

   Estratto dalla Proposta C approvata il 27 agosto 2026. Solo le sezioni che
   sito.css non copre: impalcatura, testata, linea oraria, pie' di pagina e
   barra bassa stanno gia' la'.
   ========================================================================== */

/* ===== HOME · HERO ================================================ */


  /* Al club si entra dentro, non davanti. Il filmato sta a tutta schermata e
     sopra ci va pochissimo: se il video e' gia' forte, il testo che urla non
     raddoppia l'effetto, lo annulla. */
  .hero {
    position: relative; min-height: 100svh; overflow: hidden;
    display: grid; grid-template-rows: 1fr auto;
  }
  .hero__media { position: absolute; inset: 0; }
  .hero__media video, .hero__media img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    /* Il neon del locale va dal blu al rosso al viola. Smorzato di poco, smette
       di litigare con l'arancione del marchio senza diventare slavato. */
    /* Il filmato nuovo e' molto piu' luminoso del precedente: senza rialzare il
       contrasto i neri si impastano e la scena sembra nebbia. */
    filter: saturate(0.88) contrast(1.14) brightness(0.92);
    /* Ogni orientamento riceve il proprio file, gia' inquadrato: non c'e' piu'
       niente da recuperare spostando il punto di fuoco. */
    object-position: 50% 50%;
  }
  /* La velatura non e' un vetro nero sopra il video: e' un viraggio. Il centro
     viene scaldato verso l'arancione del brand, i bordi raffreddati e chiusi
     verso il nero-blu. In soft-light il grigio medio non fa nulla, quindi il
     filmato resta il filmato - cambia la temperatura, non la luminosita'.
     Serve a una cosa concreta: il girato passa dal blu al rosso al viola nel
     giro di cinque secondi, e senza un viraggio la prima schermata cambia
     colore addosso a chi guarda. Cosi' invece resta la stessa stanza. */
  .hero__grade {
    position: absolute; inset: 0; pointer-events: none; mix-blend-mode: soft-light;
    /* Il centro era #ff7a3d: su un fotogramma gia' chiaro alzava la luminosita'
       invece di limitarsi a scaldare. Un arancione piu' spento vira senza tirare
       su, e i bordi scendono piu' in basso per chiudere la scena. */
    background: radial-gradient(74% 58% at 50% 40%, #d4854f 0%, #6e6674 44%, #070a14 100%);
  }
  /* La trama. Il viraggio qui sopra da' il colore, questa da' la materia:
     e' la grana della pellicola, non un motivo geometrico. Tre ragioni oltre
     al gusto. Unifica i due filmati, che sono girati diversi e si vedeva.
     Copre le fasce di posterizzazione che il video compresso lascia nei neri,
     e la prima schermata e' quasi tutta nera. E lega il girato al resto della
     pagina invece di lasciarlo come una finestra incollata sopra.

     Sta sotto il velo di leggibilita' apposta: la pellicola vera sgrana anche
     il testo, ma qui il testo deve restare pulito. */
  .hero__grain {
    position: absolute; inset: -6%; pointer-events: none;
    background-image: var(--grana);
    background-repeat: repeat;
    /* Su schermo fitto la piastrella va servita alla meta': un pixel di grana
       deve valere un pixel dello schermo, altrimenti non e' grana, e' sfocatura. */
    background-size: 128px 128px;
    mix-blend-mode: overlay;
    opacity: 0.5;
  }
  @media (min-resolution: 1.5dppx) { .hero__grain { background-size: 64px 64px; } }

  /* La pellicola non scorre, salta. Otto scarti a tempo fisso, senza
     interpolazione: e' il motivo per cui `steps` e non una curva. Nove
     fotogrammi al secondo bastano - a 60 il velo costerebbe come il video. */
  .anim .hero__grain { animation: grana 880ms steps(1, end) infinite; }
  /* Fuori campo si ferma. Un velo a tutta schermata in sovrapposizione non e'
     gratis: finche' l'hero e' visibile vale il costo, dopo no. */
  .hero[data-fuori="true"] .hero__grain { animation-play-state: paused; }
  @keyframes grana {
    0%    { transform: translate3d(0, 0, 0); }
    12.5% { transform: translate3d(-1.5%, 1%, 0); }
    25%   { transform: translate3d(1%, -1.5%, 0); }
    37.5% { transform: translate3d(-1%, -1%, 0); }
    50%   { transform: translate3d(1.5%, 1.5%, 0); }
    62.5% { transform: translate3d(-1.5%, -0.5%, 0); }
    75%   { transform: translate3d(0.5%, 1%, 0); }
    87.5% { transform: translate3d(1%, -1%, 0); }
  }

  /* Sopra il viraggio, il velo che serve alla leggibilita': sotto la barra di
     navigazione e nel terzo basso, dove sta la riga di stasera. */
  .hero::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background:
      linear-gradient(to bottom,
        rgba(14,13,13,0.74) 0%, rgba(14,13,13,0.14) 15%, rgba(14,13,13,0.02) 42%,
        rgba(14,13,13,0.64) 76%, rgba(14,13,13,0.94) 100%);
  }

  /* Una pozza di buio grande quanto il contenuto, non quanto la schermata.
     Serve perche' l'anello passa da fotogrammi quasi neri a un viola acceso:
     su quello l'arancione del grammofono scendeva a 1,8:1 e spariva. Sfumata
     fino a zero, sui fotogrammi gia' bui non si vede. */
  .hero__inner::before {
    content: ""; position: absolute; z-index: -1; inset: -22% -14%;
    background: radial-gradient(50% 50% at 50% 50%,
      rgba(10,9,9,0.94) 0%, rgba(10,9,9,0.54) 52%, rgba(10,9,9,0) 100%);
  }
  .hero__inner {
    grid-row: 1; place-self: center; position: relative; z-index: 1;
    display: flex; flex-direction: column; align-items: center;
    gap: clamp(1.4rem, 3.6vh, 2.25rem); padding: 6rem var(--page-x) 0;
  }
  /* L'arancione del marchio contro un fotogramma chiaro scendeva a 2,2:1 e il
     grammofono spariva. L'alone lo stacca senza disegnare una macchia scura:
     sui fotogrammi gia' bui non si vede proprio. */
  .hero__mark { display: block; filter: drop-shadow(0 0 20px rgba(10,9,9,0.95)); }

  /* Due azioni sottovoce: un filo di bordo, niente pieno. Su un video la
     campitura arancione a tutta forza e' un cartello pubblicitario; il filo
     si vede lo stesso ed e' del locale, non della promozione. Il pieno resta
     nella barra fissa in fondo, che su mobile e' li' comunque. */
  .hero__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--vnl-space-md); }
  .hero__act {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0.62rem 1.35rem; text-decoration: none; color: var(--vnl-text);
    font-family: var(--vnl-font-body); font-size: var(--vnl-size-caption); font-weight: 600;
    text-transform: uppercase; letter-spacing: var(--vnl-tracking-wide);
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.86);
    background: rgba(14,13,13,0.56); backdrop-filter: blur(8px);
    transition: background var(--t-state) var(--ease-out), box-shadow var(--t-state) var(--ease-out);
  }
  .hero__act:hover, .hero__act:focus-visible {
    background: rgba(14,13,13,0.6); box-shadow: inset 0 0 0 1px rgba(255,255,255,0.7);
  }
  /* La differenza fra le due e' un filo arancione, non un rettangolo pieno. */
  /* Il filo del brand da solo, su un fotogramma chiaro, non si distingueva dal
     fondo: sotto ci va un secondo filo scuro che gli fa da ombra. */
  /* Sul piatto scuro l'arancione pieno del brand si ferma a 2,97:1: un pelo
     sotto la soglia dei contorni. Il brand-hover e' lo stesso arancione un
     gradino piu' chiaro, gia' definito nel design system, e passa. */
  .hero__act--first { box-shadow: inset 0 0 0 1px var(--vnl-brand-hover), 0 0 0 1px rgba(14,13,13,0.55); }
  .hero__act--first:hover, .hero__act--first:focus-visible {
    background: rgba(232, 73, 16, 0.28); box-shadow: inset 0 0 0 1px var(--vnl-brand-hover), 0 0 0 1px rgba(14,13,13,0.55);
  }

  /* In basso a sinistra, solo cosa c'e' stasera. Niente pannello: il velo del
     gradiente basta gia' a tenerlo leggibile. Regge tre stati, non solo la
     sera buona - ad agosto il locale e' chiuso. */
  .hero__foot { grid-row: 2; position: relative; z-index: 1; padding-bottom: clamp(2rem, 6vh, 3.5rem); }
  .tonight { display: flex; flex-direction: column; gap: 0.3rem; max-width: 44ch; }
  .tonight__flag {
    display: inline-flex; align-items: center; gap: 0.5rem;
    font-family: var(--vnl-font-body); font-size: var(--vnl-size-caption); font-weight: 600;
    text-transform: uppercase; letter-spacing: var(--vnl-tracking-wide); color: var(--vnl-text);
  }
  /* L'arancione del brand non e' un colore da testo: sul filmato la parola
     scendeva a 3,6:1. Arancione resta il punto che pulsa, che e' il segnale;
     la parola, che e' testo, torna bianca. */
  .tonight__dot { width: 7px; height: 7px; background: var(--vnl-brand); border-radius: 50%; }
  .tonight[data-stato="chiuso"] .tonight__flag,
  .tonight[data-stato="stagione"] .tonight__flag { color: var(--vnl-text-muted); }
  .tonight[data-stato="chiuso"] .tonight__dot,
  .tonight[data-stato="stagione"] .tonight__dot { background: var(--vnl-text-muted); }
  .anim .tonight[data-stato="aperto"] .tonight__dot { animation: pulse 2.4s var(--ease-out) infinite; }
  @keyframes pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.35; transform: scale(0.8); } }
  .tonight__what { margin: 0; color: var(--vnl-text); font-size: var(--vnl-size-body); line-height: 1.45; }
  .tonight__what b { font-weight: 600; }
  .tonight__when { margin: 0; color: var(--vnl-text-muted); font-size: var(--vnl-size-body-sm); font-variant-numeric: tabular-nums; }

  /* Il filmato parte gia' visibile e si apre: nessun contenuto e' nascosto in
     attesa di un'animazione. Poche cose, quindi pochi ritardi. */
  .anim .hero__media { animation: media-wipe 1200ms var(--ease-out-expo) both; }
  @keyframes media-wipe { from { clip-path: inset(14% 0 14% 0); transform: scale(1.05); } }
  .anim .hero__mark    { animation: rise var(--t-enter) var(--ease-out) 320ms both; }
  .anim .hero__actions { animation: rise var(--t-enter) var(--ease-out) 480ms both; }
  .anim .hero__foot    { animation: rise var(--t-enter) var(--ease-out) 620ms both; }
  @keyframes rise { from { opacity: 0; transform: translateY(1.25rem); } }
/* ===== HOME · BARRA DELLA SERA ==================================== */


  .evening { padding-block: clamp(3.5rem, 10vh, 6rem) 0; }

  .timeline {
    position: sticky; top: 4.25rem; z-index: var(--z-rail);
    background: rgba(14,13,13,0.9); backdrop-filter: blur(14px);
    border-block-start: 1px solid var(--vnl-border);
    margin-bottom: clamp(1.5rem, 4vh, 3rem);
  }
  .timeline__inner { display: flex; gap: 0; overflow-x: auto; scrollbar-width: none; }
  .timeline__inner::-webkit-scrollbar { display: none; }
  .timeline__step {
    flex: 1 0 auto; display: flex; flex-direction: column; gap: 0.15rem;
    padding: 0.7rem var(--vnl-space-md) 0.8rem; text-decoration: none;
    border-inline-end: 1px solid rgba(255,255,255,0.07); position: relative;
    transition: background var(--t-state) var(--ease-out);
  }
  .timeline__step:last-child { border-inline-end: 0; }
  .timeline__step:hover { background: var(--vnl-surface-1); }
  .timeline__step b {
    font-family: var(--vnl-font-display); font-weight: 800; font-size: var(--vnl-size-body-sm);
    letter-spacing: var(--vnl-tracking-display); font-variant-numeric: tabular-nums;
    color: var(--vnl-text-muted); transition: color var(--t-state) var(--ease-out);
  }
  .timeline__step span {
    font-family: var(--vnl-font-body); font-size: var(--vnl-size-caption); font-weight: 600;
    text-transform: uppercase; letter-spacing: var(--vnl-tracking-wide); color: var(--vnl-text-faint);
    transition: color var(--t-state) var(--ease-out);
  }
  .timeline__step::after {
    content: ""; position: absolute; inset-inline: 0; bottom: 0; height: 2px;
    background: var(--vnl-brand); transform: scaleX(0); transform-origin: left;
    transition: transform var(--t-layout) var(--ease-out);
  }
  /* scaleX e non width: la larghezza e' una proprieta' di layout. */
  .timeline__fill {
    position: absolute; inset-block-end: 0; inset-inline: 0; height: 2px;
    background: var(--vnl-brand); transform-origin: left;
    transform: scaleX(var(--p, 0)); transition: transform 120ms linear;
  }
  .timeline { position: sticky; }
  .timeline__step[data-on="true"] b { color: var(--vnl-brand); }
  .timeline__step[data-on="true"] span { color: var(--vnl-text); }
  .timeline__step[data-on="true"]::after { transform: scaleX(1); }
/* ===== HOME · I MOMENTI =========================================== */


  .moment {
    display: grid; gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    /* Niente riga fra un momento e l'altro: separa lo spazio, e l'immagine
       che cambia lato fa il resto. */
    padding-block: clamp(2.25rem, 6.5vh, 4rem);
  }
  .moment:nth-of-type(even) > .moment__media { order: -1; }
  /* Sul telefono due colonne da 170 px schiacciavano il testo, e il
     bottone di «Discoteca» (nowrap) usciva dallo schermo: una colonna,
     la foto sempre sopra. */
  @media (max-width: 40rem) {
    .moment { grid-template-columns: minmax(0, 1fr); }
    .moment > .moment__media { order: -1; }
  }
  .moment__body { display: flex; flex-direction: column; gap: var(--vnl-space-sm); align-items: flex-start; }
  .moment__time {
    display: flex; align-items: baseline; gap: var(--vnl-space-sm); flex-wrap: wrap; margin: 0;
    font-family: var(--vnl-font-display); font-weight: 800; font-size: var(--vnl-size-display-sm);
    letter-spacing: var(--vnl-tracking-display); color: var(--vnl-brand);
    font-variant-numeric: tabular-nums; line-height: 1;
  }
  .moment__kicker {
    font-family: var(--vnl-font-body); font-size: var(--vnl-size-caption); font-weight: 600;
    text-transform: uppercase; letter-spacing: var(--vnl-tracking-wide); color: var(--vnl-text-muted);
  }
  .moment__text { margin: 0; color: var(--vnl-text-muted); max-width: 42ch; line-height: 1.62; }
  .moment__days {
    margin: 0; font-family: var(--vnl-font-body); font-size: var(--vnl-size-caption); font-weight: 600;
    text-transform: uppercase; letter-spacing: var(--vnl-tracking-wide); color: var(--vnl-text-faint);
  }
  /* Ogni momento ha la sua proporzione: quattro riquadri identici in fila
     sono un elenco, non un racconto. */
  .moment__media { position: relative; overflow: hidden; aspect-ratio: var(--ratio, 4 / 3); }
  /* Il terzo momento rompe l'alternanza: immagine larga in cima, testo sotto
     su due colonne. Quattro spezzati foto+testo di fila sono un elenco. */
  .moment--live {
    grid-template-columns: 1fr;
    gap: clamp(1.25rem, 3vw, 2rem);
    padding-block: clamp(3rem, 8vh, 5rem);
  }
  .moment--live .moment__media { order: -1; }
  .moment--live .moment__body {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(1rem, 3vw, 2.5rem); align-items: start;
  }
  .moment--live .moment__body { align-content: start; row-gap: var(--vnl-space-sm); }
  .moment--live .moment__time { grid-column: 1; grid-row: 1; }
  .moment--live .moment__body > :nth-child(2) { grid-column: 1; grid-row: 2; }
  .moment--live .moment__days { grid-column: 1; grid-row: 3; align-self: end; }
  .moment--live .moment__text { grid-column: 2; grid-row: 1 / span 2; max-width: 46ch; margin: 0; }
  .moment--live .moment__body > :last-child { grid-column: 2; grid-row: 3; align-self: end; justify-self: start; }
  @media (max-width: 60rem) {
    .moment--live .moment__body { grid-template-columns: 1fr; }
    .moment--live .moment__body > * { grid-column: 1 !important; grid-row: auto !important; }
  }

  .moment--aperitivo .moment__media { --ratio: 16 / 10; }
  .moment--cena      .moment__media { --ratio: 1 / 1; }
  .moment--live      .moment__media { --ratio: 21 / 9; }
  .moment--club      .moment__media { --ratio: 4 / 3; }
  .moment__media img { width: 100%; height: 116%; object-fit: cover; display: block; position: absolute; inset-block-start: -8%; }
  /* Il velo di colore aspetta la fotografia. Le immagini sono a caricamento
     pigro: se il velo parte prima, per un attimo si vede un rettangolo colorato
     e vuoto, che sembra un errore piu' di quanto sembri un'attesa. */
  .moment__media::after {
    content: ""; position: absolute; inset: 0; mix-blend-mode: soft-light; pointer-events: none;
    background: var(--tint, transparent);
    opacity: 0; transition: opacity 420ms var(--ease-out);
  }
  .moment__media.is-caricata::after { opacity: 1; }
  .moment--aperitivo { --tint: rgba(232, 160, 60, 0.26); }
  .moment--cena      { --tint: rgba(232, 130, 40, 0.28); }
  .moment--live      { --tint: rgba(140, 60, 160, 0.22); }
  .moment--club      { --tint: rgba(30, 70, 190, 0.34); }

  /* La foto si scopre con una tendina invece di dissolversi: e' il materiale
     giusto per una pagina in cui la fotografia e' il contenuto.

     Lo stato chiuso vive su `.is-armed`, che JS mette SOLO su cio' che sta
     tutto sotto la piega. Quello che e' gia' in vista, e tutto quanto se
     l'osservatore non parte, resta semplicemente visibile: il moto e' un di
     piu' su una pagina gia' finita, non la condizione per vederla. */
  .anim .moment.is-armed .moment__media { clip-path: inset(0 100% 0 0); }
  /* i momenti pari hanno l'immagine a sinistra: la tendina apre dal lato opposto */
  .anim .moment:nth-of-type(even).is-armed .moment__media { clip-path: inset(0 0 0 100%); }
  /* Lo stato aperto deve battere anche il selettore con :nth-of-type, che ha
     specificita' piu' alta: senza la seconda riga i momenti pari non si
     aprivano mai e restavano invisibili. */
  .anim .moment.is-armed.is-in .moment__media,
  .anim .moment:nth-of-type(even).is-armed.is-in .moment__media {
    clip-path: inset(0 0 0 0); transition: clip-path 900ms var(--ease-out-expo);
  }
  .anim .moment.is-armed .moment__body > * { opacity: 0.001; transform: translateY(0.9rem); }
  .anim .moment.is-armed.is-in .moment__body > * {
    opacity: 1; transform: none;
    transition: opacity var(--t-enter) var(--ease-out), transform var(--t-enter) var(--ease-out);
    transition-delay: calc(var(--i, 0) * 70ms);
  }
/* ===== HOME · CALENDARIO ========================================== */


  /* Titolo a sinistra, collegamento a destra, sulla stessa linea di base. */
  .sec-row {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: var(--vnl-space-lg); flex-wrap: wrap;
    margin-bottom: clamp(1.75rem, 5vh, 2.75rem);
  }
  .sec-row__link {
    color: var(--vnl-text); text-decoration: none; position: relative; padding-block: 0.3rem;
    font-family: var(--vnl-font-body); font-size: var(--vnl-size-body-sm); font-weight: 600;
    text-transform: uppercase; letter-spacing: var(--vnl-tracking-wide);
    display: inline-flex; align-items: center; gap: 0.45rem; white-space: nowrap;
  }
  .sec-row__link::after {
    content: ""; position: absolute; inset-inline: 0; bottom: 0; height: 1px;
    background: var(--vnl-brand); transform: scaleX(0); transform-origin: left;
    transition: transform var(--t-state) var(--ease-out);
  }
  .sec-row__link:hover::after, .sec-row__link:focus-visible::after { transform: scaleX(1); }
  .sec-row__link i { font-style: normal; color: var(--vnl-brand); transition: transform var(--t-state) var(--ease-out); }
  .sec-row__link:hover i { transform: translateX(0.25rem); }

  /* Fascia di stagione: normalmente spenta, si accende quando serve. */
  .season {
    display: flex; flex-wrap: wrap; gap: var(--vnl-space-sm) var(--vnl-space-md);
    align-items: baseline; padding: var(--vnl-space-md) var(--vnl-space-lg);
    border: 1px solid var(--vnl-brand); margin-bottom: clamp(1.5rem, 4vh, 2.5rem);
  }
  .season b {
    font-family: var(--vnl-font-body); font-size: var(--vnl-size-caption); font-weight: 600;
    text-transform: uppercase; letter-spacing: var(--vnl-tracking-wide); color: var(--vnl-brand);
  }
  .season span { color: var(--vnl-text-muted); font-size: var(--vnl-size-body-sm); }

  /* La fascia esce dalla griglia di pagina, ma le quattro card devono avere
     lo stesso spazio utile. Con quattro colonne uguali il rientro di bordo
     mangiava la larghezza delle due esterne: a 1600px restavano 194px di
     testo contro 350px, e il titolo andava a capo una parola per riga.
     Le colonne esterne si allargano del rientro: il contenuto torna identico
     in tutte e quattro e il testo dell'ultima finisce esattamente sul
     margine destro della pagina. */
  .nights {
    --nights-gap: 2px;
    --nights-inset: max(0px, calc(var(--edge) - var(--vnl-space-lg)));
    --nights-col: calc((100% - 2 * var(--nights-inset) - 3 * var(--nights-gap)) / 4);
    display: grid; gap: var(--nights-gap); background: var(--vnl-border);
    grid-template-columns:
      calc(var(--nights-col) + var(--nights-inset))
      var(--nights-col)
      var(--nights-col)
      calc(var(--nights-col) + var(--nights-inset));
    grid-auto-rows: 1fr;              /* stessa altezza per tutte */
  }
  /* Una card per volta: sul telefono sono incolonnate e la fascia entrava
     tutta insieme, cosi' le ultime tre erano gia' comparse quando le
     raggiungevi. */
  .anim .night.is-armed { opacity: 0.001; transform: translateY(1.1rem); }
  .anim .night.is-armed.is-in {
    opacity: 1; transform: none;
    transition: opacity 620ms var(--ease-out), transform 620ms var(--ease-out);
    transition-delay: calc(var(--i, 0) * 70ms);
  }

  .night {
    position: relative; isolation: isolate; overflow: hidden;
    min-height: clamp(23rem, 52vh, 36rem);
    display: flex; flex-direction: column;
    padding: var(--vnl-space-lg);
    background: var(--vnl-surface-1);
    text-decoration: none; color: inherit;
  }
  /* La fascia esce dai margini, il testo dentro no: la prima card comincia
     dove comincia il titolo della sezione, l'ultima finisce dove finisce. */
  .nights > .night:first-child { padding-inline-start: var(--edge); }
  .nights > .night:last-child  { padding-inline-end: var(--edge); }
  .night__bg { position: absolute; inset: 0; z-index: -2; }
  .night__bg img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    filter: brightness(0.5) saturate(0.9);
    transform: scale(1.02);
    transition: filter var(--t-layout) var(--ease-out), transform 900ms var(--ease-out);
  }
  .night::after {
    content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    background: linear-gradient(to top,
      rgba(14,13,13,0.97) 0%, rgba(14,13,13,0.90) 34%,
      rgba(14,13,13,0.62) 66%, rgba(14,13,13,0.72) 100%);
  }
  .night__chips, .night__foot { transition: transform var(--t-layout) var(--ease-out); }
  .night:hover .night__bg img, .night:focus-within .night__bg img {
    filter: brightness(0.66) saturate(1.05); transform: scale(1.06);
  }
  .night:hover .night__foot, .night:focus-within .night__foot { transform: translateY(-0.35rem); }

  /* chip dei momenti: quelli spenti restano visibili, e' l'informazione */
  /* I chip stanno su una riga sola: il numero del giorno scende in basso,
     in tensione col titolo, invece di rubargli larghezza. */
  .night__chips { display: flex; flex-wrap: wrap; gap: 0.25rem; margin-bottom: auto; }
  .night__foot { display: flex; align-items: flex-end; gap: var(--vnl-space-sm); }
  .night__text { min-width: 0; }
  .night__num {
    margin: 0 0 0 auto; line-height: 0.78; flex: 0 0 auto;
    font-family: var(--vnl-font-display); font-weight: 800;
    font-size: clamp(1.9rem, 2.9vw, 2.6rem); letter-spacing: -0.035em;
    color: rgba(255,255,255,0.22); font-variant-numeric: tabular-nums;
    transition: color var(--t-layout) var(--ease-out);
  }
  .night:hover .night__num { color: rgba(255,255,255,0.34); }
  .night--special .night__num { color: rgba(232, 73, 16, 0.55); }
  .chip {
    /* tracking piu' stretto del solito: cosi' i quattro chip entrano su una
       riga sola anche nelle card di bordo, che hanno meno larghezza utile */
    font-family: var(--vnl-font-body); font-size: 0.625rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.09em;
    padding: 0.24rem 0.42rem; border: 1px solid currentColor; white-space: nowrap;
    color: var(--vnl-text); background: rgba(14,13,13,0.45);
  }
  .chip[data-off="true"] { color: var(--vnl-text-faint); border-color: rgba(255,255,255,0.16); background: none; }
  .chip[data-brand="true"] { color: var(--vnl-on-brand); background: var(--vnl-brand); border-color: var(--vnl-brand); }

  .night__date {
    margin: 0 0 0.35rem; font-family: var(--vnl-font-body); font-size: var(--vnl-size-caption);
    font-weight: 600; text-transform: uppercase; letter-spacing: var(--vnl-tracking-wide);
    color: var(--vnl-text-muted); font-variant-numeric: tabular-nums;
  }
  .night__title {
    margin: 0 0 0.5rem; font-family: var(--vnl-font-display); font-weight: 700;
    font-size: var(--vnl-size-display-sm); letter-spacing: var(--vnl-tracking-display);
    text-transform: uppercase; line-height: 1.05; color: var(--vnl-text); text-wrap: balance;
  }
  .night__cast { margin: 0 0 var(--vnl-space-sm); color: var(--vnl-text-muted); font-size: var(--vnl-size-body-sm); line-height: 1.5; }
  .night__cast b { color: var(--vnl-text); font-weight: 600; }
  .night__go {
    font-family: var(--vnl-font-body); font-size: var(--vnl-size-caption); font-weight: 600;
    text-transform: uppercase; letter-spacing: var(--vnl-tracking-wide); color: var(--vnl-brand);
    display: inline-flex; align-items: center; gap: 0.4rem;
  }
  .night__go span { transition: transform var(--t-state) var(--ease-out); }
  .night:hover .night__go span, .night:focus-visible .night__go span { transform: translateX(0.25rem); }
  .night--special { box-shadow: inset 0 0 0 2px var(--vnl-brand); }

  .calendar-all {
    display: flex; flex-wrap: wrap; gap: var(--vnl-space-md); align-items: center;
    justify-content: space-between; margin-top: var(--vnl-space-lg);
  }
  .calendar-all small { color: var(--vnl-text-faint); font-size: var(--vnl-size-caption); }

  /* Sotto le quattro colonne il rientro di bordo non ha piu' senso: la prima
     e l'ultima card non sono piu' agli estremi della stessa riga. */
  @media (max-width: 68rem) {
    .nights { grid-template-columns: repeat(2, 1fr); }
    .nights > .night:first-child, .nights > .night:last-child { padding-inline: var(--vnl-space-lg); }
  }
  @media (max-width: 40rem) {
    .nights { grid-template-columns: 1fr; }
    .night { min-height: 19rem; }
    /* incolonnate entrano una alla volta: lo scaglionamento non serve piu' */
    .anim .night.is-armed.is-in { transition-delay: 0ms; }
  }
/* ===== HOME · PROVINO ============================================= */


  .contact-sheet { padding-block: clamp(2.5rem, 6vh, 3.75rem); }
  .sheet__bleed { padding-inline-start: var(--edge); }
  .sheet__scroller {
    display: grid; grid-auto-flow: column; grid-auto-columns: clamp(150px, 22vw, 210px);
    gap: 2px; overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x proximity; cursor: grab;
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .sheet__scroller::-webkit-scrollbar { display: none; }
  .sheet__scroller.is-dragging { cursor: grabbing; scroll-snap-type: none; }
  .sheet__frame {
    position: relative; aspect-ratio: 1 / 1; scroll-snap-align: start; margin: 0;
    background: var(--vnl-surface-1); overflow: hidden;
  }
  .sheet__frame img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    filter: saturate(0.8) brightness(0.86);
    transition: filter var(--t-layout) var(--ease-out), transform var(--t-layout) var(--ease-out);
  }
  .sheet__frame:hover img, .sheet__frame:focus-within img { filter: none; transform: scale(1.04); }
  .sheet__frame figcaption {
    position: absolute; inset-block-end: 0; inset-inline: 0; padding: 0.4rem 0.55rem;
    font-family: var(--vnl-font-body); font-size: 0.6875rem; font-weight: 600;
    letter-spacing: var(--vnl-tracking-wide); text-transform: uppercase;
    color: var(--vnl-text); background: linear-gradient(to top, rgba(14,13,13,0.92), transparent);
    font-variant-numeric: tabular-nums;
  }

  /* Avanzamento al posto della scrollbar di sistema */
  .sheet__progress {
    margin-top: var(--vnl-space-md); height: 2px; background: var(--vnl-border);
    position: relative; overflow: hidden;
  }
  /* La barra si ridimensiona con scaleX invece che con width: la larghezza
     e' una proprieta' di layout e animarla fa ricalcolare la pagina. */
  .sheet__progress i {
    position: absolute; inset-block: 0; left: 0; display: block; width: 100%;
    background: var(--vnl-brand); transform-origin: left;
    transform: translateX(var(--x, 0)) scaleX(var(--w, 0.2));
    transition: transform 90ms linear;
  }
  .sheet__meta {
    display: flex; justify-content: space-between; gap: var(--vnl-space-md);
    margin: var(--vnl-space-sm) 0 0;
    font-family: var(--vnl-font-body); font-size: var(--vnl-size-caption); font-weight: 600;
    text-transform: uppercase; letter-spacing: var(--vnl-tracking-wide); color: var(--vnl-text-faint);
    font-variant-numeric: tabular-nums;
  }
/* ===== HOME · EVENTI ============================================== */


  .private { padding-block: clamp(4rem, 11vh, 6.5rem); }
  .private__grid { display: grid; gap: clamp(1.5rem, 4vw, 3rem); grid-template-columns: minmax(0,1fr) minmax(0,1fr); align-items: center; }
  .private__pics { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 2px; }
  .private__pics img { width: 100%; height: 100%; aspect-ratio: 1/1; object-fit: cover; display: block; }
  .private__pics img:first-child { grid-row: span 2; aspect-ratio: auto; }
/* ===== HOME · PRENOTA ============================================= */


  .booking { padding-block: clamp(3rem, 8vh, 5rem); }
  .booking__grid { display: grid; gap: clamp(1.5rem, 4vw, 3rem); grid-template-columns: minmax(0,1fr) minmax(0,1fr); align-items: start; }
  /* Dopo le due griglie, o la seconda la riscrive. Sul telefono testo e foto uno sopra l'altro: su due colonne da 170 px
     il testo andava a capo a ogni parola e il bottone sconfinava sotto le foto. */
  @media (max-width: 60rem) {
    .private__grid, .booking__grid { grid-template-columns: minmax(0,1fr); }
  }
  .booking__routes { display: grid; gap: 2px; background: var(--vnl-border); }
  .booking__route {
    background: var(--vnl-surface-1); padding: var(--vnl-space-lg);
    display: flex; flex-direction: column; gap: var(--vnl-space-xs); text-decoration: none;
    transition: background var(--t-state) var(--ease-out);
  }
  .booking__route:hover, .booking__route:focus-visible { background: var(--vnl-surface-2); }
  .booking__route b {
    font-family: var(--vnl-font-display); font-weight: 700; text-transform: uppercase;
    font-size: var(--vnl-size-display-sm); letter-spacing: var(--vnl-tracking-display); color: var(--vnl-text);
  }
  .booking__route span { color: var(--vnl-text-muted); font-size: var(--vnl-size-body-sm); }
  .booking__route em {
    font-style: normal; color: var(--vnl-brand); font-family: var(--vnl-font-body);
    font-size: var(--vnl-size-caption); font-weight: 600; text-transform: uppercase;
    letter-spacing: var(--vnl-tracking-wide);
  }
/* ===== HOME · MOVIMENTO DA TELEFONO =============================== */


  /* Da telefono il passaggio del mouse non esiste: tutto quello che su
     desktop e' un effetto di hover, qui non accade mai. Queste regole lo
     restituiscono come effetto d'ingresso e come risposta al dito. */
  @media (hover: none), (max-width: 40rem) {
    .anim .night.is-armed .night__bg img { transform: scale(1.16); }
    .anim .night.is-armed.is-in .night__bg img {
      transform: scale(1);
      transition: transform 1500ms var(--ease-out-expo), filter 900ms var(--ease-out);
    }
    /* il dito non lascia traccia: la pressione la deve dare la card */
    .night, .booking__route, .sheet__frame { transition: transform var(--t-tap) var(--ease-out), background var(--t-state) var(--ease-out); }
    .night:active, .booking__route:active { transform: scale(0.988); }
    .night:active .night__bg img { filter: brightness(0.68) saturate(1.05); }
  }

  /* Le tre porte della prenotazione entrano in ordine di lettura: sono una
     lista, lo scaglionamento e' l'ordine, non decorazione. */
  .anim .booking__route.is-armed { opacity: 0.001; transform: translateY(0.8rem); }
  .anim .booking__route.is-armed.is-in {
    opacity: 1; transform: none;
    transition: opacity 520ms var(--ease-out), transform 520ms var(--ease-out);
    transition-delay: calc(var(--i, 0) * 90ms);
  }

  /* Le foto degli eventi privati: in griglia su desktop, incolonnate sul
     telefono. In colonna lo scaglionamento si sente, in griglia si vede appena. */
  .anim .private__pics img.is-armed { opacity: 0.001; transform: translateY(0.9rem) scale(1.02); }
  .anim .private__pics img.is-armed.is-in {
    opacity: 1; transform: none;
    transition: opacity 560ms var(--ease-out), transform 700ms var(--ease-out);
    transition-delay: calc(var(--i, 0) * 80ms);
  }
