/* =============================================================================
   Modulo: card che va a tutto schermo.

   Stessa struttura a due layout della hero e dei servizi, e per le stesse
   ragioni: il default è la versione statica — un titolo, una card, le tappe una
   sotto l'altra — e il layout animato sta dentro
   `@media (scripting: enabled) and (prefers-reduced-motion: no-preference)`.

   Il JavaScript qui scrive **un numero e tre classi**: `--expand`, il progresso
   0→1 dell'apertura della card, `is-open` quando la card ha finito di aprirsi, e
   `is-active` sulla tappa e sul filmato correnti. Tutte le interpolazioni — la
   card che cresce, le laterali che escono, il titolo che sale — sono `calc()`
   qui sotto, su quell'unico numero. Non c'è nessuna tappa intermedia da tenere
   sincronizzata fra i due file.

   Le geometrie sono quelle del Make, un frame 1512×982, in percentuale della
   scena. La scena è grande quanto il viewport, quindi le percentuali reggono a
   ogni larghezza.
   ========================================================================== */

.cards-fullscreen {
    /* --- Valore guidato dal JS ----------------------------------------------
       0 = tre card al centro, 1 = quella centrale riempie lo schermo. Il default
       è il fotogramma zero: se il JS non parte mai, la prima schermata è
       comunque composta. */
    --expand: 0;

    /* Le due card laterali finiscono di uscire al 60% dell'apertura, non alla
       fine: nel Make la loro traccia è [0, 0.15] dentro un'intro che arriva a
       0.25. Sono già fuori campo mentre quella centrale sta ancora crescendo. */
    --side: min(1, var(--expand) / 0.6);

    /* Quanto scroll vale un passo. La scena ne ha uno per aprire la card più uno
       per tappa: è lo stesso numero che il JS usa per dividere il progresso.
       100vh e non i 200vh del Make perché è il passo dei servizi, e sulla home i
       due moduli sono consecutivi. */
    --step-length: 100vh;

    /* --- Geometrie del Make -------------------------------------------------
       Card centrale a riposo: 716×380 al centro di un frame 1512×982.
       Card laterali: 472×252, sempre centrate sulla stessa y — nel Make tutte e
       tre hanno il centro a 491px, cioè esattamente metà schermo. */
    --card-w-rest: 47.35%;
    --card-h-rest: 38.7%;
    --side-w: 31.22%;
    --side-h: 25.66%;

    /* Quanto della card laterale è dentro lo schermo, in frazione della sua
       larghezza: 382 di 472. È lo stesso numero due volte — dice dove sta
       (sporge di quel tanto dal bordo) e di quanto deve traslare per uscire del
       tutto. Tenerlo uno solo è ciò che garantisce che esca esatta. */
    --side-peek: 0.8093;

    /* Fra il fondo del titolo e la cima dei riquadri il design mette 40px: il
       titolo sta a y=160 alto 128, la fila a y=328 (nodo 649:2383). Non è un
       token perché la scala dei passi non ha 2,5rem, e sta qui perché lo stesso
       numero serve ai due layout — nello statico è il `gap` della griglia, in
       quello animato la distanza da cui il titolo è ancorato alla fila. */
    --intro-gap: 2.5rem;

    position: relative;
    color: var(--color-scene-text);
}

/* Il fondo scuro sta sui **riquadri**, non sulla sezione: nel design le tre card
   a riposo stanno sul fondo pagina col suo pattern, e dipingerlo di nuovo lo
   coprirebbe. Sul riquadro serve, per il tempo in cui il filmato non è arrivato. */
.cards-fullscreen__card,
.cards-fullscreen__side {
    background-color: var(--color-scene-bg);
}

/* -----------------------------------------------------------------------------
   Layout statico: nessun JavaScript, movimento ridotto, o viewport stretto.
   -------------------------------------------------------------------------- */

.cards-fullscreen__viewport {
    padding-block: var(--space-section);
}

.cards-fullscreen__scene {
    position: relative;
    display: grid;
    gap: var(--intro-gap);
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

/* Nel design è un **titolo di sezione in display**: 72px su 64 di interlinea,
   peso 900, maiuscolo, centrato, col riempimento sfumato — nel Make era invece un
   paragrafo a 40px in tondo. La classe `.display-gradient` la mette il PHP, così
   il riempimento resta dichiarato una volta in base.css. */
.cards-fullscreen__intro {
    /* Niente `margin` qui: lo possiede `.display-gradient` (base.css), che ci mette
       un negativo per compensare il proprio padding. Un `margin: 0` in questa regola
       lo azzererebbe — stessa specificita', ma il CSS del modulo carica dopo — e
       l'accento delle maiuscole tornerebbe tagliato. Il reset di base.css lo azzera
       gia' per tutti. */
    font-size: var(--text-display);
    line-height: var(--leading-display);
    font-weight: var(--weight-black);
    text-transform: uppercase;
    text-align: center;
    font-feature-settings: "lnum", "pnum";
}

/* Ogni riga è un blocco, così l'interlinea si applica alla riga e non all'intero
   paragrafo. Le interruzioni arrivano dai campi ACF: sono scelte in redazione,
   non l'andare a capo automatico. */
.cards-fullscreen__line {
    display: block;
}

/* Le card laterali servono solo a uscire di scena. Nel layout statico la scena
   non c'è, quindi non ci sono nemmeno loro. */
.cards-fullscreen__side {
    display: none;
}

.cards-fullscreen__card {
    position: relative;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    border-radius: var(--radius-l);
}

/* In statico la card mostra la prima tappa e basta: i media sono tutti
   sovrapposti, e senza questa regola si vedrebbe solo l'ultimo. Hanno
   `preload="none"`, quindi restano sui rispettivi poster senza scaricare nulla. */
.cards-fullscreen__media:not(:first-child) {
    display: none;
}

.cards-fullscreen__media {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

.cards-fullscreen__overlay {
    position: absolute;
    inset: 0;
    background-color: #000;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--duration-slow) var(--ease-in-out);
}

.cards-fullscreen__slides {
    display: grid;
    gap: var(--space-xl);
    list-style: none;
    margin: 0;
    padding: 0;
}

.cards-fullscreen__slide {
    display: grid;
    gap: var(--space-s);
}

.cards-fullscreen__title {
    margin: 0;
    font-size: var(--text-title);
    line-height: var(--leading-solid);
    font-weight: var(--weight-black);
    text-transform: uppercase;
    font-feature-settings: "lnum", "pnum";
}

.cards-fullscreen__text {
    max-width: var(--container-narrow);
    margin: 0;
    font-size: var(--text-body-l);
    line-height: var(--leading-body-l);
}

/* -----------------------------------------------------------------------------
   Layout animato.
   -------------------------------------------------------------------------- */

/* soglia scene: 901px — vedi base.css → "Passaggio fra scene" */
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) and (min-width: 901px) {

    /* La schermata che resta in pin, più un passo per aprire la card e uno per
       tappa, più i due tratti del passaggio fra scene. Il `+ 1` è l'apertura: è
       lo stesso conto che fa il JS, ed è l'unica cosa che i due file devono
       sapere entrambi. Vedi base.css → "Passaggio fra scene". */
    .cards-fullscreen {
        height: calc(
            100vh
            + var(--scene-enter, 0px)
            + (var(--slide-count, 1) + 1) * var(--step-length)
            + var(--scene-hold, 0px)
        );
    }

    /* Qui non c'è nessuna dissolvenza d'ingresso, e non è una dimenticanza: il
       modulo porta `data-scene="after"`, quindi non si sovrappone alla scena
       sopra e `--enter` non gli viene mai scritto. Gli altri moduli-scena hanno
       in questo punto `opacity: var(--enter, 1)` e una regola `.is-entering` per
       i pointer-events — vedi services-scroll e cta-fullscreen. Se un domani
       questo modulo tornasse a sovrapporsi, vanno rimesse insieme all'attributo.
       Vedi base.css → "Passaggio fra scene". */

    .cards-fullscreen__viewport {
        position: sticky;
        inset-block-start: 0;
        height: 100vh;
        padding-block: 0;
        overflow: hidden;
    }

    .cards-fullscreen__scene {
        display: block;
        height: 100%;
        max-width: none;
        margin-inline: 0;
        padding-inline: 0;
    }

    /* Il titolo è ancorato **alla fila, non alla cima della scena**: il gap del
       design sta fra il fondo del titolo e la cima dei riquadri, e solo
       `inset-block-end` lo tiene fisso a prescindere da quante righe ha il
       titolo. La fila è centrata, quindi la sua cima è a (100% − altezza) / 2 e
       contata dal basso è (100% + altezza) / 2: da lì il gap sale.

       Ancorarlo in alto lo legava invece all'altezza del titolo. Il 14,15% del
       Make — 139px su un frame alto 982 — con due righe da 64 lasciava 34px
       invece di 40, e con una riga sola ne avrebbe lasciati 104.

       Sale di 269px mentre svanisce, che su 982 sono 27,39vh. La scena è alta
       quanto il viewport, quindi vh e percentuale della scena sono la stessa
       cosa — ma `translate` in percentuale si riferisce all'elemento, non al
       contenitore, e per questo qui è in vh.

       `translate` è una property a sé e non dentro `transform`: così il
       centramento orizzontale (-50%) e lo spostamento animato convivono in una
       sola dichiarazione, senza un wrapper il cui unico compito sarebbe tenere
       il -50%. */
    .cards-fullscreen__intro {
        position: absolute;
        inset-inline-start: 50%;
        inset-block-end: calc((100% + var(--card-h-rest)) / 2 + var(--intro-gap));
        z-index: 3;
        width: 100%;
        padding-inline: var(--gutter);
        opacity: calc(1 - var(--expand));
        translate: -50% calc(var(--expand) * -27.39vh);
        pointer-events: none;
    }

    /* Le due card laterali. Centrate sulla stessa y della centrale, sporgenti
       dai bordi, e in uscita traslano esattamente di quanto sporgono. */
    .cards-fullscreen__side {
        display: block;
        position: absolute;
        inset-block-start: calc((100% - var(--side-h)) / 2);
        width: var(--side-w);
        height: var(--side-h);
        overflow: hidden;
        border-radius: var(--radius-m);
        opacity: calc(1 - 0.6 * var(--side));
    }

    .cards-fullscreen__side--start {
        inset-inline-start: calc((var(--side-peek) - 1) * var(--side-w));
        translate: calc(var(--side) * var(--side-peek) * -100%);
    }

    .cards-fullscreen__side--end {
        inset-inline-end: calc((var(--side-peek) - 1) * var(--side-w));
        translate: calc(var(--side) * var(--side-peek) * 100%);
    }

    .cards-fullscreen__side-image {
        width: 100%;
        height: 100%;
        object-fit: cover;
        object-position: center;
    }

    /* La card centrale: da 716×380 al centro, a tutta la scena. Le quattro
       interpolazioni partono da due soli numeri, `--card-w-rest` e
       `--card-h-rest`, perché la posizione a riposo *è* il centro — non un terzo
       e un quarto valore da tenere d'accordo con i primi due.

       Si animano dimensioni e inset e non uno `scale()`: fra riposo e schermo
       pieno le proporzioni cambiano, e uno scale schiaccerebbe il filmato. È un
       elemento fuori dal flusso, quindi il ricalcolo è confinato a lui;
       `contain` lo dichiara al browser invece di lasciarglielo dedurre. */
    .cards-fullscreen__card {
        position: absolute;
        inset-inline-start: calc((100% - var(--card-w-rest)) / 2 * (1 - var(--expand)));
        inset-block-start: calc((100% - var(--card-h-rest)) / 2 * (1 - var(--expand)));
        width: calc(var(--card-w-rest) + (100% - var(--card-w-rest)) * var(--expand));
        height: calc(var(--card-h-rest) + (100% - var(--card-h-rest)) * var(--expand));
        aspect-ratio: auto;
        z-index: 1;
        contain: layout paint;
        will-change: width, height;

        /* Il raggio si chiude aprendosi. Nel Make resta 16px anche a schermo
           pieno, ma là la card finale è più larga del frame — 1850 su 1512 — e i
           suoi angoli sono fuori campo. Qui riempie lo schermo esatto, quindi
           per ottenere lo stesso risultato a video il raggio deve andare a zero. */
        border-radius: calc(var(--radius-m) * (1 - var(--expand)));
    }

    /* Tutti i media sovrapposti e trasparenti: il crossfade è la transizione di
       opacità di quello che diventa attivo. Durante l'apertura l'attivo è il
       primo — è il JS a dirlo, non un `:first-child` qui, che resterebbe acceso
       anche dopo e impedirebbe il primo crossfade. */
    .cards-fullscreen__media {
        position: absolute;
        inset: 0;
        opacity: 0;
        transition: opacity var(--duration-slow) var(--ease-in-out);
    }

    .cards-fullscreen__media:not(:first-child) {
        display: block;
    }

    .cards-fullscreen__media.is-active {
        opacity: 1;
    }

    /* Finché nessuna tappa è attiva si vede la prima. Scritta così — "se nella
       card non c'è niente di attivo" — e non con un `:first-child` fisso: quel
       selettore resterebbe acceso anche dopo, e il primo crossfade non si
       vedrebbe.

       Serve perché il layout animato lo sceglie `scripting: enabled`, che è vero
       anche se questo script non gira: un errore in un altro file lascerebbe la
       card nera. Come nella hero, il default del CSS è il fotogramma zero. */
    .cards-fullscreen__card:not(:has(.is-active)) .cards-fullscreen__media:first-child {
        opacity: 1;
    }

    /* Il velo nero arriva quando la card ha finito di aprirsi, non durante:
       serve a rendere leggibile il testo, e il testo compare in quel momento. */
    .cards-fullscreen.is-open .cards-fullscreen__overlay {
        opacity: var(--cards-overlay, 0.6);
    }

    /* Le tappe, tutte impilate al centro dello schermo sopra la card. */
    .cards-fullscreen__slides {
        display: block;
        position: absolute;
        inset-block-start: 50%;
        inset-inline-start: 50%;
        z-index: 2;
        width: 100%;
        padding-inline: var(--gutter);
        translate: -50% -50%;
        opacity: 0;
        pointer-events: none;
        transition: opacity var(--duration-slow) var(--ease-in-out);
    }

    .cards-fullscreen.is-open .cards-fullscreen__slides {
        opacity: 1;
    }

    .cards-fullscreen__slide {
        display: flex;
        position: absolute;
        inset-inline: var(--gutter);
        inset-block-start: 0;
        flex-direction: column;
        align-items: center;
        gap: var(--space-s);
        translate: 0 -50%;
        text-align: center;
    }

    /* 128px su 104 d'interlinea e -3,84px di tracking nel Make: sono 8,47vw,
       0,8125 e -0,03em. Non è `--text-display`, che si ferma a 4,5rem: questo
       Make usa un corpo più grande di quello della home, e finché la scala
       tipografica vera non arriva il valore resta locale al modulo. */
    .cards-fullscreen__title {
        font-size: clamp(2.5rem, 8.47vw, 8rem);
        line-height: 0.8125;
        letter-spacing: -0.03em;
        opacity: 0;
        translate: 0 16px;
        transition:
            opacity var(--duration-slow) var(--ease-in-out),
            translate var(--duration-slow) var(--ease-in-out);
    }

    /* 24px su 32, peso 600. Il ritardo di 80ms è quello del Make: il sottotitolo
       entra un soffio dopo il titolo, non insieme. */
    .cards-fullscreen__text {
        max-width: 42rem;
        font-size: clamp(1.125rem, 1.59vw, 1.5rem);
        line-height: 1.333;
        font-weight: var(--weight-semibold);
        opacity: 0;
        translate: 0 12px;
        transition:
            opacity var(--duration-slow) var(--ease-in-out) 80ms,
            translate var(--duration-slow) var(--ease-in-out) 80ms;
    }

    .cards-fullscreen__slide.is-active :is(.cards-fullscreen__title, .cards-fullscreen__text) {
        opacity: 1;
        translate: 0 0;
    }
}
