/* =============================================================================
   Modulo: il muro dei loghi dei brand.

   Due modi, e il PHP scrive quale con una classe sola: la griglia ferma del
   design fino a sedici loghi, il carosello infinito da lì in su. Le celle, gli
   spazi e le altezze sono gli stessi nei due modi — cambia se la riga va a capo
   o scorre.

   Il layout fermo è il default, e quello in movimento sta dentro
   `@media (prefers-reduced-motion: no-preference)`: è la stessa struttura dei
   moduli-scena, senza `scripting: enabled` perché qui non c'è JavaScript da
   aspettare.
   ========================================================================== */

.logo-wall {
    /* --- Geometria del design (nodo 649:2468) -------------------------------
       Su un contenitore da 1448: cella 285,95 × 94,02, spazio fra le celle
       101,4. Le frazioni sono su 1448 e tornano a 100 — 4 × 19,7481 più
       3 × 7,0021 — quindi quattro celle riempiono la riga esatta.

       Sono `cqw` e non `%`. Nel carosello la cella sta dentro la pista, che è il
       doppio della riga, e una percentuale si riferirebbe a quella: le celle
       verrebbero larghe il doppio. Il contenitore di query è
       `.logo-wall__inner`, quindi `100cqw` è la larghezza utile del contenitore
       — 1448 sul frame del design — in tutti e due i modi.

       ⚠ **Il contenitore di query non può essere `.logo-wall__rows`**, e sembra
       il posto naturale. Nella griglia le celle vanno a capo dentro quel flex,
       quindi è lui a portare il `column-gap`: un elemento però non interroga se
       stesso, e quel `cqw` cadrebbe sul contenitore più esterno — non essendocene
       nessuno, sul viewport. Misurato: `gap` 105,86 invece di 101,38 (il 7% di
       1512 invece che di 1448), 4 celle più 3 spazi oltre il 100%, e la riga
       andava a capo con **tre** celle invece di quattro. Il difetto è silenzioso:
       le celle hanno la misura giusta, è la somma che non ci sta. */
    --logo-columns: 2;
    --logo-gap: 7.0021cqw;
    --logo-cell: calc((100cqw - (var(--logo-columns) - 1) * var(--logo-gap)) / var(--logo-columns));

    /* L'altezza **non** segue la larghezza della cella. La cella si allarga
       quando le colonne diminuiscono, e un logo alto il doppio su un telefono
       sarebbe un errore: l'altezza è una frazione del contenitore, 94,02 su
       1448, con un minimo perché sotto i 56px un logo non si legge. */
    --logo-height: clamp(3.5rem, 6.4928cqw, 5.875rem);

    /* Secondi per logo, cioè la velocità del carosello: la durata del ciclo è
       questo numero per quanti loghi ha la riga, così due righe con un numero
       diverso di loghi scorrono alla stessa velocità e non nello stesso tempo.
       Un passo — cella più spazio — sono 387px sul contenitore del design: a 6s
       fanno circa 65px al secondo. È il valore da toccare se il movimento
       sembra lento o nervoso. */
    --logo-pace: 6s;

    /* 80px fra il titolo e i loghi: nel design il titolo sta a y 160 alto 192 e
       le righe cominciano a 432. Come in `cards-fullscreen`, non è un token
       perché la scala dei passi non ha 5rem. */
    --intro-gap: 5rem;

    /* La dissolvenza ai bordi delle righe che scorrono. Sta qui e non nella
       regola perché la larghezza è la cosa da toccare, non il gradiente; ed è
       dichiarata anche fuori dal carosello di proposito, così un domani una riga
       ritagliata per un altro motivo può riusarla.

       Il gradiente è simmetrico, quindi `to right` va bene in tutte e sei le
       lingue senza diventare una proprietà logica. */
    --logo-fade: var(--logo-gap);
    --logo-fade-mask: linear-gradient(
        to right,
        transparent 0,
        #000 var(--logo-fade),
        #000 calc(100% - var(--logo-fade)),
        transparent 100%
    );
}

/* Il design mette 160px sopra e sotto (frame alto 1112,78, contenuto da 160 a
   952,78), che su 1512 sono 10,58vw. Non è `--space-section`, che si ferma a
   128: quello è il ritmo dello scaffolding, questo è il valore del design. */
.logo-wall__inner {
    container-type: inline-size;
    display: grid;
    gap: var(--intro-gap);
    padding-block: clamp(var(--space-3xl), 10.58vw, 10rem);
}

/* ⚠ Nessun `justify-items: center` qui: centrerebbe anche le righe, che si
   dimensionerebbero al contenuto invece di riempire il contenitore, e da lì
   tutte le larghezze delle celle sarebbero sbagliate in silenzio. È l'errore
   che è già costato la pista del carosello — vedi case-carousel.css. Il titolo
   si centra col proprio `text-align`. */
.logo-wall__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 dal campo ACF. */
.logo-wall__line {
    display: block;
}

/* -----------------------------------------------------------------------------
   La griglia ferma: il default, e anche il layout con movimento ridotto.

   ⚠ **Qui le righe del PHP non esistono.** `display: contents` scioglie i tre
   contenitori — riga, pista, lista — e i loghi diventano figli di questo flex,
   che va a capo da sé: 48px fra una riga e l'altra (`--space-xl`, il valore del
   design) e `--logo-gap` fra le celle.

   È voluto, e la ragione è che **il numero di colonne cambia col viewport
   mentre la composizione del PHP no**. Una riga da quattro loghi su tre colonne
   andrebbe a capo 3+1, cioè un orfano per riga: quattro righe da quattro
   diventerebbero otto righe alternate 3, 1, 3, 1. Sciolte, l'unica cosa che
   decide la forma è `--logo-columns`, e il PHP non ne sa niente.

   Quattro celle più tre spazi fanno esattamente 100cqw, quindi una riga piena è
   a filo dei bordi come nel design, che la compone con `space-between`. Il
   `center` serve all'ultima riga, quando è parziale: al centro e non spalancata
   ai due bordi.

   `list-style` si eredita, quindi vale sui `li` anche con la lista a
   `display: contents`; `role="list"` nel PHP rimette la semantica che
   `display: contents` porta via.
   -------------------------------------------------------------------------- */

.logo-wall__rows {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-xl) var(--logo-gap);
}

.logo-wall__row,
.logo-wall__track,
.logo-wall__set {
    display: contents;
}

.logo-wall__set {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* La copia esiste solo per chiudere il ciclo del carosello. Qui non c'è ciclo,
   quindi non c'è copia — e questa è anche la versione che si vede con
   `prefers-reduced-motion`, dove una riga da dieci loghi si scioglie nella
   griglia e si vedono tutti, invece di restarne quattro visibili e sei tagliati. */
.logo-wall__set[aria-hidden="true"] {
    display: none;
}

.logo-wall__item {
    flex: 0 0 var(--logo-cell);
    height: var(--logo-height);
}

/* ⚠ `contain`, non `cover`, e la differenza è tutta nel fatto che i loghi qui
   sono contenuto. In Figma il fill risulta `cover` perché ogni PNG è stato
   esportato **già della misura della propria cella**, quindi le proporzioni
   combaciano e non ritaglia niente. I loghi che carica l'editor hanno
   proporzioni qualunque: `cover` ne taglierebbe i bordi, e un logo tagliato è un
   marchio usato male. `contain` lo iscrive nella cella e lo centra.

   Le due misure sono esplicite e non `auto`: un elemento sostituito senza
   dimensioni prende le proprie intrinseche, e la cella non conterrebbe niente. */
.logo-wall__logo {
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center;
}

@media (min-width: 48rem) {
    .logo-wall {
        --logo-columns: 3;
    }
}

@media (min-width: 901px) {
    .logo-wall {
        --logo-columns: 4;
    }
}

/* -----------------------------------------------------------------------------
   Il carosello infinito.

   La pista contiene i loghi due volte e trasla di **una copia più uno spazio**:
   arrivata là, la seconda copia occupa esattamente il posto in cui era la prima,
   quindi il salto all'inizio del ciclo non si vede. La pista è larga
   `2S + G`, dove S è una copia e G lo spazio, e una copia più uno spazio è
   `(2S + G + G) / 2`, cioè `(100% + G) / 2`: da qui il `calc()` nella keyframe.

   ⚠ **Perché quattro loghi sono il minimo.** Perché non si veda un buco, la
   finestra che si scopre traslando deve essere coperta dalla copia: serve
   `S >= V`, dove V è la riga visibile. Con n loghi e c colonne, `S` sono n celle
   e n−1 spazi e `V` c celle e c−1 spazi, quindi la condizione è **n >= c**: una
   riga deve avere almeno tanti loghi quante colonne si vedono. Le colonne sono
   al massimo quattro, e sopra i sedici loghi la riga più corta ne ha sempre
   almeno quattro — vedi il PHP. Il quattro del design e il quattro della soglia
   sono lo stesso quattro.

   Ai due bordi i loghi **si dissolvono invece di tagliarsi**, con una maschera
   sfumata larga uno spazio. Il ritaglio cade al contenitore, a 32px dal bordo
   dello schermo, dove la pagina continua: un logo tagliato netto lì sembra finito
   sotto un riquadro invisibile, mentre dissolvendosi sembra che entri ed esca
   dalla fila. Vale **solo qui**: nella griglia non c'è niente da tagliare, e la
   maschera velerebbe la prima e l'ultima colonna di una fila già allineata.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
    /* Qui le righe tornano a essere righe: una pila di una colonna, e ognuna
       ritaglia la propria pista. */
    .logo-wall--scroll .logo-wall__rows {
        display: grid;
        gap: var(--space-xl);
    }

    /* `overflow: hidden` resta: la maschera sfuma solo la sua fascia, oltre quella
       il contenuto va ritagliato comunque.

       La fascia è larga uno spazio fra le celle — 101px sul contenitore del
       design — perché è la misura di vuoto che il modulo ha già: un logo comincia
       a comparire dov'è finito il precedente. `--logo-fade` è la manopola.

       Il prefisso `-webkit-` non è di troppo: `mask-image` senza prefisso è
       arrivato in Chrome 120 e in Safari 15.4, e questo tema non ha un
       autoprefixer. Stessa ragione del `-webkit-background-clip` di base.css. */
    .logo-wall--scroll .logo-wall__row {
        display: block;
        overflow: hidden;
        -webkit-mask-image: var(--logo-fade-mask);
        mask-image: var(--logo-fade-mask);
    }

    /* Lo spazio è lo stesso dentro una copia e fra le due: è questo che rende il
       passo uniforme anche sulla cucitura, e quindi il ciclo invisibile. */
    .logo-wall--scroll .logo-wall__track,
    .logo-wall--scroll .logo-wall__set,
    .logo-wall--scroll .logo-wall__set[aria-hidden="true"] {
        display: flex;
        flex-wrap: nowrap;
        justify-content: flex-start;
        gap: var(--logo-gap);
    }

    /* `width: max-content` è quello che rende vero il `-100%` della keyframe: la
       pista è un blocco, quindi da sola sarebbe larga quanto la riga, e le celle
       la sborderebbero senza che il `-100%` valga la loro somma. */
    .logo-wall--scroll .logo-wall__track {
        width: max-content;
        animation: logo-wall-scroll calc(var(--logo-count, 4) * var(--logo-pace)) linear infinite;
        will-change: translate;
    }

    /* Prima riga a sinistra, seconda a destra, terza a sinistra, quarta a
       destra. L'alternanza è una proprietà della posizione nella pila, quindi la
       sa il CSS da sé: nessun attributo dal PHP, e aggiungere una riga non
       richiede di ricordarsi il verso. */
    .logo-wall--scroll .logo-wall__row:nth-child(even) .logo-wall__track {
        animation-direction: reverse;
    }

    /* Un movimento che parte da solo e non finisce mai deve potersi fermare
       (WCAG 2.2.2). `prefers-reduced-motion` copre chi l'ha chiesto al sistema;
       questo copre chi si ferma sul logo per leggerlo, col mouse o col Tab. */
    .logo-wall--scroll .logo-wall__row:hover .logo-wall__track,
    .logo-wall--scroll .logo-wall__row:focus-within .logo-wall__track {
        animation-play-state: paused;
    }
}

@keyframes logo-wall-scroll {
    from {
        translate: 0;
    }

    to {
        translate: calc((-100% - var(--logo-gap)) / 2);
    }
}
