/*
 * Tema `chplus` — CH+ architecture partners.
 *
 * L'impaginazione e' quella di bergmeisterwolf.it, riprodotta dai valori del suo
 * foglio di stile e non a occhio: container 1330px, corpo 1.125rem/1.625rem in
 * #b2b2b2, sezioni a 50px, fondo grigio #f7f8f8, transizione
 * cubic-bezier(.19,1,.22,1) mezzo secondo.
 *
 * ⚠️ I caratteri si nominano per RUOLO ( --font-light / --font-book / --font-medium ),
 * mai col nome del font: la sostituzione di Berthold Imago sta tutta in `fonts.css`,
 * e questo file non deve sapere quale carattere sia arrivato.
 *
 * ⚠️ Niente Bootstrap. Il riferimento lo usa, ma qui servono sei classi di griglia
 * su dodici colonne: portarsi 120 KB per quelle e' peso che il visitatore paga.
 */

:root {
    /* ⚠️ Hanken Grotesk, non piu' DIN Alternate: il restyle su big.dk voleva lo stesso
       carattere del riferimento ( Everett, a pagamento ) — vedi il commento esteso in
       fonts.css su perche' e' Hanken Grotesk a starci al posto, con licenza libera. E'
       UN FILE CARICATO DA NOI, non piu' un font di sistema: si vede uguale su
       Mac/Windows/Android invece di cambiare a seconda di chi guarda. Tre pesi VERI,
       non piu' due: 300/400/500, quelli che il file variabile porta davvero. */
    --font-light:  'Hanken Grotesk', system-ui, sans-serif;
    --font-book:   'Hanken Grotesk', system-ui, sans-serif;
    --font-medium: 'Hanken Grotesk', system-ui, sans-serif;

    /* ⚠️ BIANCO E NERO PURO, senza tinta — la palette del riferimento ( big.dk ), che non ha
       nessun colore d'accento. --accent era il rosso mattone #bd3d20: ora e' lo stesso nero
       pieno del marchio ( --ink-strong ), a 21,0:1 sul bianco — il massimo contrasto possibile,
       non un compromesso. --accent-soft resta un grigio scuro, piu' presente di --ink ma sotto
       il nero pieno, per la stessa gerarchia di prima ( descrizione sotto un titolo evidenziato ). */
    --ink:        #808080;   /* il testo: grigio chiaro */
    --accent-soft: #4d4d4d;  /* la descrizione sotto il titolo evidenziato: grigio scuro,
                                 fra --ink e --accent. Contrasto 7,5:1 sul bianco. */
    --ink-strong: #000000;   /* il marchio, e ora anche --accent: nero pieno */
    --ink-soft:   #808080;
    --ink-faint:  #b9b9b9;   /* solo decorazioni: i puntini dello slideshow. NON testo, contrasto 2:1 */
    --heading:    var( --accent );   /* i titoli: --accent, in tutto il tema chiaro ( 21,0:1 sul bianco ) */
    --accent:     var( --ink-strong );   /* passaggio del mouse, voce attiva, puntino attivo:
                                             nero pieno, lo stesso segno del marchio — niente
                                             tinta, solo bianco/nero come il riferimento. */
    --rule:       #b9b9b9;
    --paper:      #ffffff;   /* il fondo: bianco ( l'avorio #faf7f2 provato il 2026-09-21 e' stato tolto ) */
    --paper-alt:  #f1ece4;   /* la fascia dei riconoscimenti */

    /* ⚠️ 81x32 e' la misura a cui il marchio si vede su ch-plus.com ( `.logo-holder` e'
       90px, e i glifi occupano l'89,9% di quel PNG ), e i 32 in altezza sono anche
       l'area di contenuto della testata del riferimento: le due misure combaciano.
       E' l'unica misura del logo, l'altezza la calcola il rapporto. */
    --logo-width: 81px;

    /* ⚠️ QUASI TUTTA LA PAGINA, non piu' una colonna di 1330px con due bordi larghi ai
       lati: richiesta esplicita. `min()` invece di un numero fisso: resta largo QUANTO
       LO SCHERMO ( 96vw, cioe' 2vw di margine per lato ) fin che lo schermo non supera
       gli 1875px circa, dove il tetto di 1900px prende il sopravvento — senza tetto, un
       monitor ultra-largo avrebbe righe di testo lunghe quanto tutto lo schermo, illeggibili. */
    --container:  min( 1900px, 96vw );
    --gutter:     20px;

    /* la stessa curva del riferimento, su ogni transizione */
    --ease: cubic-bezier( 0.19, 1, 0.22, 1 );

    /* ⚠️ UNA CURVA A PARTE per la crescita del progetto in elenco ( `.project-expand-panel`,
       `.project-expand-content` ): `--ease` sopra e' scattante apposta — quasi tutto il
       movimento nei primi istanti, poi ferma — giusta per un pulsante o un'ombra, ma su
       un riquadro che deve CRESCERE VISIBILMENTE sembrava uno scatto secco invece di un
       ingrandimento. Questa e' simmetrica ( accelera, poi rallenta, come un vero movimento
       fisico ) e si usa SOLO li'. */
    --ease-grow: cubic-bezier( 0.65, 0, 0.35, 1 );
}

/*
 * ⚠️ TEMA SCURO: stesse variabili di sopra, valori diversi. Un elemento le legge sempre
 * dal PIU' VICINO antenato che le dichiara — qui `<html data-theme="dark">` — quindi
 * ogni regola scritta con `var( --qualcosa )` cambia colore da sola, senza una seconda
 * copia del foglio di stile. E' il motivo per cui `--heading: var( --accent )` ( sopra )
 * non va ripetuta qui sotto: segue `--accent` da sola.
 *
 * ⚠️ L'attributo lo scrive `theme-toggle.js`, letto da un piccolo script IN LINEA nella
 * testa del documento ( vedi `default_page.php` ) — deve girare PRIMA che la pagina si
 * disegni, o la prima immagine sarebbe sempre chiara per un istante anche con lo scuro
 * gia' scelto l'ultima volta.
 *
 * Contrasti su --paper: --ink 8,6:1 ( AAA ) · --accent 21,0:1 ( AAA — e' --ink-strong, bianco
 * pieno sul nero, ridefinito qui sotto ).
 * ⚠️ --accent NON compare qui: segue --ink-strong per cascata dal `:root`, che qui sotto
 * DIVENTA bianco — quindi --accent passa da nero a bianco senza bisogno di ridichiararlo. */
:root[data-theme="dark"] {
    --paper:       #000000;
    --paper-alt:   #141414;
    --ink:         #a6a6a6;
    --ink-soft:    #8c8c8c;
    --ink-faint:   #333333;
    --ink-strong:  #ffffff;   /* il marchio, e --accent per cascata: da nero pieno a bianco pieno */
    --rule:        #2b2b2b;
    --accent-soft: #cccccc;   /* la descrizione sotto un titolo evidenziato: grigio chiaro,
                                 fra --ink e --accent — la stessa gerarchia del tema chiaro,
                                 capovolta. Contrasto 12,6:1 sul nero. */
}

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

/* ⚠️ NIENTE "SCROLL ANCHORING": e' l'abitudine del browser di tenere ferma da solo la
   porzione di pagina che si sta guardando quando il contenuto sopra o dentro di lei
   cambia misura, agganciandosi a un punto qualunque nel contenuto — utile in generale,
   ma qui litiga con lo scorrimento di centratura scritto a mano in project-expand.js
   ( `animateScrollTo`, per la scheda che si apre sul posto in `project-list.php` ):
   mentre il riquadro cresce, il browser correggeva lo scorrimento per conto suo,
   fermandolo a centinaia di pixel dal bersaglio vero. Misurato su un iPad vero, dove il
   contenuto sopra la scheda ( testata, filtri ) e' piu' alto che su un telefono o certi
   schermi da tavolo, e lo scarto si vedeva a occhio: la scheda restava tagliata invece
   che centrata. Spento su tutto il documento, non solo sul singolo riquadro che cresce:
   l'aggancio si sceglie ovunque nella pagina che scorre, non solo dentro l'elemento che
   sta cambiando misura — escludere solo quello non bastava. */
html { -webkit-text-size-adjust: 100%; overflow-anchor: none; }

body {
    margin: 0;
    background: var( --paper );
    color: var( --ink );
    font-family: var( --font-book );
    font-size: 1.125rem;
    line-height: 1.625rem;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* ⚠️ SOLO qui, sul fondo e il testo di base: e' cio' che si vede di piu' cambiando
       tema, e basta transizionare il contenitore piu' esterno — dentro, ogni colore e'
       una `var()` che legge lo stesso `--paper`/`--ink`, quindi cambia insieme a lui
       senza bisogno di una transizione scritta su ciascun elemento. */
    transition: background-color 0.4s var( --ease ), color 0.4s var( --ease );
}

h1, h2, h3, h4, h5, h6 {
    font-family: var( --font-medium );
    /* ⚠️ 700, non piu' 400: con Imago "medium" era un file a se' ( peso 500 ), e questo
       400 non contava — il browser rendeva comunque l'unico peso disponibile per quel
       nome. DIN Alternate e' un font di SISTEMA con due pesi VERI, quindi ora conta
       davvero: senza cambiarlo, i titoli sarebbero DIN Alternate normale, non grassetto. */
    font-weight: 700;
    margin-top: 0;
    /* ⚠️ L'evidenziatore usa `--accent`, non una coppia dedicata: e' lo stesso rosso in
       ogni tema ( non viene ridefinito in scuro, vedi il commento sopra su `--accent` ),
       ma sul fondo quasi nero del tema scuro lo stesso esadecimale si legge arancio — la
       differenza chiaro/scuro viene dal contrasto, non da un secondo colore da mantenere.
       ⚠️ `box-decoration-break: clone`: un titolo su piu' righe prende un blocco PER
       RIGA, come farebbe un evidenziatore vero, non un rettangolo solo che salta le
       righe vuote in mezzo. `margin-left` negativo quanto il `padding` orizzontale:
       senza, il padding sposterebbe il testo a destra rispetto a tutto cio' che gli
       sta allineato accanto.
       ⚠️ `width: fit-content`: un h1-h6 e' un blocco, quindi senza questa riga lo sfondo
       si allarga fino al bordo del contenitore — spesso molto piu' largo del testo —
       invece di fermarsi dove finisce la scritta. `fit-content` resta un blocco ( va
       comunque a capo da solo, non affianca il testo che segue ), ma la sua larghezza
       e' quella del contenuto, non quella disponibile. */
    color: var( --paper );
    background-color: var( --accent );
    padding: 0.05em 0.3em;
    margin-left: -0.3em;
    width: fit-content;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}

/* ⚠️ Le eccezioni, ESPLICITE: senza, erediterebbero l'evidenziatore da sopra e si
   romperebbero — la voce di menu diventerebbe un titolo con tanto di sfondo e
   riquadro, il testo sulla foto un blocco opaco sopra l'immagine invece che il
   bianco fisso con l'ombra che ha gia' ( vedi ".slideshow-overlay h1" piu' sotto ),
   e "data" ( vedi ".content-info h4" piu' sotto ) un'etichetta con la cornice di
   un titolo. */
.list-title { background: none; padding: 0; margin-left: 0; }

p { line-height: 1.725rem; margin-bottom: 15px; font-size: inherit; }

a {
    color: var( --ink );
    text-decoration: none;
    line-height: inherit;
    transition: all 0.5s var( --ease ) 0s;
}
a:hover, a:focus { color: var( --accent ); }

img { max-width: 100%; height: auto; border: 0; }

/* ⚠️ Il browser da' a `figure` un margine suo — `1em 40px` — e quei 40px spostavano le
   fotografie di una scheda progetto a destra del menu, restringendole di 80. Nella lista
   non si vedeva perche' li' `.project-item figure` lo azzerava gia'. Qui una volta per
   tutte: una figura e' un contenitore, non un blocco rientrato. */
figure { margin: 0; }

ul { margin: 0; padding: 0; list-style: none; }


/* ─── griglia ───────────────────────────────────────────────────────────────
   Dodici colonne come il riferimento, ma in flex invece che in float.
   ⚠️ I margini negativi sulla riga e il padding sulle colonne devono restare
   pari: e' cio' che tiene le immagini allineate al bordo del container. */

.container {
    width: 100%;
    max-width: var( --container );
    margin: 0 auto;
    padding: 0 var( --gutter );
}

/* ⛔ NIENTE PIU' UN TETTO FISSO SOTTO I 1400px ( era 1180px ): col container gia'
   scritto in `vw` qui sopra, si restringe DA SOLO seguendo lo schermo — un secondo
   numero fisso qui lo avrebbe solo ristretto una seconda volta, contro la richiesta
   di sfruttare la larghezza. */

.row {
    display: flex;
    flex-wrap: wrap;
    margin-left: calc( var( --gutter ) * -1 );
    margin-right: calc( var( --gutter ) * -1 );
}

.row > [class*="col-"] {
    position: relative;
    width: 100%;
    padding-left: var( --gutter );
    padding-right: var( --gutter );
}

.col-3  { flex: 0 0 25%;      max-width: 25%; }
.col-4  { flex: 0 0 33.3333%; max-width: 33.3333%; }
.col-6  { flex: 0 0 50%;      max-width: 50%; }
.col-8  { flex: 0 0 66.6667%; max-width: 66.6667%; }
.col-9  { flex: 0 0 75%;      max-width: 75%; }
.col-12 { flex: 0 0 100%;     max-width: 100%; }

.offset-4 { margin-left: 33.3333%; }

.section-row { padding: 50px 0; }
.gray-bg     { background-color: var( --paper-alt ); }


/* ─── testata ───────────────────────────────────────────────────────────── */

/* ⚠️ 50 + 32 + 40 = i 122px di testata del riferimento, e i 32 del mezzo sono
   esattamente l'altezza del marchio ( --logo-width ). L'altezza NON e' fissata a
   122px come li': sotto i 991 il menu va a capo su tre righe, e una misura fissa lo
   taglierebbe. */
.site-header {
    padding: 50px 0 40px;
    background: var( --paper );
}

/*
 * ⚠️ IL MENU PARTE DA UN TERZO, non dal centro: e' la verticale su cui comincia la
 * colonna delle immagini, e nel riferimento le due cose combaciano al pixel — la
 * prima voce del menu e la prima fotografia stanno tutte e due a 686,3 su una
 * finestra da 1786. Li' l'allineamento viene dalla griglia ( logo in `col-4`, menu e
 * segni in `col-8` ); qui la fascia del marchio prende lo stesso terzo, e il menu
 * comincia subito dopo. Centrato — com'era prima — non si appoggiava a niente.
 *
 * ⚠️ Allineati in alto, il menu galleggiava sopra il piede del logo, che e' piu' alto di
 * una riga di testo: la riga poggia sul suo bordo inferiore.
 */
.site-header .row {
    align-items: flex-end;
    flex-wrap: nowrap;
    gap: 0;
}

.site-header .header-side {
    flex: 0 0 33.3333%;
    min-width: 0;
    padding: 0 var( --gutter );
    display: flex;
    align-items: flex-end;
}
/* i segni prendono lo spazio che avanza e si appoggiano al bordo destro */
.site-header .header-side-end { flex: 1 1 auto; justify-content: flex-end; }
.site-header .main-nav { flex: 0 0 auto; padding: 0 var( --gutter ); }

/* ⚠️ `display: flex` e non un div qualunque: con il link `inline-block` il marchio sta
   dentro una RIGA DI TESTO, e sotto di lui resta lo spazio del descender — 6,5px che
   facevano una testata di 128,5px dove il riferimento ne misura 122. Un contenitore
   flex non ha line-box, quindi l'altezza e' quella del marchio e basta.
   ⚠️ `position: relative` e' per `.brand-tagline`, che si posiziona rispetto a QUESTO
   contenitore e non rispetto alla pagina. */
.logo {
    display: flex;
    position: relative;
    color: var( --ink-strong );
}
/* ⚠️ UN BOTTONE, NON UN LINK: il marchio non porta piu' alla home — apre il menu, come
   il segno in alto a sinistra su big.dk. Alla home ci si arriva da dentro il pannello
   ( la voce "Progetti", che home e' gia' — vedi la fusione di Fase 4 ), non dal marchio.
   Reimpostato a `font: inherit` e senza bordo: e' un `<button>`, che porta il SUO stile
   di default se non lo si toglie. */
.logo button {
    display: block;
    position: relative;   /* ancora per le fette del marchio e per `.menu-lines`, sovrapposte qui dentro */
    width: var( --logo-width );
    aspect-ratio: 1491 / 589;   /* la STESSA misura di `.logo .brand-mark`: qui non c'e' piu' un
                                   contenuto in flusso a darla da solo, con le fette tutte
                                   `position: absolute` il bottone si schiaccerebbe a zero */
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    color: inherit;
    cursor: pointer;
}
/* ⚠️ Il marchio si tinge d'accento col pannello aperto: lo stesso riscontro che aveva
   prima il bottone a tre barre ( vedi `.nav-active .menu-btn`, tolto — il marchio ne
   ha preso il posto anche in questo ). `currentColor` arriva alle fette e alle righe
   per `background-color: currentColor`, quindi basta ricolorare il bottone. */
.nav-active .logo button { color: var( --accent ); }

/*
 * ⚠️ IL MARCHIO SI SCOMPONE IN TRE FETTE, non sfuma e basta: sono tre copie della
 * STESSA maschera ( vedi `.logo .brand-mark` piu' sotto, che queste regole riusano
 * `background-color`/`mask` da li' tramite la classe condivisa ), ognuna ritagliata
 * al proprio terzo con `clip-path` e impilata esattamente sulle altre — a riposo
 * ricompongono il segno intero, un pixel alla volta uguale a prima.
 * Aprendo il pannello ogni fetta si stacca per conto suo ( verso l'alto e a sinistra
 * la prima, di lato la seconda, verso il basso e a sinistra la terza ) mentre sfuma:
 * e' la differenza fra "il marchio si scompone" e "il marchio sfuma", ed e' tutta
 * qui — tre traiettorie diverse, non una sola su tre pezzi identici.
 */
.logo-btn .mark-shard {
    /* ⚠️ MASCHERA E MISURA arrivano da `.logo .brand-mark` qui sotto — condivisa, non
       ridetta: ogni fetta e' anche un `.brand-mark`, vedi le classi nel markup. Qui si
       aggiunge solo cio' che serve in PIU' per farne una fetta che si stacca da sola:
       la sovrapposizione esatta e il taglio. */
    position: absolute;
    inset: 0;
    transition: opacity 0.45s var( --ease ), transform 0.45s var( --ease );
}
.logo-btn .mark-shard-1 { clip-path: inset( 0 0 66.667% 0 ); }
.logo-btn .mark-shard-2 { clip-path: inset( 33.333% 0 33.333% 0 ); }
.logo-btn .mark-shard-3 { clip-path: inset( 66.667% 0 0 0 ); }

.nav-active .logo-btn .mark-shard-1 { transform: translate( -9px, -11px ) rotate( -10deg ); opacity: 0; }
.nav-active .logo-btn .mark-shard-2 {
    transform: translate( 7px, 0 ) scale( 0.8 );
    opacity: 0;
    transition-delay: 0.03s;
}
.nav-active .logo-btn .mark-shard-3 {
    transform: translate( -9px, 11px ) rotate( 10deg );
    opacity: 0;
    transition-delay: 0.06s;
}

.logo-btn .menu-lines {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 7px;
    width: 30px;

    /* ⚠️ FERME E INVISIBILI a pannello chiuso: `opacity`/`transform`, non `display: none`
       — quello non si anima. Partono piu' piccole e ruotate, cosi' quando entrano
       sembrano srotolarsi dai pezzi del marchio invece di comparire gia' ferme. */
    opacity: 0;
    transform: scale( 0.5 ) rotate( -20deg );
    transition: opacity 0.45s var( --ease ) 0.08s, transform 0.45s var( --ease ) 0.08s;
    pointer-events: none;   /* il click resta sul bottone, non su queste righe */
}
.logo-btn .menu-lines span {
    display: block;
    width: 100%;
    height: 2px;
    background: currentColor;
    border-radius: 1px;
}

.nav-active .logo-btn .menu-lines {
    opacity: 1;
    transform: scale( 1 ) rotate( 0deg );
}

/* ⚠️ Chi ha chiesto meno movimento non vuole nemmeno questo: cambio secco, senza
   rotazione, scala ne' ritardi fra un pezzo e l'altro. */
@media ( prefers-reduced-motion: reduce ) {
    .logo-btn .mark-shard,
    .logo-btn .menu-lines {
        transition: opacity 0.2s linear;
        transition-delay: 0s;
        transform: none !important;
    }
}

/* "architecture partners": lo stesso carattere che stava bianco sull'apertura della home
   ( --font-medium, com'era in `.slideshow-overlay h1` ), chiaro.
   ⚠️ FUORI DAL FLUSSO ( `position: absolute` ), non una seconda riga: se fosse un
   elemento normale, alto com'e', allargherebbe la testata oltre i 122px del
   riferimento — vedi il commento sopra su ".logo". Cosi' invece si sovrappone al
   marchio senza cambiarne l'altezza.
   ⚠️ Il bordo sinistro parte da dove comincia il "+" nel marchio, non da dove comincia
   la "C": misurato sui pixel dell'immagine, il "+" inizia al 75% della larghezza del
   marchio — da qui `calc( var( --logo-width ) * 0.75 )`, cosi' la percentuale resta
   giusta anche se --logo-width cambia. Il `+ 4px` in coda e' solo respiro dal marchio,
   non fa parte della misura sul "+".
   ⚠️ `bottom: -2px`, non `0`: il marchio e' tutto MAIUSCOLO, quindi il suo bordo basso E'
   la riga di base. Il testo invece ha un'interlinea ( anche a `line-height: 1` il
   carattere riserva spazio sotto la riga di base, per le discendenti che qui non ci
   sono quasi mai ) — a `bottom: 0` la scritta restava visibilmente piu' in alto. -2px
   NON e' a occhio: e' la differenza misurata fra le due righe di base vere, ottenuta
   allineando davvero marchio e scritta con `align-items: baseline` in un flex di prova
   e leggendo `getBoundingClientRect()` — la stessa aritmetica che userebbe il browser. */
.logo .brand-tagline {
    position: absolute;
    left: calc( var( --logo-width ) * 0.75 + 4px );
    bottom: -2px;
    font-family: var( --font-medium );
    font-weight: 700;   /* vedi il commento su "h1, h2, ..." per il perche' ora serve */
    font-size: 0.8125rem;
    line-height: 1;
    color: #999999;   /* piu' chiaro di --ink-soft ( #808080 ): qui e' decorazione
                          accanto al marchio, non testo da leggere */
    white-space: nowrap;
}

/*
 * ⚠️ IL MARCHIO E' UNA MASCHERA, NON UN'IMMAGINE. Il logo di ch-plus.com e' bianco su un
 * rettangolo NERO PIENO ( alpha 255 su tutti i pixel ): messo com'e' su carta bianca
 * sarebbe una macchia nera. Il file e' stato riscritto con l'alpha ricavato dalla
 * luminanza, e qui porta la SOLA forma — il colore lo mette il tema, quindi un tema
 * scuro cambia una variabile invece di chiedere un secondo file.
 *
 * ⚠️ Una misura sola: la seconda la da' `aspect-ratio`, che e' quello dei glifi
 * ( 1491x589 ). Scriverle tutte e due significa che un giorno divergono e il logo si
 * schiaccia.
 */
.logo .brand-mark {
    display: block;
    width: var( --logo-width );
    aspect-ratio: 1491 / 589;
    background-color: currentColor;
    -webkit-mask: url( '../images/logo.webp' ) no-repeat center / contain;
            mask: url( '../images/logo.webp' ) no-repeat center / contain;
}

/* ─── velo d'apertura ───────────────────────────────────────────────────── */

/*
 * ⚠️ NASCOSTO DI DEFAULT: si accende SOLO quando l'`<html>` porta `data-intro="pending"`
 * o `"leaving"` — scritto dallo script in testa a `default_page.php` prima che il
 * browser disegni. Senza quell'attributo ( niente JavaScript, `prefers-reduced-motion`,
 * o una pagina aperta a meta' di una sessione gia' vista ) questo blocco non esiste per
 * il layout: `display: none` e non `opacity: 0`, perche' un velo trasparente ma ancora
 * `position: fixed` bloccherebbe comunque i click sulla pagina sotto.
 */
.intro-veil { display: none; }

html[data-intro="pending"] .intro-veil,
html[data-intro="leaving"] .intro-veil {
    display: flex;
    position: fixed;
    inset: 0;
    z-index: 10000;   /* sopra il banner cookie ( 9999 ): e' la primissima cosa che si vede */
    align-items: center;
    justify-content: center;
    background: var( --paper );
    transform: translateY( 0 );
    will-change: transform;
}

/*
 * ⚠️ LA STESSA MASCHERA DEL MARCHIO VERO ( vedi `.logo .brand-mark` sopra ), non una
 * seconda immagine: cosi' il segno che si vede grande al centro e' esattamente quello
 * che poi resta piccolo in testata, non una sua imitazione che potrebbe disallinearsi.
 * La misura di partenza e' in `vw`, non un valore fisso: su un telefono stretto 340px
 * sarebbe piu' largo dello schermo.
 * ⚠️ `--intro-dx`/`--intro-dy`/`--intro-scale-from` li scrive `js/intro.js`, MISURANDO
 * la posizione vera del marchio in testata — non una formula a vista che vale per un
 * solo breakpoint e stona su tutti gli altri. Finche' lo script non li scrive restano
 * ai valori di ripiego qui sotto, che tengono il marchio fermo ( `pending` non anima
 * niente da solo: e' `leaving`, aggiunto dallo script, ad avviare la transizione ).
 */
.intro-veil .intro-logo {
    display: block;
    width: min( 42vw, 340px );
    aspect-ratio: 1491 / 589;
    background-color: var( --ink-strong );
    -webkit-mask: url( '../images/logo.webp' ) no-repeat center / contain;
            mask: url( '../images/logo.webp' ) no-repeat center / contain;
    transform: translate( 0, 0 ) scale( 1 );
    opacity: 1;
    transition: transform 900ms cubic-bezier( .65, 0, .35, 1 ), opacity 350ms ease 650ms;
}

/*
 * ⚠️ IL VELO NON SFUMA: SI TRASCINA VIA VERSO L'ALTO, come la banda nera dell'apertura
 * di big.dk ( misurata in sessione: un rettangolo pieno che passa da `translateY(0)` a
 * `translateY(-100%)`, non un'opacita' che scende ). Parte con un ritardo ( `250ms` )
 * cosi' il marchio ha gia' iniziato il suo viaggio quando il fondo comincia a scoprire
 * la testata vera sotto di lui — altrimenti i due movimenti partirebbero insieme e
 * sembrerebbero due animazioni scollegate invece di una sola apertura.
 */
html[data-intro="leaving"] .intro-veil {
    transform: translateY( -100% );
    pointer-events: none;
    transition: transform 700ms cubic-bezier( .65, 0, .35, 1 ) 250ms;
}

html[data-intro="leaving"] .intro-veil .intro-logo {
    transform: translate( var( --intro-dx, 0px ), var( --intro-dy, 0px ) ) scale( var( --intro-scale-from, 0.24 ) );
    opacity: 0;
}

.main-nav ul { display: flex; gap: 34px; }

/* ⚠️ Un interruttore a scorrimento, non un bottone a icona come prima: una PISTA ovale e
   un CURSORE tondo che scivola da un lato all'altro. Il sole e la luna sono DUE svg, non
   una che cambia `path`: un'icona sola che si trasforma vorrebbe un'animazione sui punti
   del tracciato, per due forme cosi' diverse non vale la spesa — stanno DENTRO il cursore,
   non ferme sulla pista, perche' e' il cursore a portare lo stato ( non l'azione, stavolta:
   a sinistra il sole vuol dire "sono nel chiaro", non "passa al chiaro" — e' cosi' che si
   legge un interruttore, diverso da un bottone a icona ). Il tema lo mette JavaScript,
   scrivendo `data-theme` sull'`<html>`: vedi `theme-toggle.js` e lo script in linea in
   `default_page.php`.
   ⚠️ Le misure: pista 42x22, cursore 18x18 con 2px di margine per lato — la corsa e'
   quindi 42 - 2*2 - 18 = 20px, il valore del `translateX` qui sotto. Se una misura cambia,
   cambiano insieme. */
/* Selettore di lingua a tendina: la sigla della lingua corrente e la freccia — la stessa dell'elenco
   degli anni, in giu' chiusa e in su' aperta — e sotto il pannello bianco con le lingue. Il pannello e'
   fuori dal flusso, cosi' la testata non cambia altezza aprendolo. */
.lang-switch { position: relative; margin-left: 16px; align-self: center; font-size: 1rem; }
.lang-switch summary {
    display: flex; align-items: center; gap: 6px;
    color: var( --ink ); cursor: pointer; list-style: none;
    transition: color 0.5s var( --ease ) 0s;
}
.lang-switch summary::-webkit-details-marker { display: none; }
.lang-switch summary:hover, .lang-switch[open] summary { color: var( --accent ); }
.lang-switch .chevron { --chevron-size: 10px; --chevron-weight: 3; transform: rotate( -90deg ); transition: transform 0.3s var( --ease ) 0s; }
.lang-switch[open] .chevron { transform: rotate( 90deg ); }
.lang-switch ul {
    position: absolute; right: -14px; top: calc( 100% + 10px ); z-index: 30;
    min-width: 64px; padding: 10px 18px;
    background: var( --paper ); box-shadow: 0 6px 24px rgba( 0, 0, 0, 0.14 );
}
.lang-switch li { padding: 6px 0; }
.lang-switch a { color: var( --ink ); }
.lang-switch a:hover { color: var( --accent ); }
.lang-switch a.active { font-weight: 700; }

.theme-toggle {
    position: relative;
    display: inline-flex;
    align-items: center;
    width: 42px;
    height: 22px;
    margin-left: 16px;
    padding: 0;
    border: 1px solid var( --rule );
    border-radius: 999px;
    background: var( --paper-alt );
    cursor: pointer;
    transition: border-color 0.5s var( --ease ) 0s;
}
.theme-toggle:hover { border-color: var( --accent ); }
.theme-toggle-knob {
    position: absolute;
    /* ⚠️ 1px e non 2: `top`/`left` contano dal bordo INTERNO della pista, che ha 1px di bordo —
       dentro restano 40x20, e un cursore 18x18 con 1px per lato e' centrato con 2px in tutto. */
    top: 1px;
    left: 1px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var( --ink );
    color: var( --paper );   /* il colore delle icone dentro, non del cursore */
    transition: transform 0.35s var( --ease ) 0s, background-color 0.5s var( --ease ) 0s;
}
:root[data-theme="dark"] .theme-toggle-knob { transform: translateX( 20px ); background: var( --accent ); }
.theme-toggle-knob svg {
    display: block;
    width: 12px;
    height: 12px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}
/* ⚠️ `.theme-toggle-knob .theme-toggle-sun`, non `.theme-toggle-sun` da sola: due classi
   battono la specificita' di ".theme-toggle-knob svg" qui sopra ( una classe piu' un tag ),
   che altrimenti vincerebbe lei e le due icone resterebbero visibili insieme. */
.theme-toggle-knob .theme-toggle-sun { display: none; }
:root[data-theme="dark"] .theme-toggle-knob .theme-toggle-moon { display: none; }
:root[data-theme="dark"] .theme-toggle-knob .theme-toggle-sun { display: block; }

/* ⚠️ MAIUSCOLO e spaziato: il restyle sul riferimento ( big.dk ) usa cosi' la testata —
   prima era minuscolo per scelta di stile propria, ora si segue il riferimento. Le
   etichette nel documento restano "Home", "Studio": e' `text-transform`, non le si
   riscrive a mano. */
.main-nav li { font-size: 0.8125rem; text-transform: uppercase; letter-spacing: 0.06em; }
.main-nav a,
.main-nav summary { color: var( --ink ); }
.main-nav .active > a,
.main-nav a:hover,
.main-nav summary:hover { color: var( --accent ); }
/* ⚠️ L'evidenziatore SOLO sulla voce attiva ( la pagina su cui si e' ), non anche
   sull'hover: un riquadro che appare e sparisce passando il mouse su ogni voce
   sarebbe piu' fastidioso che utile. Un `<a>` e' inline, quindi il riquadro segue
   gia' da solo il testo — non serve `width: fit-content` come per i titoli, che
   sono di blocco. Stesso evidenziatore dei titoli, `--accent` — qui vince
   sul `color: var( --accent )` della riga sopra perche' viene dopo lei nel foglio. */
.main-nav > ul > li.active > a { color: var( --paper ); background-color: var( --accent ); padding: 0.05em 0.3em; }
/* ⚠️ `> ul > li.active > a`, non `.active > a`: dentro il pannello del mega-menu c'e' un'altra
   voce "attiva" ( il filtro scelto ), e senza il percorso diretto quella prendeva LO STESSO
   riquadro pieno — sfondo nero, e sopra un colore che un'altra regola rendeva nero anche lui:
   testo invisibile. */

/* ─── mega-menu ( voce "Progetti" della testata ) ──────────────────────────────────────
   Un <details> come `.lang-switch`, stessa meccanica: apre/chiude da solo, la freccia
   ruota, il pannello e' fuori dal flusso cosi' la testata non cambia altezza. Il pannello
   elenca le tipologie ricavate da `partials/project-taxonomy.php` — le stesse che la
   pagina progetti userebbe per i suoi filtri, qui come scorciatoie dalla testata. */
.mega-menu { position: relative; }
.mega-menu summary {
    display: flex; align-items: center; gap: 5px;
    cursor: pointer; list-style: none;
    transition: color 0.5s var( --ease ) 0s;
}
.mega-menu summary::-webkit-details-marker { display: none; }
.mega-menu .chevron { --chevron-size: 8px; --chevron-weight: 3; transform: rotate( -90deg ); transition: transform 0.3s var( --ease ) 0s; }
.mega-menu[open] .chevron { transform: rotate( 90deg ); }
.mega-menu-panel {
    position: absolute; left: 0; top: calc( 100% + 14px ); z-index: 30;
    min-width: 220px; padding: 22px 26px;
    background: var( --paper ); box-shadow: 0 10px 30px rgba( 0, 0, 0, 0.12 );
}
.mega-menu-panel ul { display: flex; flex-direction: column; gap: 12px; }
.mega-menu-panel a { color: var( --ink ); text-transform: none; letter-spacing: normal; font-size: 0.95rem; }
.mega-menu-panel a:hover { color: var( --accent ); }
.mega-menu-panel li.active a { color: var( --ink-strong ); font-weight: 700; }

/*
 * ⚠️ I segni sono CONTORNATI, non pieni: a 18px una "f" piena dentro un quadrato impasta,
 * e un contorno sottile sta accanto a un menu leggero senza pesare. Il tratto e' l'unica
 * cosa colorata — `fill: none` sta sull'elemento, e la spia di Instagram lo rovescia.
 */
.social-links { display: flex; align-items: center; gap: 14px; padding: 4px; }

.social-link { display: block; color: var( --ink ); }
.social-link:hover { color: var( --accent ); }

.social-link svg {
    display: block;
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.social-link svg .filled { fill: currentColor; stroke: none; }


/* ─── fascia di apertura ────────────────────────────────────────────────── */

.section-banner-row  { padding: 0; }
.section-banner-img img { width: 100%; height: auto; display: block; }

/* Il testo grande d'apertura: rientrato di un terzo, come nel riferimento. */
.text-bigger,
.text-bigger p,
.text-bigger .text-block {
    font-family: var( --font-light );
    font-size: 32px;
    line-height: 1.4;
}


/* ─── elenco dei progetti ───────────────────────────────────────────────── */

.projects { margin-bottom: 40px; }

/* ─── i filtri, sopra la lista ──────────────────────────────────────────────────────────
   Prima stavano in una colonna a sinistra ( `.side-nav` ), sticky, con gli anni sotto le
   tipologie. La lista ora e' fatta di righe intere ( vedi `.project-row` piu' sotto ) e non
   ha piu' una colonna stretta a cui stare a fianco: i filtri salgono sopra, orizzontali —
   il disegno del riferimento ( big.dk ). */
/* ⚠️ NIENTE PIU' RIGA SOTTO ai filtri: richiesta esplicita, la stessa ragione di
   `.project-row` piu' sotto — a separare resta l'aria, non un filo. */
.project-filters { padding-bottom: 40px; margin-bottom: 60px; }
.project-filters .list-title { margin: 0 0 26px; font-size: 1.5rem; }
.project-filters .list-title a { color: var( --ink ); }
.project-filters .list-title a:hover { color: var( --ink-strong ); }
.project-filters .list-title a.active { color: var( --paper ); background-color: var( --accent ); padding: 0.05em 0.3em; }

.filter-tabs { display: flex; flex-wrap: wrap; gap: 10px 28px; margin-bottom: 22px; }
.filter-tabs a {
    color: var( --ink ); font-size: 0.8125rem; text-transform: uppercase; letter-spacing: 0.06em;
    transition: color 0.5s var( --ease ) 0s;
}
.filter-tabs a:hover { color: var( --ink-strong ); }
/* stesso evidenziatore del menu principale: solo sulla tipologia scelta, non sull'hover */
.filter-tabs li.active a { color: var( --paper ); background-color: var( --accent ); padding: 0.05em 0.3em; }

/* ⚠️ <details> nativo, come il mega-menu della testata: si apre da tastiera e funziona
   senza JavaScript — spogliato del suo aspetto di sistema. */
.filter-years summary {
    display: inline-flex; align-items: center; gap: 8px;
    color: var( --ink ); font-size: 0.8125rem; text-transform: uppercase; letter-spacing: 0.06em;
    cursor: pointer; list-style: none;
    transition: color 0.5s var( --ease ) 0s;
}
.filter-years summary::-webkit-details-marker { display: none; }
.filter-years summary:hover, .filter-years[open] summary { color: var( --ink-strong ); }
.filter-years .chevron { --chevron-size: 9px; --chevron-weight: 3; transform: rotate( -90deg ); transition: transform 0.3s var( --ease ) 0s; }
.filter-years[open] .chevron { transform: rotate( 90deg ); }
.filter-years ul { display: flex; flex-wrap: wrap; gap: 8px 20px; margin-top: 16px; padding-left: 0; }
.filter-years a { color: var( --ink ); font-size: 0.9rem; }
.filter-years a:hover { color: var( --ink-strong ); }
.filter-years li.active a { color: var( --paper ); background-color: var( --accent ); padding: 0.05em 0.3em; }

/* ─── la lista: una riga per progetto, testo a sinistra e fotografia a destra ────────────
   Il disegno del riferimento. `.details` qui e' la STESSA classe della colonna di testo
   nella scheda di un progetto: eredita gli stili di `.title`/`.concept`/`.name` piu' sotto,
   non li duplica — solo `.project-row` sostituisce `.project-item` in quei selettori. */
/* ⚠️ ALLINEATI IN ALTO ( `align-items: flex-start` ), non centrati: nel riferimento il
   titolo comincia alla cima della fotografia, non a meta' altezza — lo stesso principio
   della scheda di un progetto, vedi `.strip-info` piu' sotto. */
/* ⚠️ NIENTE PIU' RIGA SOTTO: richiesta esplicita — la separazione fra un progetto e il
   successivo la fa lo spazio bianco ( `padding` ), non un filo. Anche nel riferimento
   le righe dell'elenco non hanno un bordo, solo aria fra una fotografia e l'altra. */
.project-row {
    display: flex; align-items: flex-start; gap: var( --gutter );
    padding: 50px 0;
}
.project-row:first-child { padding-top: 0; }
.project-row > a { display: flex; align-items: flex-start; gap: var( --gutter ); width: 100%; }
.project-row .details { flex: 0 0 auto; width: 25%; padding-top: 0; }

/* ⚠️ `flex: 0 1 auto`, non piu' `1 1 auto`: quello FORZAVA la figura a riempire tutta la
   larghezza che restava dopo il testo, anche quando la fotografia — una verticale, piu'
   stretta della sua colonna — non ne aveva bisogno. Il velo qui sotto e' `inset:0` DENTRO
   la figura, quindi copriva anche lo spazio vuoto rimasto: un riquadro grigio accanto alla
   foto, non dietro di essa. Senza quel di piu' da riempire, la figura si stringe alla
   misura della fotografia — la larghezza vera continua a deciderla lei ( `.project-row img`
   qui sotto ), niente cambia per le orizzontali, che la loro misura la toccano gia'.
   ⚠️ E NIENTE PIU' `justify-content: flex-end`: richiesta esplicita — le verticali vanno
   a sinistra, accanto al testo, non staccate a destra con un vuoto in mezzo. */
.project-row figure { flex: 0 1 auto; display: flex; margin: 0; background: var( --paper ); position: relative; z-index: 1; }
/* ⚠️ Il velo al 2% non e' decorazione: e' cio' che impedisce a una foto con i bordi
   chiari di sparire dentro il bianco della pagina. Sta anche nel riferimento. */
.project-row figure::before {
    content: "";
    position: absolute;
    inset: 0;
    background: #000;
    opacity: 0.02;
    z-index: -1;
}
/* ⚠️ L'ALTEZZA E' UN TETTO, la larghezza la decide la forma della fotografia — la stessa
   scelta gia' fatta ( e misurata ) per la scheda di un progetto: vedi il commento la',
   non ripetuto qui. Qui il tetto e' piu' alto perche' la riga e' sola, non una fra tante
   affiancate. */
/* ⚠️ PIU' PICCOLE, richiesta esplicita ( 62vh → 38vh ): nell'elenco sono un'ANTEPRIMA,
   il progetto vero — grande, a tutta larghezza — si vede aprendo la riga con un click.
   Due cose diverse, non piu' la stessa misura. */
.project-row img {
    display: block;
    height: auto;
    width: auto;
    max-height: 38vh;
    max-width: 100%;
    filter: grayscale( 1 );
    transition: filter 0.5s var( --ease ) 0s;
}
/* la copertina e' in bianco e nero e torna a colori al passaggio del mouse ( o con la
   tastiera, per chi naviga senza mouse ). ⚠️ `.project-row a:hover`, non il contrario: il
   link e' DENTRO `.project-row` ( `.project-row > a > figure > img` ), quindi e' lui che
   deve avere `:hover`, non il suo antenato. */
.project-row a:hover img,
.project-row a:focus-visible img { filter: grayscale( 0 ); }

/* ─── la riga che si apre sul posto ( js/project-expand.js ) ─────────────────────────────
   ⚠️ Come nel riferimento ( big.dk ): un click sulla riga non lascia l'elenco, la apre LI',
   con le altre righe ancora sopra e sotto — scorrendo si passa alla riga dopo com'e' oggi,
   solo che ora una di esse puo' essere gia' aperta. Il pannello e' un fratello della riga,
   non un suo contenuto: la riga resta cliccabile per richiuderlo, il pannello e' un'altra
   `<div>` che l'apertura crea al primo click e injetta di HTML preso dal frammento
   ( `?frammento=progetto`, vedi render.php ).
   ⚠️ ALTEZZA A GRIGLIA ( `grid-template-rows: 0fr` → `1fr` ), non `max-height`: un
   `max-height` finto ( un numero abbastanza grande ) o fa uno scatto se il contenuto e'
   piu' alto di quel numero, o anima un vuoto se e' piu' basso — la riga della griglia
   anima l'altezza VERA del contenuto senza che il JS la debba misurare. */
.project-expand-panel {
    display: grid;
    grid-template-rows: 0fr;
    /* ⚠️ PIU' LENTA ( 0.6s → 1s → 1.3s ) e con `--ease-grow`, non `--ease`: richiesta
       esplicita, lo scatto si vedeva soprattutto qui. Vedi il commento su `--ease-grow`
       nel `:root`. */
    transition: grid-template-rows 1.3s var( --ease-grow );
}
.project-expand-panel.is-open { grid-template-rows: 1fr; }
/* ⚠️ `min-height` TRANSIZIONA anche lui, stessa durata e curva del riquadro: senza,
   `js/project-expand.js` lo scrive con un numero preciso ( SUBITO al click, per aprirsi
   senza aspettare la rete — vedi il commento la' ) e quel numero, senza una transizione
   propria, vince istantaneamente sulla riga della griglia — il riquadro saltava di colpo
   alla misura finale, annullando l'animazione di `grid-template-rows` qui sopra invece di
   accompagnarla: era quello lo scatto lamentato, non la velocita' della transizione.
   Con la stessa transizione sul minimo, le due misure crescono ( e si richiudono )
   insieme, in un movimento solo. */
.project-expand-panel > .project-expand-inner {
    position: relative;
    overflow: hidden;
    min-height: 0;
    transition: min-height 1.3s var( --ease-grow );
}

/* ⚠️ IL CONTENUTO CRESCE ANCHE LUI, non solo il riquadro che lo contiene: col solo
   `grid-template-rows` qui sopra la scheda arriva gia' alla sua misura finale, e SI
   RIVELA man mano che il riquadro si allarga — come se un sipario si aprisse su una
   fotografia ferma, non come se la fotografia stessa si aprisse. Nel riferimento e'
   la seconda: parte un poco piu' piccola e leggermente trasparente, e cresce fino
   alla misura vera insieme al riquadro. `js/project-expand.js` accende `is-visible`
   un istante dopo aver scritto l'HTML — mai subito, o il browser non avrebbe un
   fotogramma "prima" da cui partire e la transizione non si vedrebbe. */
.project-expand-content {
    opacity: 0;
    transform: scale( 0.92 );
    /* ⚠️ transform-origin IN ALTO, non al centro ( il ripiego del browser ): il riquadro
       cresce verso il basso ( `grid-template-rows` ), quindi il contenuto deve crescere
       dalla SUA cima, la stessa cima che resta ferma — crescendo dal centro la meta'
       superiore si sarebbe mossa verso l'alto mentre il riquadro la copre, un
       contro-movimento che il riferimento non ha. */
    transform-origin: 50% 0%;
    transition: opacity 1.3s var( --ease-grow ), transform 1.3s var( --ease-grow );
}
.project-expand-content.is-visible { opacity: 1; transform: scale( 1 ); }

/* ⚠️ LA RIGA SPARISCE MENTRE E' APERTA, non resta sopra il pannello: il riferimento non
   mostra la riga stretta E la scheda grande insieme, la riga aperta DIVENTA la scheda.
   `display:none` sul suo link e non sulla riga intera: la riga resta nel documento, con
   `data-expand-url`, pronta a richiudersi. */
.project-row.is-active > a { display: none; }
/* ⚠️ SENZA PADDING SOTTO: col link nascosto sopra, quel padding lascerebbe una fascia
   vuota fra il bordo della riga e il pannello che si apre subito dopo. */
.project-row.is-active { padding-bottom: 0; }
/* ⛔ NIENTE PIU' PULSANTE DI CHIUSURA, richiesta esplicita — tolto ovunque, anche dalla
   scheda aperta con un click ( sulla home era gia' sparito ). Chiudere ora si fa
   cliccando la riga stessa, quel poco che resta cliccabile dov'era il pulsante — vedi
   js/project-expand.js. Il cursore lo dice: quella fascia, anche se stretta, reagisce
   ancora al click.
   ⚠️ `min-height`, non solo il cursore — misurato, e' un difetto vero: sulla PRIMA riga
   dell'elenco ( `.project-row:first-child { padding-top: 0 }`, poco piu' sotto in questo
   foglio ) sommato al `padding-bottom: 0` qui sopra, la riga restava ALTA ZERO PIXEL —
   niente da cliccare, niente da toccare, nessun modo di richiuderla piu' se non il tasto
   "indietro" del browser. Un minimo garantisce sempre qualcosa su cui cliccare, qualunque
   sia la riga. */
.project-row.is-active { cursor: pointer; min-height: 44px; }

/* ⚠️ A TUTTA LARGHEZZA anche qui dentro, come sulla pagina propria del progetto: senza,
   `.project-strip` erediterebbe la larghezza stretta del `.container` dell'elenco invece
   di sbordare fino ai due bordi dello schermo. Il calcolo funziona perche' ogni antenato
   fra questo e il `.container` e' largo quanto lui — nessuno dei due si centra una
   seconda volta — quindi il centro di questo elemento resta quello del `.container`, che
   e' gia' il centro dello schermo: la stessa base su cui poggia `--content-inset`.
   ⚠️ SOLO SOPRA I 767px, misurato su un iPhone vero: `100vw` li' non e' affidabile come
   sembra — Safari lo calcola sulla finestra PIU' GRANDE possibile ( quella con la barra
   degli indirizzi gia' ritirata ), qualche pixel piu' larga di quella davvero visibile.
   Quei pixel in piu' finivano nel calcolo qui sotto, e spostavano tutta la scheda — testo
   compreso — di una manciata di pixel fuori dal bordo sinistro: le prime lettere di ogni
   riga sparivano, tagliate. Sotto i 767 `.project-strip` non ne ha bisogno comunque: ha
   gia' il suo margine di 20px da `style.css` piu' sotto, uguale a quello del resto del
   sito in quella misura — non deve sbordare fino al bordo vero dello schermo. */
@media ( min-width: 768px ) {
    .project-expand-panel .project-strip { width: 100vw; margin-left: calc( 50% - 50vw ); }
}

/* ⚠️ NIENTE MARGINE SOPRA QUI DENTRO, corretto dopo una segnalazione da un iPad vero
   ( "non e' centrato" ): i 90px di `margin-top` qui sopra ( in `.project-strip` )
   servono a scostare la striscia dalla TESTATA FISSA della pagina propria del progetto —
   qui dentro non c'e' nessuna testata da scostare, il pannello e' gia' posizionato dove
   deve stare. Quel margine, non contato nel calcolo dell'altezza in project-expand.js,
   spingeva la fotografia 90px piu' in basso di quanto il centraggio avesse previsto —
   uno scarto che sui telefoni ( striscia verticale, altro layout ) non si vedeva, ma su
   uno schermo largo come un iPad, dove la striscia resta orizzontale, spostava tutto
   verso il basso e rompeva la simmetria fra il margine sopra e quello sotto. */
.project-expand-panel .project-strip { margin-top: 0; }

/* ⚠️ UN TETTO SCRITTO IN CSS, non solo calcolato in JavaScript — aggiunto dopo una
   fotografia vera da un iPad: nonostante il calcolo in project-expand.js ( verificato
   piu' volte, anche con `visualViewport` per Safari ) risultasse sempre giusto in ogni
   prova qui, sul dispositivo vero la fotografia continuava a sfondare sotto il bordo
   dello schermo, senza nessun margine — il JavaScript, per una ragione che da qui non
   si e' riusciti a isolare, non arrivava mai a scrivere la sua altezza su quel
   dispositivo. Un `max-height` in CSS non dipende da NESSUN calcolo, nessuno script,
   nessuna condizione di rete: il browser lo applica da solo, sempre, qualunque cosa
   succeda al JavaScript. Non sostituisce il calcolo preciso ( che centra la fotografia
   con lo stesso margine sopra e sotto quando funziona ), lo protegge: se per qualunque
   motivo quel calcolo non arriva, la fotografia resta comunque dentro lo schermo invece
   di sfondarlo.
   ⚠️ `dvh`, non solo `vh`: e' l'unita' ideata apposta per Safari mobile, dove la barra
   degli indirizzi cambia l'altezza VISIBILE senza cambiare quella che `vh` racconta — la
   riga doppia ( `vh` prima, `dvh` dopo ) fa si' che i browser che non conoscono ancora
   `dvh` restino comunque protetti dal `vh` normale, e quelli che lo conoscono usino la
   misura piu' precisa, scritta per ultima cosi' vince quando c'e'.
   ⚠️ 88, non 65: un numero piu' BASSO sembrava piu' sicuro, ma un `max-height` vince
   SEMPRE sull'altezza scritta dal JavaScript, anche quando quel calcolo e' giusto — a
   65vh tagliava corto pure i casi che funzionavano gia' bene ( misurato: il margine sotto
   uscito quasi il triplo di quello sopra, il tetto interveniva quando non doveva ). 88
   lascia il calcolo preciso libero di lavorare nei casi normali, e resta comunque un
   argine vero contro un'altezza che, se il JavaScript non arriva, sfonderebbe il 100%
   dello schermo.
   ⛔ SOLO SOPRA I 767px: sotto quella misura la striscia e' gia' verticale ( fotografie
   impilate, non affiancate — vedi la media query in style.css ) e la sua altezza la
   decide il CONTENUTO, apposta, non lo schermo — un tetto qui le avrebbe schiacciate
   una sopra l'altra invece di lasciarle scorrere in colonna alla loro misura vera. */
@media ( min-width: 768px ) {
    .project-expand-panel .project-strip {
        max-height: 88vh;
        max-height: 88dvh;
    }

    /* ⚠️ UN TETTO PIU' STRETTO E CONSAPEVOLE DELLA TESTATA, SOLO per il progetto a caso
       della home — corretto dopo una segnalazione vera: "88vh" bastava contro un
       progetto aperto da un CLICK ( che scorre e si centra da solo ), ma sulla home
       la testata e i filtri restano SEMPRE li' sopra, fissi, e "88vh" non li conta —
       88vh di striscia PIU' la testata puo' benissimo superare il 100% dello schermo,
       e la fotografia torna a sfondare sotto il bordo se il calcolo preciso in
       project-expand.js non arriva ( su un motore diverso, con tempi diversi, come
       segnalato ). Qui si sottrae uno spazio fisso e prudente ( testata, filtri,
       margini — misurato largo apposta, meglio un'immagine un poco piu' bassa del
       necessario che una tagliata ) dall'altezza vera dello schermo, invece di una
       semplice percentuale che non sa cosa le sta sopra. */
    .project-row[data-auto-expand="1"] + .project-expand-panel .project-strip {
        /* ⚠️ `max()` con un pavimento di 200px: su uno schermo bassissimo
           `100dvh - 420px` potrebbe scendere sotto zero, e un `max-height` negativo
           non e' un tetto piu' basso — e' un valore che il browser scarta, come se il
           tetto non ci fosse affatto. */
        max-height: max( calc( 100vh - 420px ), 200px );
        max-height: max( calc( 100dvh - 420px ), 200px );
    }
}

/* ⚠️ SENZA, la larghezza intera del calcolo qui sopra puo' aprire per un istante una
   barra di scorrimento ORIZZONTALE ( la verticale della pagina toglie qualche pixel al
   100vw ) proprio mentre il pannello si anima — la si vede comparire e sparire. Stessa
   ricetta di `.has-menu-panel body`, poco sopra in questo foglio, per lo stesso motivo.
.project-expanded { overflow-x: hidden; }

/* la didascalia: la parola-concetto in medium, il nome del progetto in book */
.details { padding-top: 10px; position: relative; }
/* ⚠️ `:is(h1,h2,h3)` e non il solo `h3`: il livello dell'intestazione lo decide ora la
   pagina ( `headingLevel` su `banner` ), e su Contatti la didascalia della fascia e' un
   `h1`. Legata al TAG, quella pagina perdeva corpo, interlinea e colore tutti insieme.
   La specificita' non cambia: `:is()` prende quella del suo argomento piu' alto, che qui
   e' un selettore di tipo. */
.details :is( h1, h2, h3 ) {
    font-size: 1.12rem;
    line-height: 1.25rem;
    color: var( --heading );
    margin-bottom: 0;
}
/* ⚠️ Niente evidenziatore QUI: nelle schede progetto lo si vuole solo sul concetto
   ( vedi ".title .concept" piu' sotto, che lo riaccende da solo ), non su tutta la
   riga concetto+nome insieme — altrimenti il nome, piu' piccolo, finirebbe dentro
   lo stesso riquadro del concetto. Le due forme del titolo, l'h3 nell'elenco e
   l'h1.details-title nella pagina del progetto: vedi il commento piu' sotto sul
   perche' sono due selettori e non uno solo. */
.details :is( h1, h2, h3 ),
.details-title { background: none; padding: 0; margin-left: 0; width: auto; }
/* ⚠️ La scheda di un progetto e' un link che contiene la didascalia: al passaggio del mouse
   ( o con la tastiera ) la descrizione sotto il titolo si scurisce, da `--accent-soft` a
   `--accent`: diventa dello stesso colore del titolo. Il colore lo cambia lo span `.name` e
   non il link, perche' `.details h3` ha gia' il suo colore e quello del link non arriva fin li'. */
a:hover .details .title .concept:not( :empty ) + .name,
a:focus-visible .details .title .concept:not( :empty ) + .name { color: var( --accent ); }
.details :is( h1, h2, h3 ) a { color: inherit; }
/* ⛔ PER CLASSE, NON PER TAG. La regola di prima era `.details .title span`, e nell'elenco
   dei progetti il concetto era testo NUDO mentre il nome stava in uno span: vestiva quindi
   il nome invece del concetto, cioe' l'esatto contrario. Negli altri template erano due
   span, e prendeva tutti e due. Ora ognuno porta il suo ruolo scritto addosso.

   ⚠️ `.details-title` accanto a `.details`: la scheda di un progetto ha l'intestazione in un
   `h1.details-title` che NON sta dentro un `.details`, quindi con il solo discendente di
   `.details` la sua didascalia restava fuori dalla regola.

   ⚠️ Lo stacco fra concetto e nome lo mette il CSS e non uno spazio nel markup: cosi' con il
   concetto vuoto non resta uno spazio davanti al nome. */
:is( .details, .details-title ) .title       { font-family: var( --font-medium ); font-weight: 700; }
:is( .details, .details-title ) .title .name { font-family: var( --font-book ); transition: color 0.5s var( --ease ) 0s; }
:is( .details, .details-title ) .title .concept:not( :empty ) { margin-right: 0.35em; }

/* ⚠️ Il titolo del progetto sta su UNA riga sola: concetto e nome, non piu' impilati. Chi
   scrive la pagina mette un `<br>` davanti al nome — serviva al layout a due righe di prima
   — e qui lo si nasconde via CSS invece di editare a mano le pagine di ogni progetto. */
:is( .project-row .details, .details-title ) .title .name br:first-child { display: none; }

/* NELLE SCHEDE DEI PROGETTI ( elenco e pagina ) il CONCETTO e' il TITOLO: in alto, grande,
   ed E' LUI a portare l'evidenziatore — non il nome sotto, ne' la riga intera. Il NOME e'
   la DESCRIZIONE: piu' piccolo, piu' chiaro, senza sfondo.
   ⚠️ `.concept:not( :empty ) + .name` e non `.name` da solo: altrove ( team, slide, card ) il
   nome e' l'unica riga e deve restare com'e'. ⚠️ Il concetto e' minuscolo e in medium, come
   all'inizio: il maiuscoletto provato il 2026-09-21 e' stato tolto.
   ⚠️ Un `<span>` e' inline: il riquadro segue gia' da solo la larghezza del testo, come
   sul menu — non serve `width: fit-content`, che serve solo agli elementi di blocco. */
:is( .project-row .details, .details-title ) .title .concept {
    color: var( --paper );
    background-color: var( --accent );
    padding: 0.05em 0.3em;
    margin-left: -0.3em;
}
:is( .project-row .details, .details-title ) .title .concept:not( :empty ) + .name {
    font-size: 0.8em;
    color: var( --accent-soft );
}
/* la descrizione sotto un titolo ( il ruolo sotto il nome del team ): terracotta chiaro, come
   il nome sotto il concetto nelle schede dei progetti */
.details .meta-info { font-size: 0.875rem; line-height: 1.5rem; color: var( --accent-soft ); }

/* la descrizione di una card ( es. le novita' ): sotto il titolo, piu' piccola e in terracotta
   chiaro. ⚠️ `.card-item > .text-block` e non `.text-block`: quel nome e' anche il testo lungo
   delle schede e delle pagine, che deve restare scuro e a corpo pieno. */
.card-item > .text-block { font-size: 0.875rem; line-height: 1.5rem; color: var( --accent-soft ); }


/* ─── scheda di un progetto ─────────────────────────────────────────────── */

/* ⚠️ LA STESSA FRECCIA in tre punti del tema: qui, sul pannello degli anni ( piu' sotto,
   `.side-nav-years` ) e sulle frecce della galleria a tutto schermo ( `.full-screen-prev`/
   `-next`, con le fotografie ) — un segno solo, pieno e arrotondato, non tre disegni
   diversi con la stessa idea. Misura e spessore sono `--chevron-size`/`--chevron-weight`
   apposta: chi la usa piu' grande o piu' sottile cambia due numeri, non ridisegna il segno.
   Il verso — dove punta — lo decide chi la usa, con un `transform: rotate()`. */
.chevron {
    display: block;
    fill: none;
    stroke: currentColor;
    stroke-linecap: round;
    stroke-linejoin: round;
    width: var( --chevron-size, 18.7px );
    height: var( --chevron-size, 18.7px );
    stroke-width: var( --chevron-weight, 3.4 );
}

/* ⚠️ RESTYLE sul riferimento ( big.dk ): il titolo di un progetto li' e' grande, quasi un
   manifesto — non piu' la misura di un `h3` di sistema. Rotto apposta il vincolo descritto
   qui sotto ( restava uguale all'h3 di prima ): ora e' una scelta editoriale, non un residuo
   del browser. */
/* ⚠️ PIU' PICCOLO di quanto fosse ( 2.6rem, poi 1.9rem ): nella striscia il titolo sta in
   una colonna stretta ( `.strip-info`, 260px ) — richiesta esplicita, di nuovo piu'
   piccolo. */
.details-title { font-size: 1.5rem; line-height: 1.25; margin: 0 0 1.2rem; }
@media ( max-width: 767px ) { .details-title { font-size: 1.25rem; } }

/* ⚠️ IL NOME VA SEMPRE A CAPO sotto il concetto, qui: richiesta esplicita — non piu' sulla
   stessa riga quando ci sta. `display: block`, non un `<br>` nel markup: cosi' vale anche
   per i progetti la cui pagina non ne porta uno salvato, senza dover editare 61 schede a
   mano. Solo QUI ( `.details-title`, il titolo grande della scheda aperta ): l'elenco e i
   rimandi precedente/seguente restano su una riga sola, dove lo spazio e' quello che e'. */
.details-title .title .name,
.details-title .title .concept:not( :empty ) + .name { display: block; font-size: 0.7em; }

/* ⚠️ « tutti i progetti » e' l'`h1` dell'elenco, ma resta una voce di menu: `font: inherit`
   riporta corpo, famiglia, peso e interlinea a quelli della riga, che da `h1` sarebbero
   2em in grassetto. Il colore lo mette l'`a` dentro, come su tutte le altre voci. */
.list-title    { font: inherit; margin: 0; }

/* IL TESTO LUNGO DI UN MODULO — scheda progetto, `text-section`, `intro-text`.
   ⚠️ E' UN blocco, non un `<p>` per paragrafo: la property e' una stringa e gli a capo li
   disegna `nl2br`. Le misure sono quelle che i `<p>` avevano, cosi' la pagina non cambia
   aspetto.
   ⛔ Ed e' un `div` per una seconda ragione, pagata il 2026-08-26: cio' che si scrive con la
   barra di formattazione puo' essere un BLOCCO — il giustificato di Chrome salva un
   `<div style="text-align">`, una lista un `<ul>` — e un blocco dentro un `<p>` CHIUDE il
   `<p>` nel parser. Il testo finiva fuori dall'elemento con `data-prop-name`: si vedeva, e
   non si poteva piu' modificare. Un nome solo per tutti e tre i moduli, cosi' la prossima
   volta non si sbaglia in uno dei tre. */
.text-block    { line-height: 1.725rem; margin-bottom: 15px; }
.content-info  { margin-top: 65px; }

/* ⚠️ MAIUSCOLO e spaziato: il restyle sul riferimento tratta le etichette dei dati
   ( "data", i titoletti dei crediti ) come quelle di big.dk — piccole, grige, maiuscole,
   spaziate. Prima erano solo in medium/grassetto, stessa misura del testo intorno. */
.content-info h4 {
    font-family: var( --font-book );
    font-size: 0.75rem;
    line-height: 1.5rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var( --ink-soft );
    margin: 0;
    background: none;   /* niente evidenziatore: e' un'etichetta ( "data" ), non un titolo */
    padding: 0;
    margin-left: 0;
}
.content-info p { font-size: 0.875rem; line-height: 1.5rem; margin: 0 0 5px; }
/* ⚠️ RAVVICINATI, non piu' 25px: richiesta esplicita — "data", "cliente", "luogo" sono
   voci di UNA scheda dati, non paragrafi separati, e 25px li leggeva come blocchi
   staccati invece che come righe della stessa tabella. */
.content-info .info-group { margin-bottom: 12px; }
.content-info .info-label { font-family: var( --font-medium ); font-weight: 700; }

/* ⚠️ I crediti sono UN testo, e i titoletti sono il grassetto che ci si scrive dentro: la
   regola da' al `<b>` l'aspetto che aveva `.info-label`, cosi' la pagina non cambia faccia
   pur avendo perso l'elenco di coppie che il template spezzava. Stessa uppercase/spaziatura
   di `.content-info h4` qui sopra, per la stessa ragione. */
.content-info .project-details { font-size: 0.875rem; line-height: 1.5rem; }
/* ⚠️ Non solo `<b>`: qualche scheda vecchia porta i titoletti scritti con uno `<span>` o un
   `<font>` a `font-family: chplus-medium` invece del grassetto — un residuo della barra di
   formattazione di prima del cambio carattere ( 2026-08-25 ). Il testo resta quello, la
   regola prende anche quella forma perche' altrimenti quei titoletti restavano scuri e a
   corpo pieno invece che come tutti gli altri.
   ⚠️ `font-weight: 700`, non piu' `normal`: richiesta esplicita — "data", "cliente", "luogo"
   in neretto, come "DATA" nella striscia qui sopra ( `.info-label`, gia' a 700 ). Prima i
   due titoletti si somigliavano ma non erano UGUALI: uno in grassetto, l'altro no.
   ⚠️ `margin-top` piu' STRETTO ( 0.15em, non 0.4em ): e' lo spazio SOPRA ogni titoletto —
   fra un valore e il titoletto della coppia dopo — e con l'intervallo fra le coppie gia'
   ridotto ( vedi `br + br` qui sotto ) un margine cosi' largo tornava a separarle troppo. */
.content-info .project-details b,
.content-info .project-details span[style*="chplus-medium"],
.content-info .project-details font[face*="chplus-medium"] {
    display: inline-block; margin-top: 0.15em;
    font-family: var( --font-medium ); font-weight: 700;
    font-size: 0.75rem; letter-spacing: 0.06em; text-transform: uppercase; color: var( --ink-soft );
}
/* ⚠️ LA RIGA VUOTA fra una coppia e la prossima e' un `<br><br>` scritto nel testo salvato
   ( vedi il commento su `itemDetails` in project_page.php ) — non si puo' toccare da qui
   senza riscrivere il contenuto di 61 progetti. Si restringe SOLO IL SECONDO dei due `<br>`
   di fila: la sua riga vuota prende l'altezza del font che le si da', quindi un font piu'
   piccolo la rende una riga vuota piu' bassa — il primo `<br>` ( quello fra il titoletto e
   il suo valore, che resta com'e' ) non e' toccato dal selettore. */
.content-info .project-details br + br { font-size: 0.4em; }

/* ⚠️ Il testo del progetto, PIU' GRANDE: nel riferimento il corpo della scheda non e' un
   paragrafo qualunque, ha piu' respiro di quello di una pagina normale — solo qui, non nel
   `.text-block` condiviso con `text-section`/`intro-text`, che restano alla loro misura. */
.strip-text .text-block { font-size: 1.25rem; line-height: 1.8rem; }

.project-img-box { margin: 0; height: 100%; }
.project-img-box figure { height: 100%; margin: 0; position: relative; }


/* ─── scheda di un progetto: la striscia orizzontale ( stile big.dk ) ───────
   ⚠️ TITOLO, DATI, TESTO E FOTOGRAFIE sono TUTTI figli diretti di `.project-strip`, non
   tre blocchi separati di cui solo uno scorre: e' quello a fare "una striscia sola che
   scorre in orizzontale" invece di "una pagina normale con dentro una galleria che
   scorre". Vedi il commento in project_page.php su come sono messi in ordine.

   ⚠️ L'ALTEZZA E' UN TETTO FISSO ( `--strip-height` ), non il contrario: nel disegno di
   riferimento e' la striscia a decidere quanto e' alta la pagina, e ogni fotografia si
   allarga o si stringe per starci dentro mantenendo le sue proporzioni — esattamente
   come gia' succede riga per riga nell'elenco progetti ( `.project-row img`, stesso
   principio, misura diversa perche' li' la riga sta da sola e qui ce ne sono tante
   affiancate ). */
:root {
    --strip-height: 72vh;

    /*
     * ⚠️ IL MARGINE SINISTRO VERO DEL SITO, non il solo gutter: `.container` e' largo
     * al massimo `--container`, e sopra quella misura resta CENTRATO — il suo bordo
     * vero e' il gutter PIU' lo spazio vuoto che lo separa dal bordo della finestra.
     * Sotto quella misura lo spazio vuoto e' zero e resta il solo gutter: `max()` sceglie
     * da solo quale dei due conta, senza una regola a parte per ogni schermo.
     * ⚠️ E' la stessa aritmetica che il marchio in testata eredita gratis da
     * `.container > .row > .header-side` ( gutter e margine negativo del `.row` che si
     * annullano a vicenda ) — qui non c'e' quella catena di annullamenti perche' la
     * striscia non e' dentro un `.container`, quindi la si scrive per esteso una volta
     * sola, qui, invece di where la usa. */
    --content-inset: max( var( --gutter ), calc( ( 100vw - var( --container ) ) / 2 + var( --gutter ) ) );
}

/*
 * ⚠️ `scroll-snap`: SENZA, lo scorrimento a mano ( trackpad, rotella ) lascia spesso un
 * riquadro a META' fuori dal bordo — capitato proprio al testo, che li' si legge a
 * fatica perche' ogni riga finisce contro il bordo della finestra invece che contro il
 * bordo del suo riquadro. `scroll-snap-align: start` su ognuno, qui sotto, fa si' che
 * chi si ferma su un riquadro lo trovi intero.
 * ⚠️ `proximity`, NON `mandatory`: quello obbligava ogni fermata a un riquadro intero,
 * e con la rotella del mouse — che manda un colpo alla volta, non un trascinamento
 * continuo — ogni colpo veniva interpretato come "fermata" e la striscia scattava al
 * riquadro dopo invece di scorrere: non fluido, un salto a scatti. `proximity` aggancia
 * solo quando ci si ferma GIA' vicino a un bordo, e lascia libero lo scorrimento nel
 * mezzo. `scroll-behavior: smooth` ammorbidisce anche quello: la rotella non sposta piu'
 * la striscia di scatto, la accompagna e la rallenta alla fine della corsa.
 * ⚠️ `scroll-padding-left`, UGUALE al `padding-left`: senza, lo snap ignora il padding del
 * contenitore e considera "inizio" il bordo del CONTENUTO, non quello scrollabile — al
 * caricamento la striscia si scrollava da sola di quei pixel per agganciare il primo
 * riquadro al bordo, cancellando il margine appena aggiunto ( lo si vedeva da `scrollLeft`
 * gia' a 79px a pagina appena aperta, invece che a 0 ). Dicendo allo snap dove sta
 * davvero il bordo utile, il margine resta visibile anche dopo l'aggancio.
 */
.project-strip {
    display: flex;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 60px;
    height: var( --strip-height );
    margin: 90px 0 50px;
    padding: 0 var( --gutter ) 0 calc( var( --content-inset ) + 24px );
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    scroll-behavior: smooth;
    scroll-padding-left: calc( var( --content-inset ) + 24px );

    /* ⚠️ NIENTE BARRA DI SCORRIMENTO, richiesta esplicita: lo scorrimento resta ( il
       gesto — rotella, trackpad, dito — continua a funzionare identico ), solo non si
       vede piu' la barra sotto. Tre proprieta' diverse perche' ogni motore la nasconde
       a modo suo: Firefox con `scrollbar-width`, Safari/Chrome vecchio con la
       pseudo-classe qui sotto, i browser piu' recenti con `scrollbar-color: transparent`. */
    scrollbar-width: none;       /* Firefox */
    scrollbar-color: transparent transparent;
}
.project-strip::-webkit-scrollbar { display: none; }   /* Chrome, Safari, Edge */

.project-strip .strip-box {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    height: 100%;
    scroll-snap-align: start;
}
/*
 * ⚠️ TITOLO E DATI ALLINEATI IN ALTO, non centrati come il resto della striscia: nel
 * riferimento il blocco titolo+dati comincia alla cima, alla stessa altezza della cima
 * delle fotografie — sono le fotografie e il testo, piu' alti e vari, a restare
 * centrati in verticale, non questo blocco corto.
 */
.project-strip .strip-info  { width: 260px; justify-content: flex-start; overflow-y: auto; }
/* ⚠️ PIU' STRETTO di prima ( era 420px ): ora e' UN paragrafo per riquadro, non tutta
   la descrizione insieme — un riquadro piu' stretto lo tiene leggibile a un colpo
   d'occhio, senza bisogno di scorrere avanti e indietro dentro la stessa riga. */
.project-strip .strip-text  { width: 340px; overflow-y: auto; }
.project-strip .strip-info .content-info { margin-top: 40px; }
.project-strip .strip-text .text-block { margin-top: 0; }

/* ⚠️ UN VECCHIO TESTO puo' portare `font-family` scritto IN LINEA dalla barra di
   formattazione di prima del cambio carattere — un'istantanea del carattere di
   allora, che nessuna regola qui nel foglio di stile puo' piu' battere in
   specificita'. Qui si toglie con `!important` SOLO dentro i crediti della scheda:
   l'alternativa era riscrivere il testo salvato di ogni progetto che lo porta. */
.content-info .project-details [style*="font-family"] { font-family: var( --font-book ) !important; }

/*
 * ⚠️ LE FOTOGRAFIE RESTANO NODI DI `project-image.php` ( `.col-N.xnode`, con il loro
 * `data-node-id` ): qui si toglie solo il significato che aveva la loro `span` — non
 * piu' UNA LARGHEZZA ( un terzo del `.row`, la meta', tutta ) ma un numero rimasto sul
 * nodo senza effetto sul disegno. La larghezza vera la da' `width: auto` insieme
 * all'altezza fissa della striscia: e' la FORMA della fotografia a decidere quanto e'
 * larga, una volta che e' alta come tutte le altre.
 */
.project-strip > .xnode { flex: 0 0 auto; width: auto; max-width: none; height: 100%; padding: 0; }
.project-strip .project-img-box img {
    height: 100%;
    width: auto;
    max-width: none;
    display: block;
}

/* ⚠️ SOTTO I 767: la striscia torna verticale e alta quanto il suo contenuto — uno
   scorrimento ORIZZONTALE su un telefono, dove il dito scorre gia' la pagina in
   verticale, sarebbe un gesto ambiguo ( su o di lato? ) invece di un gesto naturale.
   `order` rimette in un ordine da leggere dall'alto in basso senza toccare il markup:
   titolo con i suoi dati, poi le fotografie, poi il testo — lo stesso ordine di
   lettura di sopra ( titolo+dati, poi la prima foto, poi il testo ), solo impilato. */
@media ( max-width: 767px ) {
    :root { --strip-height: auto; }

    .project-strip {
        flex-direction: column;
        overflow: visible;
        gap: 40px;
        margin: 70px 0 40px;
        /* ⚠️ SIMMETRICO, non il `+ 24px` di sopra: quello serviva a staccare il
           TITOLO dal bordo in una striscia larga, qui invece il bordo destro e
           sinistro devono restare uguali — le fotografie, impilate, vanno a
           tutta larghezza fra i due margini, non solo da un lato. Lo stesso
           margine che il resto del sito usa sotto i 767 ( vedi `.container`). */
        padding: 0 20px;
        scroll-snap-type: none;   /* la pagina scorre in verticale, qui non c'e' piu' niente da agganciare */
    }
    .project-strip .strip-box   { scroll-snap-align: none; }
    .project-strip .strip-info { order: 1; width: auto; overflow: visible; }
    .project-strip > .xnode    { order: 2; width: 100%; height: auto; }
    .project-strip .strip-text { order: 3; width: auto; height: auto; overflow: visible; }

    .project-strip .project-img-box img { width: 100%; height: auto; }
}


/* ─── una fotografia a tutto schermo ────────────────────────────────────────
   ⚠️ La velatura la crea il JS quando serve e la toglie chiudendo: un div sempre
   presente e nascosto e' `position: fixed` a tutto schermo con `z-index` altissimo, e
   il giorno che una classe non viene tolta e' un velo invisibile che intercetta ogni
   click. E' un incidente gia' pagato, e non lascia traccia: la pagina si vede e non
   risponde. */

/* ⛔ NIENTE PIU' CURSORE A LENTE sulle fotografie della striscia: richiesta esplicita,
   insieme al click che apriva lo zoom — vedi il commento in js/lightbox.js. */

.full-screen-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba( 0, 0, 0, 0.92 );
    cursor: zoom-out;
}

/* ⚠️ `max-*` e non `width: 100%`: una fotografia non si INGRANDISCE oltre la sua misura
   vera, si mostra al massimo che lo schermo consente senza sbordare. */
.full-screen-overlay img {
    max-width: 92vw;
    max-height: 86vh;
    width: auto;
    height: auto;
    display: block;
}

/* ⚠️ LA STESSA FRECCIA del link che torna all'elenco ( `.chevron`, sopra ), grande e sui
   due lati invece che piccola sopra le fotografie — non un disegno a parte per la
   lightbox. "precedente" e' il segno cosi' com'e' ( punta a sinistra ), "successiva" e' lo
   stesso ruotato di 180°. */
.full-screen-prev,
.full-screen-next {
    position: absolute;
    top: 50%;
    transform: translateY( -50% );
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border: 0;
    background: none;
    padding: 0;
    cursor: pointer;
    opacity: 0.6;
    transition: opacity 0.5s var( --ease ) 0s;
}
.full-screen-prev:hover,
.full-screen-next:hover { opacity: 1; }

/* ⚠️ Bianco FISSO, non `--paper`: queste frecce stanno sul velo quasi nero della
   lightbox ( `.full-screen-overlay`, piu' sotto ), non sul fondo pagina. Un tema
   scuro cambia `--paper` in nero, e la freccia sparirebbe sul velo che e' gia' nero
   per conto suo. */
.full-screen-prev .chevron,
.full-screen-next .chevron {
    --chevron-size: 28px;
    --chevron-weight: 3.4;
    stroke: #ffffff;
}
.full-screen-prev { left: 20px; }
.full-screen-next { right: 20px; }
.full-screen-next .chevron { transform: rotate( 180deg ); }

/* dove si e' nella serie: due numeri, non ventitre pallini */
.full-screen-counter {
    position: absolute;
    bottom: 24px;
    left: 0;
    right: 0;
    margin: 0;
    text-align: center;
    color: #ffffff;   /* fisso, stesso motivo delle frecce qui sopra */
    font-size: 0.875rem;
    letter-spacing: 0.08em;
    opacity: 0.7;
    pointer-events: none;
}

@media ( max-width: 767px ) {
    .full-screen-prev { left: 6px; }
    .full-screen-next { right: 6px; }
    .full-screen-overlay img { max-width: 96vw; }
}


/* ─── le persone dello studio ─────────────────────────────────────────────
   Il ritratto riempie la colonna e nome e ruolo stanno sotto, con lo stesso
   `.details` delle didascalie: e' la stessa relazione — un'immagine e cio' che
   la nomina — quindi porta lo stesso segno.

   ⚠️ Il margine sotto serve a schermo STRETTO: sotto i 991 le colonne vanno una
   sull'altra, e senza, il ruolo di uno tocca il ritratto del successivo. */

.person-item { margin-bottom: 40px; }
.person-photo img { display: block; width: 100%; height: auto; }


/* ─── schede ──────────────────────────────────────────────────────────────
   Come le persone: la fotografia riempie la colonna, e sotto la didascalia.
   ⚠️ Il RAPPORTO E' FISSO: tre fotografie affiancate con proporzioni diverse
   ( 2000x1124 e 2000x1062 ) mettevano i titoli su tre altezze diverse. */

.card-item { margin-bottom: 40px; }
.card-item > a { display: block; }
.card-photo img { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.card-item .details { margin-bottom: 10px; }
/* il titolo della scheda in grassetto: il medium, come i `<b>` delle schede progetto. */
.card-item .title .name { font-family: var( --font-medium ); font-weight: 700; }

/* la fila che scorre: tre schede in vista, le altre oltre il bordo.
   ⚠️ La barra di scorrimento RESTA, sottile, al contrario dello slideshow: qui non ci
   sono frecce ne' avanzamento automatico, e senza barra con il mouse non si scorre. */
.card-strip {
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: thin;
}
.card-strip > .card-item { scroll-snap-align: start; }
.card-strip:focus-visible { outline: 1px solid var( --ink ); outline-offset: 3px; }


/* ─── riconoscimenti ────────────────────────────────────────────────────── */

.awards-row { padding: 150px 0; }
.awards-img { margin: 15px 0; text-align: center; }
.awards-img img { max-width: 100%; width: auto; height: auto; }


/* ─── piede ─────────────────────────────────────────────────────────────── */

/* ─── banner dei cookie ─────────────────────────────────────────────────────
   Una fascia in basso, con i colori del sito: un'etichetta, non un avviso.
   ⚠️ `:not([hidden])` sul `display`: scritto sul solo tag, `flex` vincerebbe
   sull'attributo `hidden` e il banner comparirebbe anche a chi ha gia' scelto. */

cookie-consent:not([hidden]) {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    /* ⚠️ La fascia e' larga quanto la finestra, il contenuto quanto il container: sui
       bordi dello schermo testo e bottoni stavano fuori dalla griglia del sito */
    padding: 18px max( var( --gutter ), calc( ( 100% - var( --container ) ) / 2 + var( --gutter ) ) );
    background: var( --paper );
    border-top: 1px solid var( --rule );
    color: var( --ink-soft );
    font-size: 0.875rem;
    line-height: 1.5rem;
}
/* ⚠️ Grigio ( --ink ) e non nero ( --ink-strong ): il banner e' un testo come un altro,
   non il marchio. Il nero pieno resta SOLO sul logo. */
.cookie-consent-text a { color: var( --ink ); text-decoration: underline; }
.cookie-consent-buttons { display: flex; gap: 10px; flex: 0 0 auto; }

/* ⚠️ I due bottoni sono IDENTICI: un « Rifiuta » meno visibile non e' una scelta libera */
.cookie-consent-buttons button {
    font: inherit;
    font-family: var( --font-medium );
    font-weight: 700;
    color: var( --ink );
    background: none;
    border: 1px solid var( --ink );
    padding: 6px 18px;
    cursor: pointer;
    transition: all 0.5s var( --ease ) 0s;
}
.cookie-consent-buttons button:hover { background: var( --ink ); color: var( --paper ); }

@media ( max-width: 767px ) {
    cookie-consent:not([hidden]) { flex-direction: column; align-items: stretch; padding: 16px 20px; }
    .cookie-consent-buttons button { flex: 1; }
}

.site-footer { padding: 50px 0 30px; }

.site-footer .footer-nav li {
    font-family: var( --font-medium );
    font-weight: 700;
    font-size: 0.875rem;
    line-height: 1.5rem;
    margin-bottom: 15px;
    text-transform: lowercase;   /* le stesse voci della testata, stessa forma */
}

/* Il piede porta gli stessi segni, sotto le voci */
.site-footer .social-links { margin-top: 25px; }

.site-footer .contact-info address {
    font-style: normal;
    margin-bottom: 10px;
    padding-bottom: 10px;
    position: relative;
}
/* il trattino di 10px sotto ogni indirizzo, come nel riferimento */
.site-footer .contact-info address::after {
    content: "";
    display: block;
    width: 10px;
    height: 1px;
    background-color: var( --rule );
    position: absolute;
    left: 0;
    bottom: 0;
}
/* ⚠️ `p, address > div`: le due righe modificabili di una sede sono `div` e non `<p>`, perche'
   un blocco salvato dalla barra di formattazione chiuderebbe il `<p>`. La regola vale per
   tutte e due le forme, cosi' il telefono e la posta — che `<p>` restano — non cambiano. */
.site-footer .contact-info :is( p, address > div ) {
    font-size: 0.875rem;
    line-height: 1.5rem;
    color: var( --ink );
    margin: 0;
}
.site-footer .contact-info a { text-decoration: underline; }

.site-footer .copyright,
.site-footer .legal-links {
    font-size: 0.875rem;
    line-height: 0.875rem;
    color: var( --ink );
    margin: 0;
}
.legal-links { text-align: right; }
.legal-links a + a { margin-left: 12px; }


/* ─── in modifica ───────────────────────────────────────────────────────── */

/*
 * ⚠️ Qui sta SOLO cio' che dipende dal markup di QUESTO tema. Selezione, testi
 * modificabili e indicatori di rilascio arrivano da `res/css/inline-edit.css`, che
 * `page-composer.php` inietta da se' con `?edit=1`: erano copiati in ogni tema, e il
 * tema che se li dimenticava aveva un editor che sembrava rotto.
 */

/* ⚠️ Con l'insegna sopra lo slideshow la didascalia di una slide e' nascosta ( vedi piu'
   su ): in modifica pero' quel testo deve essere raggiungibile, altrimenti si puo'
   cambiare la foto e non cio' che ci sta scritto sotto. */
.editing .slideshow.has-overlay .slideshow-slide .details {
    display: block;
    opacity: 0.55;
}


/* ─── schermi stretti ─────────────────────────────────────────────────────
   ⚠️ I quattro scalini sono quelli del riferimento ( 1023 / 991 / 767 / 567 ) e
   vanno in quest'ordine: sono tutti `max-width`, quindi il piu' stretto deve stare
   PIU' IN BASSO o non vince. I 991 sono nostri — il riferimento li' usa la griglia
   di Bootstrap, che collassa a 992 — e restano il punto in cui le colonne si
   impilano. */

@media ( max-width: 1023px ) {
    .text-bigger, .text-bigger p, .text-bigger .text-block { font-size: 28px; }
    .awards-row { padding: 100px 0; }
}

@media ( max-width: 991px ) {
    .col-3, .col-4, .col-6, .col-8, .col-9 { flex: 0 0 100%; max-width: 100%; }
    .offset-4 { margin-left: 0; }

    /* ⚠️ Nella fila le schede NON si impilano: restano affiancate, e la successiva
       spunta dal bordo per dire che si scorre. */
    .card-strip > .card-item { flex: 0 0 80%; max-width: 80%; }

    /* Le tre fasce della testata vanno una sotto l'altra, tutte centrate */
    .site-header .row { flex-wrap: wrap; justify-content: center; }
    .site-header .header-side { flex: 0 0 100%; justify-content: center; }
    .site-header .main-nav ul { flex-wrap: wrap; justify-content: center; }

    /* ⚠️ Su mobile la colonna delle categorie va SOPRA i progetti e torna
       orizzontale: sticky su uno schermo alto 700px mangerebbe mezza pagina. */
    /* ⚠️ Su mobile la riga torna verticale: testo sopra, fotografia sotto — affiancati non
       ci sarebbero stati, ed e' lo stesso adattamento che il resto del tema fa scendendo
       sotto i 991px. */
    .project-row, .project-row > a { flex-direction: column; align-items: flex-start; gap: 20px; }
    .project-row .details { width: 100%; }
    .project-row figure { width: 100%; justify-content: flex-start; }
    .project-row img { width: 100%; max-height: none; }
    .filter-tabs { gap: 8px 20px; }

    .content-info { margin-top: 35px; }
    .legal-links { text-align: left; margin-top: 20px; }
}

@media ( max-width: 767px ) {
    /* sul telefono il riferimento allarga il solo padding del container, non il gutter */
    .container { padding: 0 20px; }

    /* la testata del riferimento passa da 122px a 72px: 30 + 22 di contenuto + 20 */
    .site-header { padding: 30px 0 20px; }
    .main-nav ul { gap: 20px; }
    .project-row { padding: 30px 0; }
    .project-filters { padding-bottom: 20px; margin-bottom: 30px; }
    .section-row { padding: 30px 0; }
    .awards-row { padding: 50px 0; }
    .text-bigger, .text-bigger p, .text-bigger .text-block { font-size: 24px; }
    .strip-text .text-block { font-size: 1.0625rem; line-height: 1.625rem; }
}

@media ( max-width: 567px ) {
    .text-bigger, .text-bigger p, .text-bigger .text-block { font-size: 20px; }
    .awards-row { padding: 30px 0; }
    .content-info { margin-top: 30px; }
}


/* ─── il menu a pannello, dal marchio ────────────────────────────────────────
   Il marchio apre il menu — come il segno in alto a sinistra su big.dk — SU OGNI
   misura di schermo, non solo sul telefono: la navigazione non sta mai in chiaro
   in testata, esce sempre come un pannello che entra da destra mentre la pagina
   resta ferma sotto ( 275px, grigio, voci bianche, la curva del riferimento ).

   ⚠️ TUTTO STA DIETRO `has-menu-panel`, che mette il JS. Senza — JavaScript spento,
   file non arrivato — queste regole non si applicano e il menu resta impilato nella
   testata: raggiungibile. Scritte senza guardia, un browser senza JS avrebbe il menu
   parcheggiato fuori schermo e un marchio che non lo riporta indietro.

   ⚠️ IL PANNELLO SI APRE SOPRA LA PAGINA, che resta ferma — si muove il solo
   pannello, con `transform`, che il browser sposta senza rifare il layout. */

.has-menu-panel .site-header { position: relative; z-index: 9000; }

/*
 * ⚠️ SOTTO AL MARCHIO, non un pannello a tutta altezza da destra: un riquadro che
 * scende dal punto in cui sta il logo, come un menu a tendina qualunque — non una
 * pagina di navigazione a parte che copre lo schermo. `left` allineato al gutter
 * della testata: e' li' che comincia `.header-side`, cioe' il marchio.
 * ⚠️ `max-height` + `overflow-y`: con tante voci ( o lo schermo basso di un telefono
 * in orizzontale ) il riquadro non deve mai uscire sotto al bordo della finestra.
 */
.has-menu-panel .site-header .main-nav {
    position: absolute;
    top: 100%;
    left: var( --gutter );
    width: 275px;
    max-width: calc( 100vw - var( --gutter ) * 2 );
    max-height: calc( 100vh - 100% - var( --gutter ) );
    overflow-y: auto;
    padding: 25px 30px;
    background: var( --ink );
    box-shadow: 0 16px 40px rgba( 0, 0, 0, 0.22 );
    z-index: 1000;

    /* ⚠️ Sceso di qualche pixel e trasparente da chiuso, non tradotto fuori schermo:
       e' una tendina che scende dal marchio, non un pannello che arriva da un bordo.
       `pointer-events: none` da chiuso: anche a un pixel di distanza non deve
       intercettare click sulla pagina sotto. */
    transform: translateY( -8px );
    opacity: 0;
    pointer-events: none;
    transition: transform 0.35s var( --ease ) 0s, opacity 0.35s var( --ease ) 0s;
}

.has-menu-panel .nav-active .main-nav {
    transform: translateY( 0 );
    opacity: 1;
    pointer-events: auto;
}

.has-menu-panel .main-nav ul {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 20px;
}
.has-menu-panel .main-nav li { margin: 0; font-size: 16px; }
.has-menu-panel .main-nav a,
.has-menu-panel .main-nav span,
.has-menu-panel .main-nav summary { color: var( --paper ); }
/* ⚠️ Il pannello e' GRIGIO ( `--ink` ), FISSO in ogni tema: la voce attiva e quella sotto
   il dito sono il solito riquadro d'accento, e il testo ci va `--paper`, NON bianco
   fisso — da quando `--accent` e' diventato `--ink-strong` ( il restyle bianco e nero,
   niente piu' rosso mattone che restava rosso in ogni tema ) l'accento stesso DIVENTA
   bianco nello scuro, e un bianco fisso ci si confondeva sopra ( bianco su bianco,
   invisibile — misurato aprendo il pannello col tema scuro attivo ). `--paper` e'
   sempre l'estremo OPPOSTO di `--accent`/`--ink-strong`, in ogni tema: e' la stessa
   coppia che usa gia' `.main-nav > ul > li.active > a` per il riquadro della voce
   attiva in chiaro, qui dentro ripetuta. Il padding sta su TUTTE le voci, cosi' la
   voce evidenziata non si sposta rispetto alle altre.
   ⚠️ `summary` mancava: era rimasta col grigio di default ( `.mega-menu summary` ), lo stesso grigio dello sfondo
   del pannello — la voce "Progetti" spariva, non solo perdeva contrasto. */
.has-menu-panel .main-nav a { display: inline-block; padding: 0.05em 0.3em; margin-left: -0.3em; }
.has-menu-panel .main-nav a:hover,
.has-menu-panel .main-nav .active > a { color: var( --paper ); background-color: var( --accent ); }

/* ⚠️ Il mega-menu, in QUESTO pannello, si apre IN LINEA e non fluttuante: da fluttuante
   ( `position: absolute`, pensato per la testata larga di prima ) sarebbe uscito dai
   275px del pannello o ci sarebbe finito sotto. Qui prende la larghezza del pannello e
   spinge giu' le voci sotto di se', come l'accordion degli anni nell'elenco progetti. */
.has-menu-panel .mega-menu-panel {
    position: static; box-shadow: none; background: none; min-width: 0; padding: 14px 0 0;
}
.has-menu-panel .mega-menu-panel a { color: var( --paper ); font-size: 16px; }
.has-menu-panel .mega-menu-panel li.active a { color: var( --paper ); font-weight: 700; }
.has-menu-panel .mega-menu .chevron { stroke: var( --paper ); }

/* ⚠️ `overflow-x` sempre, non solo da aperto: il pannello sta appoggiato al bordo
   destro e chiuso e' tradotto FUORI, quindi senza questa riga la pagina avrebbe una
   barra di scorrimento orizzontale che porta sul nulla. Da aperto si ferma anche lo
   scorrimento verticale, cosi' la pagina dietro non scivola sotto il dito. */
.has-menu-panel body { overflow-x: hidden; }
.has-menu-panel body.nav-active { overflow: hidden; }

/* ⚠️ SOLO QUI SOTTO I 1024: la RIGA della testata (una fascia sola invece delle tre
   impilate dei 991, pensate per una nav in chiaro che qui non c'e' mai piu') e lo
   spazio per i segni social, che sotto quella misura si tolgono dalla testata — ci
   sono gia' nel piede. Sopra i 1024 restano, come sempre: il pannello del menu non
   gli serve piu' spazio, visto che apre sempre SOPRA la pagina e non di fianco.
   ⚠️ 1024px e non 767: un iPad verticale ( 744-1024px a seconda del modello ) cadeva
   nel breakpoint dei 991 qui sopra, pensato per una finestra stretta, non un tablet. */
@media ( max-width: 1024px ) {
    .has-menu-panel .site-header .row { flex-wrap: nowrap; }
    .has-menu-panel .site-header .header-side { flex: 1 1 auto; justify-content: flex-start; }
    .has-menu-panel .site-header .header-side-end { justify-content: flex-end; }
    .has-menu-panel .site-header .header-side-end .social-links,
    .has-menu-panel .site-header .header-side-end .social { display: none; }
}


/* ─── slideshow ─────────────────────────────────────────────────────────────
   ⚠️ Prima di tutto e' una striscia che scorre, e funziona COSI' anche senza
   JavaScript: `scroll-snap` da' lo scatto, il dito e il trackpad fanno il resto.
   Il JS aggiunge frecce, pallini e avanzamento — se non parte non si perde
   niente di leggibile. Uno slideshow costruito al contrario ( slide nascoste,
   la prima mostrata dallo script ) senza script non mostra NULLA. */

/* ⚠️ Il riferimento per l'insegna e per le frecce e' il CONTENITORE, non il blocco
   esterno: con `position: relative` sul solo `.slideshow`, la velatura si stendeva per
   tutta la larghezza della pagina e ai lati dell'immagine restavano due macchie grigie
   sul bianco. */
.slideshow > .container { position: relative; }

.slideshow {
    position: relative;
    margin-bottom: 40px;
    /* ⚠️ L'altezza e' quella dell'apertura del riferimento, MISURATA: li' la fascia e'
       un'immagine sola 1280x853 con `height: auto` dentro il container, cioe' 3:2 sulla
       larghezza del container. Qui le slide sono sei e vanno da 1.33 a 1.88 di
       proporzione, quindi un'altezza UNIFORME e `object-fit` restano obbligatorie —
       senza, la pagina sobbalza a ogni cambio.
       Container 1330 ( 1180 sotto i 1400 ) meno i due gutter, diviso 3:2.
       ⚠️ `100vw` comprende la barra di scorrimento: sono ~10px su 866 di altezza, e
       `cover` se li mangia. */
    --slide-height: calc(
        min( 100vw - var( --gutter ) * 2, var( --container ) - var( --gutter ) * 2 ) / 1.5 );
}

.slideshow-track {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    /* la barra sotto le fotografie e' rumore: lo scorrimento si vede dalle immagini */
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.slideshow-track::-webkit-scrollbar { display: none; }
.slideshow-track:focus-visible { outline: 1px solid var( --ink ); outline-offset: 3px; }

.slideshow-slide {
    flex: 0 0 100%;
    max-width: 100%;
    margin: 0;
    scroll-snap-align: start;
    position: relative;
    background: var( --paper );
}
.slideshow-slide img {
    width: 100%;
    height: auto;
    display: block;
    /* ⚠️ `object-fit: cover` e non `contain`: contain lascerebbe bande vuote sopra
       e sotto le immagini piu' larghe, cover taglia un po' ai bordi. Su fotografie
       di architettura il taglio si perdona, le bande no. */
    height: var( --slide-height );
    object-fit: cover;
}

/* l'insegna sopra l'immagine — usata dall'apertura della home */
.slideshow-overlay {
    position: absolute;
    top: 0;
    bottom: 0;
    left: var( --gutter );
    right: var( --gutter );
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 0 var( --gutter );
    pointer-events: none;   /* il click deve arrivare alla slide sotto… */
    overflow: hidden;       /* la velatura non deve uscire dall'immagine */
}

/*
 * ⚠️ Una velatura MORBIDA dietro il solo testo, non un velo su tutta la fotografia:
 * su un cielo chiaro il bianco spariva ( il sottotitolo e il bottone erano
 * illeggibili sulla seconda slide ), ma scurire l'intera immagine per salvare tre
 * righe rovina proprio cio' che si e' venuti a guardare. Il gradiente e' centrato sul
 * testo e ai bordi non c'e' piu'.
 */
.slideshow-overlay::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    transform: translateY( -50% );
    height: 62%;
    background: radial-gradient( ellipse at center,
                                 rgba( 0, 0, 0, 0.42 ) 0%,
                                 rgba( 0, 0, 0, 0.22 ) 45%,
                                 rgba( 0, 0, 0, 0 ) 72% );
    pointer-events: none;
}
.slideshow-overlay > * { position: relative; }

/* l'insegna sfuma quando la striscia si muove, e torna sulla prima immagine */
.slideshow-overlay { transition: opacity 0.5s var( --ease ) 0s; }

/* ⚠️ Spenta su home E studio, le uniche due pagine che oggi la usano ( non su
   `.slideshow-overlay` da sola, che la spegnerebbe anche su una pagina futura che la
   volesse davvero ). La stessa scritta sta ora nella testata ( `.brand-tagline` ),
   su OGNI pagina: qui sulla foto era doppia. */
body[data-slug="home"] .slideshow-overlay,
body[data-slug="studio"] .slideshow-overlay { display: none; }
.slideshow.overlay-hidden .slideshow-overlay { opacity: 0; pointer-events: none; }
.slideshow-overlay a { pointer-events: auto; }   /* …tranne sul bottone */

/* ⚠️ Da qui in giu', fino alle frecce dello slideshow: bianco FISSO, non `--paper`.
   Questo testo e questi bottoni stanno SOPRA UNA FOTO, non sul fondo della pagina —
   un tema scuro cambia `--paper` in nero, e ci sparirebbero addosso. */
.slideshow-overlay h1 {
    font-family: var( --font-medium );
    font-weight: 700;
    background: none;   /* niente evidenziatore qui: vedi il commento sulla regola generale */
    padding: 0;
    margin-left: 0;
    font-size: clamp( 1.4rem, 3.2vw, 2.6rem );
    line-height: 1.15;
    letter-spacing: 0.01em;
    color: #ffffff;
    margin: 0 0 10px;
    /* ⚠️ Un'ombra larghissima e appena percettibile, non un velo scuro sopra la
       foto: il testo bianco su una fotografia chiara sparisce, e scurire l'intera
       immagine per salvare due righe rovina proprio cio' che si vuole mostrare. */
    text-shadow: 0 1px 18px rgba( 0, 0, 0, 0.5 );
}
.slideshow-subtitle {
    font-family: var( --font-light );
    font-size: clamp( 0.8rem, 1.3vw, 1rem );
    letter-spacing: 0.32em;
    text-transform: uppercase;
    color: #ffffff;
    margin: 0;
    text-shadow: 0 1px 16px rgba( 0, 0, 0, 0.5 );
}
/* ⚠️ Con l'insegna sopra, la didascalia sotto NON si mostra: la stessa immagine
   porterebbe due testi che si contraddicono. La regola sta qui e non nel template
   perche' una slide non puo' sapere cosa ha scritto sopra di lei. */
.slideshow.has-overlay .slideshow-slide .details { display: none; }

.slideshow-cta {
    margin-top: 26px;
    padding: 9px 20px;
    border: 1px solid rgba( 255, 255, 255, 0.85 );
    color: #ffffff;
    font-size: 0.875rem;
    backdrop-filter: blur( 2px );
}
/* ⚠️ Bianco pieno e grigio scuro FISSI, non `--paper`/`--ink`: e' un bottone sulla FOTO,
   non sulla pagina, quindi resta lo stesso in ogni tema — vedi il commento su
   ".slideshow-overlay h1" qui sopra. */
.slideshow-cta:hover { background: #ffffff; color: #1a1a1a; }

/* a tutta finestra: spenta di default, esiste per chi la chiede.
   90px erano l'altezza della vecchia testata; ora sono i 122 del riferimento. */
.slideshow-full { --slide-height: calc( 100vh - 122px ); }

/* le frecce */
.slideshow-controls button {
    position: absolute;
    /* a meta' dell'IMMAGINE, non del blocco: sotto ci sono i pallini, e con il 50%
       del blocco le frecce scendevano sotto il bordo della fotografia */
    top: calc( var( --slide-height ) / 2 );
    transform: translateY( -50% );
    width: 34px;
    height: 34px;
    border: 0;
    background: none;
    cursor: pointer;
    padding: 0;
    opacity: 0.55;
    transition: opacity 0.5s var( --ease ) 0s;
}
.slideshow-controls button:hover { opacity: 1; }
/* ⚠️ Bianco FISSO: le frecce stanno sulla FOTO che scorre, non sul fondo pagina.
   Stesso motivo del commento su ".slideshow-overlay h1". */
.slideshow-controls button::before {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    width: 12px;
    height: 12px;
    border-top: 1px solid #ffffff;
    border-right: 1px solid #ffffff;
}
/* ⚠️ Anche le frecce si misurano dal container: sul `.slideshow` finivano ai bordi
   della finestra, lontanissime dall'immagine su cui dovrebbero agire. */
.slideshow-prev { left: calc( var( --gutter ) + 10px ); }
.slideshow-next { right: calc( var( --gutter ) + 10px ); }
.slideshow-prev::before { transform: rotate( -135deg ); }
.slideshow-next::before { transform: rotate( 45deg ); }

/* i pallini */
.slideshow-dots {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin-top: 14px;
}
.slideshow-dot {
    width: 22px;
    height: 2px;
    padding: 0;
    border: 0;
    background: var( --ink-faint );
    cursor: pointer;
    transition: background 0.5s var( --ease ) 0s;
}
.slideshow-dot.active { background: var( --accent ); }

/* ⚠️ Chi ha chiesto meno movimento non deve vedere lo scatto dello scorrimento:
   l'avanzamento automatico lo spegne gia' il JS, questo toglie l'animazione. */
@media ( prefers-reduced-motion: reduce ) {
    .slideshow-track { scroll-behavior: auto; }
    .slideshow-controls button,
    .slideshow-dot { transition: none; }
}

@media ( max-width: 767px ) {
    /* ⚠️ Qui si LASCIA il riferimento, e per un motivo: sul telefono la sua fascia 3:2
       sarebbe alta 230px, e sopra la nostra ci sta l'insegna con il nome dello studio,
       che li' non c'e'. Una frazione di finestra la tiene leggibile. */
    .slideshow { --slide-height: 46vh; }
    .slideshow-full { --slide-height: 60vh; }
    .slideshow-overlay h1 { font-size: 1.3rem; }
}

@media ( max-width: 567px ) {
    /* le frecce si stringono al bordo, come nel riferimento */
    .slideshow-prev { left: 15px; }
    .slideshow-next { right: 15px; }
    .slideshow-dots { margin-top: 10px; }
}

/* ⛔ I RIMANDI PRECEDENTE/SEGUENTE ( `.project-nav` e le sue classi ) NON CI SONO PIU':
   richiesta esplicita — tolti da `project_page.php` insieme al filo che li separava dal
   resto della scheda. Questo era il loro blocco di stile. */

/* ─── puzzle delle copertine ────────────────────────────────────────────────
   Diciotto colonne per nove righe di celle quadrate: `aspect-ratio` sul contenitore dice l'altezza,
   le righe si dividono in parti uguali. I pezzi si toccano ( niente `gap` ): senza un rettangolo
   intorno e con i gradini agli angoli sono le fotografie stesse a disegnare la sagoma. Un filo di
   `--paper` tra un pezzo e l'altro ( `outline` negativo ) li fa leggere come pezzi, non come un'unica
   immagine. */
/* un livello suo: le foto restano SOTTO la testata anche spinte in alto. `overflow-x: clip`: una foto spinta o
   ruotata oltre il bordo si taglia alla finestra invece di far scorrere la pagina in orizzontale */
.cover-puzzle { margin: 70px 0 40px; position: relative; z-index: 0; isolation: isolate; overflow-x: clip; }
.site-header { position: relative; z-index: 20; }
/* ⚠️ Cio' che viene dopo il puzzle gli sta SOPRA: le foto spinte in basso finiscono sotto la prima scritta,
   che resta leggibile. */
.cover-puzzle ~ * { position: relative; z-index: 1; }
.cover-puzzle-grid {
    touch-action: pan-y;   /* col dito si trascina in orizzontale; in verticale la pagina scorre come sempre */
    display: grid;
    grid-template-columns: repeat( 18, 1fr );
    grid-template-rows: repeat( 9, 1fr );
    aspect-ratio: 2 / 1;
}
.puzzle-tile { position: relative; display: block; overflow: hidden; }
.puzzle-tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }

/* La scrivania: i pezzi stanno SEMPRE sparpagliati come fotografie posate — senza cornice, con l'ombra —
   con la trasformazione scritta dal server su ogni pezzo ( `--r`, `--tx`, `--ty`, `--s`, `--z` ) e lo
   spostamento in pixel che `cover-puzzle.js` aggiunge quando il puntatore li sposta ( `--px`, `--py`,
   `--pr` ). Il pezzo sotto il puntatore sale in primo piano. */
.puzzle-tile {
    transform: translate( calc( var( --tx, 0% ) + var( --px, 0px ) ), calc( var( --ty, 0% ) + var( --py, 0px ) ) )
               rotate( calc( var( --r, 0deg ) + var( --pr, 0deg ) ) ) scale( calc( var( --s, 1 ) * var( --k, 1.2 ) * var( --lift, 1 ) ) );
    z-index: var( --z, 1 );
    box-shadow: 0 4px 12px rgba( 0, 0, 0, 0.32 );
    outline: none;
    /* ⚠️ La curva ha un piccolo SUPERAMENTO: un pezzo che arriva al bordo va un filo oltre il punto in cui deve
       fermarsi e poi torna — e' quello il rimbalzo verso il centro. */
    transition: transform 0.55s cubic-bezier( 0.3, 1.5, 0.5, 1 ) 0s;
}
/* Si prende e si trascina: la mano, e nessuna selezione o trascinamento nativo dell'immagine. Col dito
   `pan-y` lascia scorrere la pagina finche' il JS non decide che si sta trascinando una fotografia. */
.puzzle-tile { cursor: grab; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; touch-action: pan-y; }
.puzzle-tile img { pointer-events: none; -webkit-user-drag: none; }
/* Presa in mano: sale sopra tutte, un filo piu' grande, con l'ombra piu' lunga, e segue il puntatore SENZA
   la transizione — altrimenti resterebbe indietro. */
.puzzle-tile.dragging { cursor: grabbing; transition: none; --lift: 1.06; box-shadow: 0 10px 24px rgba( 0, 0, 0, 0.4 ); }
.puzzle-tile img { transition: none; }
@media ( prefers-reduced-motion: reduce ) { .puzzle-tile { transition: none; } }

/* Su telefono le diciotto colonne sono strette: le celle si fanno piu' alte che larghe ( 1,1 : 1 al posto di 2 : 1 )
   cosi' le fotografie hanno un po' di corpo. */
@media ( max-width: 767px ) {
    .cover-puzzle-grid { aspect-ratio: 1 / 1; }
    .cover-puzzle { margin: 40px 0 30px; }
}

/* ⚠️ `--k` e' l'ingrandimento di TUTTI i pezzi, sopra la scala a caso del server: +68% su schermo grande ( il 40% in piu' del +20% di prima ),
   il doppio sul telefono, dove le foto sono di 40px in partenza e non si leggono. */
.puzzle-tile { --k: 1.68; }
@media ( max-width: 767px ) {
    /* ⚠️ Sul telefono i pezzi sono QUADRATI: le colonne sono strette e le righe alte, e lasciar decidere la
       forma alla griglia dava strisce di 76x159. Con `aspect-ratio` l'altezza segue la larghezza del pezzo,
       e il pezzo sta al centro della sua cella. */
    .puzzle-tile { --k: 3; aspect-ratio: 1 / 1; align-self: center; }
    /* ⚠️ Sul telefono meta' delle copertine: una si' e una no, in ordine di lettura del mosaico, cosi' i buchi
       stanno dappertutto e non solo in fondo. Quelle nascoste non si scaricano ( sono `lazy` da dodici in poi ). */
    .puzzle-tile:nth-child( even ) { display: none; }
}

/* Sul telefono le foto sono di 40px: un'ombra di 12px di sfocatura le sommerge, e in 60 si sommano in una nebbia
   grigia. Qui l'ombra e' un filo. */
@media ( max-width: 767px ) { .puzzle-tile { box-shadow: 0 1px 4px rgba( 0, 0, 0, 0.35 ); } }

/* Il segno che invita a prendere le foto. All'inizio: un tondo con quattro frecce in basso a sinistra del puzzle, sopra
   le foto ( il puzzle ha il suo livello, e questo sta sopra qualunque foto ) ma senza intercettare il puntatore, che
   pulsa piano. Poi `js/cover-puzzle.js` gli mette `.is-pointer`: il tondo si scioglie e resta un DITO che punta, con due
   cerchi concentrici alla punta ( `.touching` li anima: il tocco ). Col movimento ridotto resta il tondo, fermo. */
.cover-puzzle .container { position: relative; }
.cover-puzzle-hint {
    position: absolute; bottom: 12px; left: var( --gutter, 20px ); z-index: 2000000000;
    width: 36px; height: 36px; border-radius: 50%;
    background: var( --paper ); color: var( --accent ); border: 1.5px solid var( --accent );
    pointer-events: none;
    transition: opacity 0.6s var( --ease ) 0s, transform 0.6s var( --ease ) 0s,
                left 1.1s cubic-bezier( 0.5, 0, 0.2, 1 ) 0s, top 1.1s cubic-bezier( 0.5, 0, 0.2, 1 ) 0s,
                background-color 0.5s var( --ease ) 0s, border-color 0.5s var( --ease ) 0s;
}
.cover-puzzle-hint.following { transition: opacity 0.6s var( --ease ) 0s, transform 0.6s var( --ease ) 0s; }   /* incolla al dito: senza scivolamento */
.cover-puzzle-hint::after {
    content: ''; position: absolute; inset: -1.5px; border-radius: 50%; border: 1.5px solid var( --accent );
    animation: cover-puzzle-pulse 2.6s ease-out infinite;
}
.cover-puzzle-hint svg { position: absolute; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; transition: opacity 0.4s var( --ease ) 0s; }
.cover-puzzle-hint .hint-arrows { left: 9px; top: 9px; width: 18px; height: 18px; }
/* il dito: 44px, la punta dell'indice a ( 17.5, 5.5 ) dentro al segno; bianco col contorno d'accento e un'ombra, perche'
   sta sopra fotografie di ogni colore */
.cover-puzzle-hint .hint-finger { left: 0; top: 0; width: 44px; height: 44px; opacity: 0; fill: #ffffff; stroke: var( --accent ); stroke-width: 1.5;
    filter: drop-shadow( 0 0 1px rgba( 0, 0, 0, 0.6 ) ) drop-shadow( 0 2px 4px rgba( 0, 0, 0, 0.45 ) ); }
.cover-puzzle-hint.is-pointer { background: transparent; border-color: transparent; }
.cover-puzzle-hint.is-pointer::after { animation: none; opacity: 0; }
.cover-puzzle-hint.is-pointer .hint-arrows { opacity: 0; }
.cover-puzzle-hint.is-pointer .hint-finger { opacity: 1; }
.cover-puzzle-hint.gone { opacity: 0; transform: scale( 0.6 ); }

/* i due cerchi: centrati sulla punta del dito, partono uno dopo l'altro e si allargano svanendo — un tocco */
.hint-ripple { position: absolute; left: 17.5px; top: 5.5px; width: 0; height: 0; }
.hint-ripple i {
    position: absolute; left: -22px; top: -22px; width: 44px; height: 44px; border-radius: 50%;
    border: 2px solid var( --accent ); box-shadow: 0 0 0 1px rgba( 255, 255, 255, 0.7 ); opacity: 0;
}
.cover-puzzle-hint.touching .hint-ripple i { animation: cover-puzzle-touch 1.1s ease-out infinite; }
.cover-puzzle-hint.touching .hint-ripple i:nth-child( 2 ) { animation-delay: 0.4s; }
@keyframes cover-puzzle-pulse { 0% { transform: scale( 1 ); opacity: 0.55; } 100% { transform: scale( 1.7 ); opacity: 0; } }
@keyframes cover-puzzle-touch { 0% { transform: scale( 0.25 ); opacity: 0.9; } 100% { transform: scale( 1.4 ); opacity: 0; } }
@media ( prefers-reduced-motion: reduce ) { .cover-puzzle-hint::after, .cover-puzzle-hint.touching .hint-ripple i { animation: none; } }

/* Col mouse il segno E' il puntatore: sul puzzle il puntatore di sistema si nasconde ( `.pointer-mode`, scritto da
   `js/cover-puzzle.js` ) e resta il dito con i cerchi. Premuto, il dito si stringe un poco. */
.cover-puzzle-grid.pointer-mode, .cover-puzzle-grid.pointer-mode .puzzle-tile, .cover-puzzle-grid.pointer-mode .puzzle-tile.dragging { cursor: none; }
.cover-puzzle-hint.pressed .hint-finger { transform: scale( 0.86 ); transform-origin: 17.5px 5.5px; }
.cover-puzzle-hint .hint-finger { transition: opacity 0.4s var( --ease ) 0s, transform 0.15s var( --ease ) 0s; }

/* Chi ha gia' preso una foto non ha piu' bisogno dell'invito: il segno a riposo non si vede, e sul puzzle resta
   solo il dito — senza cerchi che pulsano, che compaiono soltanto premendo. Cosi' la manina di sistema non torna. */
/* A riposo il segno non si vede mai: compare solo come puntatore ( col mouse ) o durante la dimostrazione ( col dito ). */
.cover-puzzle-hint:not( .is-pointer ) { opacity: 0; }
.cover-puzzle-hint.learned.touching:not( .pressed ) .hint-ripple i { animation: none; opacity: 0; }
.cover-puzzle-hint.learned.pressed .hint-ripple i { animation: cover-puzzle-touch 1.1s ease-out infinite; }
.cover-puzzle-hint.learned.pressed .hint-ripple i:nth-child( 2 ) { animation-delay: 0.4s; }

/* ─── la manina del tocco ────────────────────────────────────────────────────
   Sostituisce il dito a contorno: mano PIENA inclinata con due archi concentrici alla punta ( come l'icona del
   "tocco" ). Del colore dei cerchi ( `--ring`: rosso nel chiaro, arancio nello scuro ), piena, senza bordo ne' ombra. La punta dell'indice sta a
   ( 11.2, 11.2 ) px dentro al segno: `TIP_X`/`TIP_Y` in `cover-puzzle.js`. I vecchi cerchi `.hint-ripple` non servono piu'. */
.hint-ripple { display: none; }
.cover-puzzle-hint .hint-finger {
    left: 0; top: 0; width: 41.6px; height: 36px; fill: var( --ring ); stroke: none;
    filter: none;
}
.cover-puzzle-hint .hint-hand { fill: var( --ring ); stroke: none; }
.cover-puzzle-hint .hint-arc { fill: none; stroke: var( --ring ); stroke-width: 2.6; stroke-linecap: round; stroke-dasharray: 75 25; stroke-dashoffset: -25; transform-origin: 16px 16px; }   /* l'apertura sta a sud-est, dal lato della mano */
.cover-puzzle-hint.pressed .hint-finger { transform: scale( 0.9 ); transform-origin: 11.2px 11.2px; }

/* il tocco: i due archi partono uno dopo l'altro dalla punta e si allargano svanendo */
.cover-puzzle-hint.is-pointer .hint-arc { animation: cover-puzzle-arc 1.1s ease-out infinite; }
.cover-puzzle-hint.is-pointer .hint-arc:nth-of-type( 2 ) { animation-delay: 0.4s; }
@keyframes cover-puzzle-arc { 0% { transform: scale( 0.7 ); opacity: 1; } 100% { transform: scale( 1.2 ); opacity: 0; } }
@media ( prefers-reduced-motion: reduce ) { .cover-puzzle-hint.is-pointer .hint-arc { animation: none; } }

/* I cerchi del tocco e la manina prendono il colore dell'evidenziatore: nero nel chiaro, bianco
   nello scuro — segue --accent per cascata, non serve ridichiararlo per tema. Animati sempre,
   finche' il puntatore e' sul puzzle. */
.cover-puzzle { --ring: var( --accent ); }

/* Mentre si trascina una foto le altre scivolano piano e SENZA il superamento della curva a molla ( quella serve al
   rimbalzo del rilascio ): con la molla, ogni spinta le faceva oscillare — vibravano. */
.cover-puzzle-grid.grid-dragging .puzzle-tile:not( .dragging ) { transition: transform 0.22s ease-out; }
