/* =============================================================================
   Modulo: i passi di un processo su una ruota.

   Nodo di design 1278:3990, `cerchio test movimento mappatura`. Le misure, per
   non doverle ricercare: cerchio Ø560 col centro a metà del frame, punti Ø12,
   8px fra un punto e la sua etichetta, etichette `label-sm` al 70%; il passo in
   evidenza sta **alle tre**, col nome in `title-upper-sm` e il paragrafo in
   `body-sm` a 38px dal punto, su una colonna da 560; al centro il titolo della
   sezione in `title-upper-md` col riempimento sfumato; in basso a destra due
   pulsanti da 56 distanti 24, a 32px dai bordi del frame.

   Due layout, e il primo è quello che si legge per default:

     1. **una lista numerata**, con tutti i testi visibili. È quel che si vede
        sotto la soglia, senza JavaScript, e in stampa;
     2. **la ruota**, nel blocco in fondo. Chiede `scripting: enabled` perché
        senza JS non ci sarebbe modo di cambiare passo, e il modulo mostrerebbe
        un testo su otto.

   ⚠ **`prefers-reduced-motion` non spegne la ruota**, a differenza dei
   moduli-scena: qui il movimento non è il modulo, è il modo in cui cambia. Con
   la preferenza attiva la ruota c'è e funziona, ma il giro è istantaneo — lo
   azzera il blocco di base.css, che mette `transition-duration: 0.01ms` su
   tutto. Il JS lo sa e non aspetta (vedi `steps-wheel.js`).
   ========================================================================== */

/* Il giro della ruota: **un solo numero**, scritto dal JS sulla sezione, che
   tutte le voci leggono. Registrarlo come `<angle>` è ciò che lo rende
   interpolabile: senza `@property` una custom property è una stringa, e una
   stringa non si anima — il giro sarebbe uno scatto.

   ⚠ La registrazione è **globale al documento**, non di questo file: se un
   domani un altro modulo dichiarasse `--wheel-rot` con un'altra sintassi,
   vincerebbe l'ultima registrata. Il nome è quello di questa ruota; un secondo
   modulo che ne voglia una ne prenda uno suo, o si porti questo in base.css. */
@property --wheel-rot {
    syntax: "<angle>";
    inherits: true;
    initial-value: 0deg;
}

.steps-wheel {
    /* Geometria della ruota, e **dipende da tutte e due le dimensioni della
       finestra**, non dalla sola larghezza.

       Nel frame di design il cerchio è 560 su 1512x982: il 37,04% della larghezza
       e il 57,03% dell'altezza. Prendere il minore dei due vuol dire una cosa sola —
       *il cerchio è grande come il design in rapporto al lato che sta stretto* — e
       sul frame di design i due conti danno lo stesso numero, quindi lì non cambia
       niente.

       ⚠ **Senza il conto sull'altezza la ruota resta a 560 su qualunque schermo**,
       perché in larghezza è tagliata dal massimo — come tutto il tema, che si
       ferma ai 1512 del frame. La sezione però è alta una schermata, quindi
       l'altezza che avanza diventa margine vuoto: misurato su un 27" 2K,
       351px sopra e 351 sotto contro i 177 del design. Col conto sull'altezza il
       cerchio sale a 758 e il vuoto torna a 256, cioè la stessa proporzione del
       design.

       Il minimo è il punto in cui la soglia scatta: sotto i 1200px la ruota non
       c'è più, quindi il clamp non deve reggere oltre. Il massimo è l'unico numero
       non misurato qui: le etichette sono a 12px e non crescono, quindi oltre i
       768 il cerchio comincia a fare da cornice a un testo che non lo segue. Un 2K
       ci sta sotto; un 4K ci si ferma. */
    --wheel-size: clamp(25rem, min(37.04vw, 57.03svh), 48rem);
    --wheel-radius: calc(var(--wheel-size) / 2);
    --wheel-dot: 0.75rem;

    /* Quanto l'etichetta sta **fuori** dal punto, misurato dal centro del punto:
       metà punto più gli 8px di stacco del design. In px e non in em, perché nel
       design lo stacco non cambia col corpo del testo. */
    --wheel-lead: 0.875rem;

    /* Lo stesso, per il passo in evidenza: nel design il paragrafo comincia a 38
       dal centro del punto. */
    --wheel-panel-lead: 2.375rem;
    --wheel-panel-w: clamp(20rem, 37.04vw, 35rem);

    /* Quanto dura il giro. Il JS se lo rilegge da qui — vedi il commento in
       `steps-wheel.js` — invece di avere una copia sua che diverge al primo
       ritocco. */
    --wheel-duration: var(--duration-slow);

    /* La zona morta: quanto scroll passa con la ruota già centrata e ferma prima
       che la pagina riprenda a scorrere. È **l'unica manopola** di quel
       comportamento — si applica nel blocco della ruota, qui sotto — e mezza
       schermata è all'incirca un colpo di trackpad: abbastanza perché nessuno
       attraversi la sezione senza vederla, poco perché non si senta bloccato.

       ⚠ Non è tempo, è spazio: la ruota non si ferma per mezzo secondo, si ferma
       per mezza schermata di scroll. Chi si ferma a leggerla ci resta finché
       vuole, chi tira dritto la vede comunque per intero. */
    --wheel-hold: 50svh;

    /* I due aloni del design, `glow` e `glow-soft-sm`. Sono effetti di questo
       modulo soltanto, quindi stanno qui e non in base.css. I raggi sono quelli
       dell'export SVG **raddoppiati**: Figma dichiara la deviazione standard
       della gaussiana, CSS il raggio di sfocatura, e il secondo è il doppio del
       primo. */
    --wheel-glow:
        0 0 14.77px rgb(255 255 255 / 0.5),
        0 0 29.53px rgb(255 255 255 / 0.6),
        0 0 103.37px rgb(255 255 255 / 0.6),
        0 0 206.73px rgb(255 255 255 / 1);
    --wheel-glow-soft:
        0 0 14.77px rgb(255 255 255 / 0.2),
        0 0 29.53px rgb(255 255 255 / 0.05),
        0 0 103.37px rgb(255 255 255 / 0.1),
        0 0 206.73px rgb(255 255 255 / 0.3);

    color: var(--color-text-primary);

    /* Lo stacco del design, 160 per lato, come margine: vedi `--space-module` in
       base.css.

       ⚠ **Sta sulla sezione e non su `__inner`**, dove fino al 25 settembre era
       un padding. `__inner` è la `sticky` della sosta, e il suo padding è dentro
       la propria scatola: toglierlo da lì restituisce alla schermata in pin i 160
       che le mancavano, e mette lo stacco dove gli altri moduli lo vedono. */
    margin-block: var(--space-module);
}

.steps-wheel__inner {
    position: relative;
}

.steps-wheel__stage {
    display: grid;
    /* 40px fra il titolo e quel che segue, come negli altri moduli: non è un
       passo della scala, che va da 32 a 48. */
    row-gap: 2.5rem;
}

/* `title-upper-md`: 40 su 40, peso 900, maiuscolo, centrato.

   ⚠ Niente `margin` su questo elemento: porta `.display-gradient`, che si
   allarga di `--fill-display-bleed` e si ritira con un margine negativo uguale.
   Un `margin` qui, anche `margin: 0`, azzererebbe la compensazione e lascerebbe
   la scatola cresciuta. Vedi base.css → `.display-gradient`. */
.steps-wheel__heading {
    font-size: var(--text-title);
    line-height: var(--leading-solid);
    font-weight: var(--weight-black);
    text-transform: uppercase;
    text-align: center;
}

.steps-wheel__line {
    display: block;
}

/* Il titolo e la riga sotto, 16 di stacco come nei moduli della pagina About. Nella
   ruota è questo gruppo a stare al centro del cerchio, non il solo titolo. */
.steps-wheel__header {
    display: grid;
    justify-items: center;
    gap: var(--space-s);
    text-align: center;
}

.steps-wheel__list {
    display: grid;
    row-gap: var(--space-l);
    list-style: none;
    padding: 0;
}

.steps-wheel__panel {
    display: grid;
    row-gap: var(--space-3xs);
}

/* `title-upper-sm`: 20 su 24, peso 900, maiuscolo, spaziato del 4%. */
.steps-wheel__title {
    font-size: var(--text-title-s);
    line-height: var(--leading-title-s);
    font-weight: var(--weight-black);
    letter-spacing: var(--tracking-title-s);
    text-transform: uppercase;
}

/* `body-sm`: 18 su 28. */
.steps-wheel__text {
    font-size: var(--text-body-m);
    line-height: var(--leading-body-m);
    font-weight: var(--weight-medium);
}

/* Il cerchio, i punti e le frecce esistono solo sulla ruota: nella lista
   sarebbero tre decorazioni che non decorano niente. */
.steps-wheel__ring,
.steps-wheel__dot,
.steps-wheel__controls {
    display: none;
}

/* -----------------------------------------------------------------------------
   La lista come linea del tempo.

   Dal 15 ottobre c'è il design della lista (nodo 1651:2829, «approach», a 440):
   i passi uno sotto l'altro, con una **linea a sinistra** e un punto per passo, e
   un **passo corrente** che segue lo scroll — bianco col suo alone, mentre gli altri
   restano al 70%. Il corrente è l'ultimo passo il cui punto ha superato la metà
   dello schermo, la regola dei nomi di `services-scroll` da telefono; lo sceglie il
   JS, che mette `is-tracking` sulla sezione e `is-current` sulla voce.

   ⚠ **`is-current` e non `is-active`.** La seconda è lo stato della ruota, che il JS
   conserva attraverso un resize — rientrando sopra i 1200 la ruota deve tornare
   sul passo dov'era, non su quello che lo scroll ha acceso nella lista.

   Senza JavaScript la linea e i punti ci sono, e i passi sono tutti bianchi: nessuno
   è corrente, e al 70% sarebbero tutti spenti.

   ⚠ **La media query è il complemento esatto di quella della ruota**, più sotto:
   `(scripting: enabled) and (min-width: 1200px)` negato è «sotto i 1200 *oppure*
   senza script». Così le regole di qui e di là non si incontrano mai, e nessuna
   delle due deve disfare l'altra.

   Le misure del design: punti da 12 col centro sull'asse della linea, testo a 26
   dal bordo della colonna — 12 di punto e 14 d'aria —, 48 fra due passi, 4 fra il
   nome e il paragrafo, paragrafo 16 su 22. Il punto sta a metà della riga del nome,
   cioè 6 sotto la sua cima.

   La linea è al 40% di bianco e **si accende vicino al passo corrente**: nel nodo è
   una sfumatura che sale al pieno e ridiscende in circa 90px per parte. Qui è fatta
   a tratti, un tratto per voce dal suo punto a quello dopo: il tratto che parte dal
   corrente si spegne scendendo, e quello che ci arriva si accende avvicinandosi. */
@media (max-width: 1199px), (scripting: none) {
    .steps-wheel {
        --steps-dot-y: 0.375rem;
        --steps-gap: var(--space-xl);
        --steps-spot: 5.625rem;
    }

    .steps-wheel__list {
        row-gap: var(--steps-gap);
    }

    .steps-wheel__item {
        position: relative;
        padding-inline-start: calc(var(--wheel-dot) + 0.875rem);
    }

    /* Il tratto fino al punto dopo: dal centro del proprio punto, alto quanto la
       voce più lo stacco. L'ultima voce non ce l'ha. */
    .steps-wheel__item:not(:last-child)::before {
        content: "";
        position: absolute;
        inset-block-start: calc(var(--steps-dot-y) + var(--wheel-dot) / 2);
        inset-inline-start: calc(var(--wheel-dot) / 2 - 0.5px);
        inline-size: 1px;
        block-size: calc(100% + var(--steps-gap));
        background-color: rgb(255 255 255 / 0.4);
    }

    .steps-wheel__item.is-current::before {
        background: linear-gradient(#fff, rgb(255 255 255 / 0.4) var(--steps-spot));
    }

    .steps-wheel__item:has(+ .is-current)::before {
        background: linear-gradient(
            rgb(255 255 255 / 0.4) calc(100% - var(--steps-spot)),
            #fff
        );
    }

    .steps-wheel__dot {
        display: block;
        position: absolute;
        inset-block-start: var(--steps-dot-y);
        inset-inline-start: 0;
        inline-size: var(--wheel-dot);
        aspect-ratio: 1;
        border-radius: var(--radius-full);
        background-color: #909090;
        transition:
            background-color var(--duration-base) var(--ease-out),
            box-shadow var(--duration-base) var(--ease-out);
    }

    .steps-wheel__text {
        font-size: var(--text-body-s);
        line-height: var(--leading-body-s-snug);
    }

    .steps-wheel.is-tracking .steps-wheel__panel {
        color: var(--color-text-secondary);
        transition: color var(--duration-base) var(--ease-out);
    }

    .steps-wheel.is-tracking .is-current .steps-wheel__panel {
        color: var(--color-text-primary);
    }

    .steps-wheel.is-tracking .is-current .steps-wheel__title {
        text-shadow: var(--wheel-glow-soft);
    }

    .steps-wheel.is-tracking .is-current .steps-wheel__dot {
        background-color: #fff;
        box-shadow: var(--wheel-glow);
    }
}

/* -----------------------------------------------------------------------------
   La ruota.

   soglia ruota: 1200px. Non è la soglia delle scene: là si tratta di mettere in
   pin una schermata, qui di far stare attorno a un cerchio otto etichette che
   sono lunghe quanto sono lunghe. Il conto è questo, sulla colonna di contenuto:
   l'etichetta più lunga del design è 219px, e a 1200 di finestra restano 250px a
   sinistra del cerchio — sotto, comincerebbero a uscire dallo schermo.

   `scripting: enabled` perché la ruota **è** il JavaScript: senza, il passo in
   evidenza resterebbe il primo per sempre e gli altri sette testi sarebbero
   invisibili. Senza JS vale il blocco qui sopra, che li mostra tutti.
   -------------------------------------------------------------------------- */

@media (scripting: enabled) and (min-width: 1200px) {

    /* Una schermata **più la zona morta**: l'altezza in più è il tratto che si
       percorre mentre la ruota sta ferma in pin. Vedi `.steps-wheel__inner`.

       ⚠ **Deve essere altezza, non `padding-block-end`.** Una `sticky` si muove
       dentro il **content box** del genitore, e il padding non ne fa parte: con
       l'altezza in più messa come padding la ruota ha esattamente la propria
       altezza di corsa, cioè zero, e si sgancia nell'istante in cui si è
       inchiodata. È il primo modo di scriverlo e non dà nessun errore — la
       sezione è più alta, la sosta semplicemente non c'è. Misurato: la ruota
       usciva dallo schermo con la sezione, `innerTop` a −450 dove doveva essere
       0. */
    .steps-wheel {
        min-block-size: calc(100svh + var(--wheel-hold));
        transition: --wheel-rot var(--wheel-duration) var(--ease-scene);
    }

    /* Alta una schermata come il frame del design, col cerchio nel mezzo. Le
       frecce si appoggiano al suo angolo in basso a destra, quindi la schermata
       è anche ciò che le mette dove il design le vuole.

       ⚠ **La sosta è una `sticky`, non un aggancio.** Uno `scroll-snap-align`
       non ferma nessuno: `base.css` aggancia in `proximity` — e deve restare
       così, con `mandatory` ogni pausa in mezzo a una scena diventa uno strappo
       — quindi porterebbe la ruota al centro solo a chi si è già fermato lì
       vicino, che è esattamente chi non ha bisogno di essere fermato. La sezione
       è invece alta una schermata **più la zona morta**, e questo elemento è
       alto una schermata e si inchioda in cima: il contenuto è centrato dentro
       di lui, quindi si inchioda **nell'istante in cui è centrato a schermo** e
       ci resta per tutta la zona morta.

       ⚠ **I conti tornano da sé e non c'è niente da sommare altrove.** Quando
       la sosta finisce, il fondo della sezione è esattamente il fondo della
       finestra: la zona morta non lascia nessuna banda in più, si vede la ruota
       ferma e poi la ruota che se ne va. Quel che segue è lo stacco fra moduli
       come ovunque — `--space-module` sulla sezione — e non un residuo della
       sosta. Verificato in headless.

       ⚠ **Sta dentro il blocco della ruota**, quindi sotto i 1200px e senza
       JavaScript non c'è: là il modulo è una lista numerata alta quanto il suo
       testo, e una schermata di scroll fermo su una lista sarebbe solo scroll
       morto. */
    .steps-wheel__inner {
        display: grid;
        align-content: center;
        position: sticky;
        inset-block-start: 0;
        min-block-size: 100svh;
    }

    /* La scatola del cerchio, spinta a destra di quanto serve al passo in
       evidenza: così il punto delle tre — il bordo destro del cerchio — resta a
       38px dalla colonna del testo, e a sinistra avanza esattamente lo spazio
       delle etichette. Con la colonna da 1448 del design il cerchio comincia a
       x=322 e il testo finisce a 1480, che sono i numeri del frame.

       `place-content: center` perché il titolo al centro è **in flusso**: è
       l'unico figlio che lo sia, e centrarlo con la griglia invece che con
       `translate` è ciò che lascia annullare i margini negativi di
       `.display-gradient`. */
    .steps-wheel__stage {
        position: relative;
        inline-size: var(--wheel-size);
        block-size: var(--wheel-size);
        place-content: center;
        row-gap: 0;
        margin-inline-start: auto;
        margin-inline-end: calc(var(--wheel-panel-lead) + var(--wheel-panel-w));
    }

    /* Il titolo al centro sta dentro il cerchio: 70% del diametro è poco meno
       del quadrato inscritto, e nel design la riga più lunga ne occupa il 62%.

       ⚠ **In `calc()` sul diametro, non in percentuale.** Una percentuale qui si
       misura sulla cella della griglia, che è dimensionata sul contenuto, che
       dipende dalla percentuale: il cerchio è fatto, e il browser lo rompe
       dimensionando la cella sul `max-content` e prendendone il 70% — 243px, la
       larghezza della parola `END-TO-END`. Misurato prima e dopo: la scatola
       veniva 243,5 e il titolo occupava tre righe invece di due.

       Sta sul gruppo e non sul titolo, così anche la riga sotto resta dentro il
       cerchio e va a capo sulla stessa larghezza. */
    .steps-wheel__header {
        inline-size: calc(var(--wheel-size) * 0.7);
    }

    /* Il cerchio. Il tratto **non è uniforme**: nell'export del nodo 1278:3994 è
       un gradiente orizzontale che va da bianco al 80% sul bordo destro — dove
       sta il passo in evidenza — a bianco al 30% dopo il 19,88% della corsa, e
       da lì resta piatto. È l'unico punto del modulo in cui il design dice dove
       guardare.

       Il `border` è il caso senza maschera: un tratto piatto al 30% è quel che il
       gradiente è per l'80% della sua corsa. Dentro il `@supports` diventa il
       gradiente vero — `border-image` non rispetta `border-radius` e
       `border-color` non accetta una sfumatura, quindi la strada è un fondo
       pieno mascherato alla sola cornice. */
    .steps-wheel__ring {
        display: block;
        position: absolute;
        inset: 0;
        border: 1px solid rgb(255 255 255 / 0.3);
        border-radius: 50%;
        /* `glow-soft-sm`, ridotto al primo dei quattro aloni: `drop-shadow`
           segue la trasparenza, quindi sfoca l'anello e non il disco, ma è un
           filtro e costa — gli altri tre, che sono da 30 a 207px di raggio su un
           tratto di un pixel, a schermo non arrivano. */
        filter: drop-shadow(0 0 14.77px rgb(255 255 255 / 0.2));
    }

    @supports (mask-composite: exclude) {
        .steps-wheel__ring {
            border: 0;
            padding: 1px;
            background: linear-gradient(
                to left,
                rgb(255 255 255 / 0.8),
                rgb(255 255 255 / 0.3) 19.88%
            );
            mask:
                linear-gradient(#000 0 0) content-box,
                linear-gradient(#000 0 0);
            mask-composite: exclude;
        }
    }

    /* La lista non è più una pila: è il piano su cui stanno i punti, e ogni voce
       è un punto solo — larghezza e altezza zero, al centro del cerchio. Quel che
       si vede sono i suoi due figli, che da lì si spostano. */
    .steps-wheel__list {
        display: block;
        position: absolute;
        inset: 0;
        row-gap: 0;
    }

    /* L'angolo di una voce, e con lui tutto il resto.

       `--i` è la posizione e arriva dal PHP; `--step-count` sta sulla sezione;
       `--wheel-rot` è il giro, e lo scrive il JS. La prima voce è quindi a 0°,
       cioè **alle tre**, che è il posto in evidenza: con `--wheel-rot: 0` la
       pagina si apre già composta, senza che il JavaScript debba raddrizzarla.

       `--dx` e `--dy` sono la direzione in cui l'etichetta si allontana dal
       punto, normalizzata sulla componente maggiore: valgono ±1 sui quattro assi
       e ancora ±1 sulle diagonali, che è la regola del design — l'etichetta di
       una diagonale sta sopra o sotto il punto, allineata al suo bordo, non
       spostata in obliquo. Passando da una posizione all'altra cambiano con
       continuità, quindi l'etichetta non salta mentre la ruota gira.

       ⚠ La divisione per una custom property è CSS Values 4, non `calc()` di
       sempre. Verificata in headless su Chromium, WebKit e Firefox insieme a
       `cos()`, `sin()` e alla transizione di `--wheel-rot`: senza una delle tre
       la ruota non si compone. */
    .steps-wheel__item {
        --a: calc(var(--i) * 360deg / var(--step-count) + var(--wheel-rot));
        --cos: cos(var(--a));
        --sin: sin(var(--a));
        --far: max(var(--cos), calc(-1 * var(--cos)), var(--sin), calc(-1 * var(--sin)));
        --dx: calc(var(--cos) / var(--far));
        --dy: calc(var(--sin) / var(--far));

        position: absolute;
        inset-block-start: 50%;
        inset-inline-start: 50%;
        inline-size: 0;
        block-size: 0;

        /* I quattro livelli di bianco del design: le voci spente stanno a 0,7,
           quella in evidenza a 1. */
        opacity: 0.7;
        transition: opacity var(--wheel-duration) var(--ease-scene);
    }

    /* La voce scelta, e quella sotto il puntatore o a fuoco. Il design non dice
       cosa fa lo hover — le sue tre schermate sono tre stati di riposo — ma un
       nome che si può premere deve dirlo prima di essere premuto, e il quarto
       livello di bianco del sistema è proprio questo: 0,7 spento, pieno acceso. */
    .steps-wheel__item.is-active,
    .steps-wheel__item:has(.steps-wheel__name:is(:hover, :focus-visible)) {
        opacity: 1;
    }

    /* Il punto. `translate` porta il centro sul cerchio, e la metà del punto lo
       centra lì sopra. */
    .steps-wheel__dot {
        display: block;
        position: absolute;
        inline-size: var(--wheel-dot);
        block-size: var(--wheel-dot);
        border-radius: 50%;
        background-color: var(--color-scene-text);
        translate:
            calc(var(--wheel-radius) * var(--cos) - var(--wheel-dot) / 2)
            calc(var(--wheel-radius) * var(--sin) - var(--wheel-dot) / 2);
        transition: box-shadow var(--wheel-duration) var(--ease-scene);
    }

    /* L'alone del design, sul solo punto in evidenza. `box-shadow` e non
       `filter`: il punto è un disco pieno, quindi l'ombra della sua scatola *è*
       l'alone del disco, e costa molto meno di quattro sfocature. */
    .steps-wheel__item.is-active .steps-wheel__dot {
        box-shadow: var(--wheel-glow);
    }

    /* L'etichetta, e per la voce in evidenza il paragrafo.

       Due trasformazioni che si compongono, e sono due cose diverse: `translate`
       la porta sul punto, `transform` la sposta **rispetto a se stessa** —
       metà della propria scatola indietro, più la direzione radiale. Con
       `--dx: 1` il bordo sinistro cade sul punto, con `--dx: -1` il destro, con
       `--dx: 0` la scatola è centrata: sono le tre alternative del design, e qui
       sono la stessa riga. */
    .steps-wheel__panel {
        position: absolute;
        inline-size: max-content;
        row-gap: var(--space-3xs);
        translate:
            calc(var(--wheel-radius) * var(--cos))
            calc(var(--wheel-radius) * var(--sin));
        transform: translate(
            calc(var(--dx) * (50% + var(--wheel-lead)) - 50%),
            calc(var(--dy) * (50% + var(--wheel-lead)) - 50%)
        );
    }

    /* `label-sm`: 12 su 16, peso 600, maiuscolo, spaziato del 12%. Su una riga
       sola: un'etichetta che va a capo cambierebbe la propria scatola, e la
       scatola è ciò su cui si allinea al punto. */
    .steps-wheel__title {
        font-size: var(--text-label);
        line-height: var(--leading-label);
        font-weight: var(--weight-semibold);
        letter-spacing: var(--tracking-label);
        white-space: nowrap;
        transition:
            font-size var(--duration-base) var(--ease-scene),
            letter-spacing var(--duration-base) var(--ease-scene),
            text-shadow var(--duration-base) var(--ease-scene);
    }

    /* Il pulsante lo costruisce il JS attorno al testo che c'è già. Non ha
       aspetto proprio: eredita tutto dal titolo, e l'unico segno che si può
       premere è il puntatore — più il focus, che base.css disegna su tutto. */
    .steps-wheel__name {
        appearance: none;
        display: block;
        padding: 0;
        border: 0;
        background: none;
        color: inherit;
        font: inherit;
        letter-spacing: inherit;
        text-align: inherit;
        text-transform: inherit;
        cursor: pointer;
    }

    /* La piega. Da 0fr a 1fr è l'unico modo di animare un'altezza automatica: la
       riga della griglia passa da zero all'altezza del contenuto, e il figlio
       ritaglia quel che eccede.

       Mentre si apre, la scatola della voce cresce: il `-50%` del `transform`
       qui sopra si ricalcola a ogni frame, quindi il nome **sale** man mano che
       il paragrafo compare, e il gruppo resta centrato sul punto come nel
       design. */
    .steps-wheel__fold {
        display: grid;
        grid-template-rows: 0fr;
        transition: grid-template-rows var(--duration-base) var(--ease-scene);

        /* ⚠ **Larga zero, non solo alta zero.** La scatola della voce è
           `max-content`, e il `max-content` di un paragrafo è tutto il paragrafo
           su una riga: un testo chiuso ma largo 1374px allargava l'etichetta che
           gli sta sopra, e l'etichetta si allinea al punto **in proporzione alla
           propria larghezza** — quindi finiva a mezzo schermo di distanza. Non si
           vedeva come un testo di troppo, si vedeva come un'etichetta nel posto
           sbagliato. Aperta, la scatola ha una larghezza dichiarata e il
           `max-content` non conta più. */
        inline-size: 0;
    }

    .steps-wheel__text {
        overflow: hidden;
        opacity: 0;
        transition: opacity var(--duration-base) var(--ease-scene);
    }

    /* Il passo in evidenza. `is-open` non è `is-active`: la prima dice *sei il
       passo scelto* e scatta al click, la seconda *sei arrivato*, e la mette il
       JS a giro finito.

       ⚠ **Le due classi sono separate per la larghezza.** `max-content` e 560px
       non si interpolano, quindi la colonna del testo compare di scatto: se
       succedesse al click, la voce in arrivo — che in quel momento è ancora su
       una diagonale — si sposterebbe di lato di colpo, perché la sua scatola si
       allinea al punto in proporzione alla propria larghezza. A giro finito
       invece `--dx` vale esattamente 1, il bordo sinistro è già sul punto e
       allargare la scatola non muove niente. */
    .steps-wheel__item.is-open .steps-wheel__panel {
        inline-size: var(--wheel-panel-w);
        transform: translate(
            calc(var(--dx) * (50% + var(--wheel-panel-lead)) - 50%),
            calc(var(--dy) * (50% + var(--wheel-panel-lead)) - 50%)
        );
    }

    /* `title-upper-sm` con l'alone del design: 20 su 24, peso 900, spaziato del
       4%. */
    .steps-wheel__item.is-open .steps-wheel__title {
        font-size: var(--text-title-s);
        line-height: var(--leading-title-s);
        font-weight: var(--weight-black);
        letter-spacing: var(--tracking-title-s);
        white-space: normal;
        text-shadow: var(--wheel-glow-soft);
    }

    .steps-wheel__item.is-open .steps-wheel__fold {
        grid-template-rows: 1fr;
        inline-size: auto;
    }

    .steps-wheel__item.is-open .steps-wheel__text {
        opacity: 1;
    }

    /* Le frecce, nell'angolo in basso a destra della schermata: 32px dai bordi,
       che è il margine di pagina. Il contenitore è `.steps-wheel__inner`, cioè il
       `.container`, quindi oltre i 1512 restano appese alla colonna invece che al
       bordo della finestra. */
    .steps-wheel__controls {
        display: flex;
        gap: var(--space-m);
        position: absolute;
        inset-block-end: var(--gutter);
        inset-inline-end: var(--gutter);
    }

    .steps-wheel__nav {
        display: grid;
        place-items: center;
        inline-size: 3.5rem;
        aspect-ratio: 1;
        padding: 0;
        border: 1px solid var(--color-text-secondary);
        border-radius: var(--radius-full);
        background: none;
        color: var(--color-text-secondary);
        cursor: pointer;
        transition:
            border-color var(--duration-base) var(--ease-out),
            color var(--duration-base) var(--ease-out);
    }

    .steps-wheel__nav:is(:hover, :focus-visible) {
        border-color: var(--color-text-primary);
        color: var(--color-text-primary);
    }

    /* La freccia indietro è **la stessa icona specchiata**, non un secondo file.
       `scale: -1 1` e non `rotate: 180deg`: la rotazione ribalta anche l'asse
       verticale, che su un chevron simmetrico non si vede, ma lo specchio è
       quello che si intende. */
    .steps-wheel__nav--prev > svg {
        scale: -1 1;
    }
}
