/*
 * 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. */
/* ⚠️ `position: sticky; top: 0`, richiesta esplicita: "il marchio in alto a sinistra
   che si trasforma in menu, fosse sempre visibile anche quando scorro la galleria
   progetti". Da `relative` ( vedi le due regole piu' sotto che lo impostavano per lo
   z-index, ora sticky anche loro ) la testata scorreva via con il resto della pagina
   come una riga qualunque — aprendo un progetto e scorrendo la sua galleria, il
   marchio ( e con lui il modo di raggiungere il menu ) spariva dallo schermo. Sticky
   la fissa in cima alla finestra appena il resto della pagina le scorre sotto, senza
   toglierla dal flusso normale finche' non ci si arriva scorrendo — `background`,
   gia' qui sotto, la rende opaca sopra a cio' che le scorre dietro. */
.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, .intro-logo-layer { display: none; }

html[data-intro="pending"] .intro-veil,
html[data-intro="leaving"] .intro-veil {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 10000;   /* sopra il banner cookie ( 9999 ): e' la primissima cosa che si vede */
    /* ⚠️ NERO FISSO, non piu' `var( --paper )` — richiesta esplicita: "all'apertura del
       sito in chiaro avro' la pagina nera". Col tema chiaro `--paper` e' bianco: il
       velo si vedeva bianco con un marchio nero sopra, non la tendina nera del
       riferimento — quella restava tale SOLO nel tema scuro, dove `--paper` e' gia'
       nero per conto suo. Un nero scritto a mano, non legato al tema, apre sempre
       con la stessa tendina scura qualunque sia il tema scelto. */
    background: #000000;
    transform: translateY( 0 );
    will-change: transform;
}

/*
 * ⚠️ `.intro-logo-layer`: un FRATELLO di `.intro-veil`, non un suo contenitore — vedi
 * il commento in `header.php` sul perche' sono due elementi `fixed` indipendenti
 * invece di genitore/figlio. Qui sta SOLO il centrare il marchio grande a schermo,
 * lo stesso `display:flex` che prima stava su `.intro-veil`; il colore di fondo ( nero )
 * resta tutto sul velo, questo strato e' trasparente, sopra di lui ( `z-index` piu'
 * alto ), cosi' il marchio resta visibile anche quando il velo gli scivola sotto.
 */
html[data-intro="pending"] .intro-logo-layer,
html[data-intro="leaving"] .intro-logo-layer {
    display: flex;
    position: fixed;
    inset: 0;
    z-index: 10001;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

/*
 * ⚠️ 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 ).
 * ⚠️ TEMPI RALLENTATI su richiesta esplicita ( erano 900ms/350ms ): la transizione del
 * marchio dura ora 1450ms, l'ultimo pezzo ( l'uscita in dissolvenza ) parte a 1050ms e
 * dura 500ms — finisce a 1550ms, appena dopo che il marchio e' arrivato al suo posto.
 */
.intro-logo {
    display: block;
    width: min( 42vw, 340px );
    aspect-ratio: 1491 / 589;
    /* ⚠️ BIANCO FISSO, stesso motivo del fondo nero qui sopra: `var( --ink-strong )`
       e' nero nel tema chiaro — su un fondo ORA nero sempre, un marchio nero sarebbe
       sparito. Il marchio che scivola in testata resta quello vero ( colorato dal
       CSS della testata, nel SUO tema ): qui, sul velo, e' sempre bianco su nero,
       come il riferimento. */
    background-color: #ffffff;
    -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 1450ms cubic-bezier( .65, 0, .35, 1 ), opacity 500ms ease 1050ms;
}

/*
 * ⚠️ 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 ( `400ms` )
 * 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.
 * ⚠️ Rallentato in proporzione al marchio ( era 700ms, ritardo 250ms ): finisce a 1500ms,
 * giusto prima che il marchio sparisca del tutto in dissolvenza ( 1550ms ).
 */
html[data-intro="leaving"] .intro-veil {
    transform: translateY( -100% );
    pointer-events: none;
    transition: transform 1100ms cubic-bezier( .65, 0, .35, 1 ) 400ms;
}

html[data-intro="leaving"] .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; }

/* ⚠️ RICERCA — stesso disegno del selettore di lingua qui sopra ( <details>, pannello
   assoluto sotto la lente, fuori dal flusso cosi' la testata non cambia altezza aprendolo
   ). La lente e' lo stesso segno CONTORNATO dei social accanto ( `.social-link svg`,
   18px, `stroke: currentColor` ) — non un'icona a parte. */
.site-search { position: relative; margin-left: 16px; align-self: center; }
.site-search summary {
    display: flex; align-items: center;
    color: var( --ink ); cursor: pointer; list-style: none;
    transition: color 0.5s var( --ease ) 0s;
}
.site-search summary::-webkit-details-marker { display: none; }
.site-search summary:hover, .site-search[open] summary { color: var( --accent ); }
.site-search summary svg {
    display: block; width: 18px; height: 18px;
    fill: none; stroke: currentColor; stroke-width: 1.5;
    stroke-linecap: round; stroke-linejoin: round;
}
/* ⚠️ IL PANNELLO E' IL MODULO STESSO — niente `<ul>` di voci come nel selettore di
   lingua, un campo di testo e un bottone che lo invia. `min-width` piu' largo di un
   `<input>` di sistema: un campo di ricerca troppo stretto si legge a fatica mentre si
   scrive. */
.site-search form {
    position: absolute; right: -14px; top: calc( 100% + 10px ); z-index: 30;
    display: flex; align-items: center; gap: 8px;
    width: 240px; padding: 10px 14px;
    background: var( --paper ); box-shadow: 0 6px 24px rgba( 0, 0, 0, 0.14 );
}
.site-search input {
    flex: 1 1 auto; min-width: 0;
    border: 0; border-bottom: 1px solid var( --rule );
    padding: 0 0 4px;
    background: none;
    color: var( --ink );
    font-family: inherit; font-size: 0.9375rem;
}
.site-search input:focus { outline: none; border-bottom-color: var( --ink ); }
.site-search input::placeholder { color: var( --ink-faint ); }
.site-search button {
    flex: 0 0 auto; display: flex;
    border: 0; background: none; padding: 0; margin: 0 0 4px;
    color: var( --ink ); cursor: pointer;
}
.site-search button:hover { color: var( --accent ); }
.site-search button svg {
    display: block; width: 16px; height: 16px;
    fill: none; stroke: currentColor; stroke-width: 1.6;
    stroke-linecap: round; stroke-linejoin: round;
}

.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 ( `.project-filters`, con dentro `.filter-tabs` e
   `.filter-years` ) NON CI SONO PIU': prima le tipologie, poi anche gli anni — via
   dalla pagina, richiesta esplicita, restano solo nel menu a tendina della testata
   ( `header.php`, dentro "Progetti" — gli anni ci sono innestati come categoria a
   parte ). Le regole che li disegnavano erano tutte scoped a quelle classi, e sono
   andate via con loro invece di restare morte nel foglio di stile. */

/* ─── 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. */
/* ⚠️ PIU' RAVVICINATE, richiesta esplicita ( 50px → 28px ): con le miniature ora tutte
   della stessa misura ( vedi `.project-row img` piu' sotto ) un distacco pensato per
   fotografie libere di essere alte quanto volevano era diventato troppo — un vuoto fra
   riquadri gia' regolari, non piu' necessario a separare forme diverse. */
.project-row {
    display: flex; align-items: flex-start; gap: var( --gutter );
    padding: 28px 0;
}
.project-row:first-child { padding-top: 0; }
/* ⚠️ CENTRATA CON LA PAGINA, richiesta esplicita: `.details` a 25% e la fotografia a
   larghezza fissa insieme non riempiono mai tutto il `.container` — coi due bloccati a
   `flex: 0 0 auto` ( niente cresce a riempire il resto ), di default un flex container
   allinea i suoi figli a SINISTRA, lasciando il vuoto avanzato tutto a destra: la coppia
   testo+fotografia stava sbilanciata verso il bordo sinistro della pagina invece che nel
   mezzo. `justify-content: center` sposta la coppia intera al centro, mantenendo intatte
   le due larghezze. */
/* ⚠️ `align-items: flex-start`, corretto dopo una prova vera: `center` ( un commit
   precedente, per "tutto centrato" ) centrava il titolo a META' dell'altezza della
   fotografia — segnalato come titolo e foto "non allineate", perche' l'inizio del
   testo non coincideva piu' con l'inizio della fotografia. Qui "centrato" resta
   `justify-content` ( la coppia intera in mezzo alla pagina ): l'allineamento FRA
   titolo e foto e' un'altra cosa, ed e' quello che torna in cima con `flex-start`. */
.project-row > a { display: flex; align-items: flex-start; justify-content: center; gap: var( --gutter ); width: 100%; }
/* ⚠️ LARGHEZZA FISSA ( 260px ), NON PIU' `width: auto` — corretto dopo una prova vera:
   `auto` faceva abbracciare alla colonna il testo di OGNI riga alla sua misura vera,
   e siccome la coppia intera si centra con `justify-content` ( qui sopra ), una colonna
   piu' stretta o piu' larga riga per riga spostava anche la fotografia di fianco —
   segnalato come fotografie "non allineate" fra loro. Fissa, la colonna resta sempre
   della stessa misura: il testo puo' essere piu' corto o piu' lungo dentro di lei, la
   fotografia accanto parte sempre dallo stesso punto. */
.project-row .details { flex: 0 0 auto; width: 260px; padding-top: 0; }

/* ⚠️ LARGHEZZA FISSA, UGUALE PER OGNI RIGA — richiesta esplicita: prima la decideva la
   forma della fotografia ( `flex: 0 1 auto`, una orizzontale e una verticale affiancate
   risultavano larghe in modo molto diverso ), ora e' un tetto fisso ( `--row-img-width` )
   come l'altezza qui sotto. Il velo qui sotto e' `inset:0` DENTRO la figura, quindi resta
   dietro la fotografia qualunque sia la sua forma dentro il riquadro.
   ⚠️ `aspect-ratio`, NON PIU' un'altezza in `vh` slegata dalla larghezza — con l'altezza
   fissa di prima ( 38vh ) il rapporto cambiava con la finestra; con `aspect-ratio` resta
   identico su ogni schermo, la larghezza fissa qui sotto lo decide da sola.
   ⚠️ `4/3` ( 1,33 ), richiesta esplicita — non piu' il 6:5 ( 1,2 ) scelto per pareggiare
   il ritaglio fra orizzontali ( quasi tutte 16:9, 1,78 ) e verticali ( quasi tutte 3:4,
   0,77 ): il ritaglio resta ( un riquadro di UNA forma sola per fotografie di forme
   diverse ), solo il punto scelto e' un altro. */
/* ⚠️ UN PO' PIU' LARGHE, richiesta esplicita ( 480px → 580px ): restano piu' strette
   di quanto fossero in origine ( 720px ), l'effetto di crescita/rimpicciolimento verso
   la fotografia aperta resta visibile, solo meno estremo di prima. */
:root { --row-img-width: 580px; }
.project-row figure { flex: 0 0 auto; width: var( --row-img-width ); aspect-ratio: 4 / 3; 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;
}
/* ⚠️ ALTEZZA AL 100%: la misura vera ormai la da' `aspect-ratio` sulla `figure` qui
   sopra, non piu' un `vh` scritto qui — l'immagine riempie il riquadro che la figure
   le ha gia' preparato.
   ⚠️ `cover`, non `contain` — corretto dopo una prova vera: `contain` ( mai ritagliare )
   lasciava, per ogni fotografia la cui forma non fosse ESATTAMENTE quella del riquadro,
   una striscia vuota — sopra/sotto per un'orizzontale piu' larga, ai lati per una
   verticale — che si vedeva come un rettangolo grigio a se' stante ( il velo al 2% di
   `figure::before`, senza piu' una fotografia sopra a coprirlo ), ed erano proprio quelle
   strisce, di misura diversa riga per riga, a far sembrare le miniature NON allineate
   anche se il riquadro era gia' della stessa larghezza per tutte. `cover` riempie sempre
   il riquadro intero — nessuno spazio vuoto, il bordo della fotografia coincide sempre
   col bordo del riquadro — al prezzo di ritagliare il bordo che avanza: accettabile qui,
   sono ANTEPRIME piccole, non la fotografia intera ( quella si vede aprendo la riga ). */
/* ⚠️ NIENTE PIU' `filter: grayscale`, richiesta esplicita: le copertine restano a
   colori sempre, non solo al passaggio del mouse — tolto anche l'hover qui sotto che
   le riportava a colori, non serve piu' niente da "riportare". */
.project-row img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    max-width: none;
    max-height: none;
}

/* ─── 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 CONTRAZIONE PRIMA DI CHIUDERE, richiesta esplicita — vedi il commento su
   `SQUEEZE_MS` in js/project-expand.js: un primo passo breve ( 0.2s, una transizione
   SUA, non quella lenta di `.is-visible` qui sopra ) che stringe appena il contenuto
   restando ancora del tutto visibile ( niente `opacity`, solo `transform` ), prima che
   la chiusura vera cominci. Dopo `.is-visible` nel foglio, cosi' vince quando ci sono
   entrambe le classi ( stessa specificita', l'ordine decide ) — durante la contrazione
   il pannello e' ancora "aperto e visibile" agli occhi di tutte le altre regole, solo
   un poco piu' stretto. */
.project-expand-content.is-squeezing { transform: scale( 0.96 ); transition: transform 0.2s var( --ease ); }

/* ⚠️ 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 ) {
    /* ⚠️ SUL RIQUADRO CHE AVVOLGE ( `.project-strip-wrap` ), non piu' sulla striscia
       stessa: da quando la striscia ha attorno quel riquadro ( serve alla freccia di
       scorrimento, vedi `.strip-scroll-hint` piu' sotto ), e' lui a dover sbordare a
       tutta larghezza — se restasse stretto quanto il `.container` dell'elenco, la
       freccia ( ancorata al SUO bordo destro, non a quello vero dello schermo )
       finirebbe spostata verso il centro invece che sul bordo. La striscia dentro
       eredita la larghezza piena del suo genitore senza bisogno di ripetere il trucco. */
    .project-expand-panel .project-strip-wrap { 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, in ELENCO e sulla scheda aperta — richiesta
   esplicita, estesa poi anche a `.project-row`: prima l'elenco teneva le due parole sulla
   stessa riga ( scelta di allora, "il titolo sta su una riga sola" ), ora il concetto
   evidenziato resta da solo sulla prima riga e il nome scende sempre sotto, qui come sulla
   scheda aperta. `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. */
:is( .project-row .details, .details-title ) .title .name,
:is( .project-row .details, .details-title ) .title .concept:not( :empty ) + .name { display: block; font-size: 0.7em; }
/* ⚠️ PIU' INTERLINEA fra le due righe, richiesta esplicita: `display: block` da solo le
   impila subito una sotto l'altra, senza respiro fra il riquadro del concetto e il nome.
   `margin-top` sul `.name`, non `line-height` sul concetto: e' lo spazio FRA le due
   righe che serve staccare, non l'altezza di una riga sola. */
:is( .project-row .details, .details-title ) .title .concept:not( :empty ) + .name { margin-top: 0.4em; }

/* ⚠️ « 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; }
/* ⚠️ 65px → 40px, richiesta esplicita ( "piu' compattate in verticale" ): meno distacco
   fra il titolo della scheda e il primo dato sotto. */
.content-info  { margin-top: 40px; }

/* ⚠️ 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.
   ⚠️ `line-height: 1.1rem`, non piu' 1.5rem — richiesta esplicita, interlinea ridotta:
   un'etichetta corta ( "data", "cliente" ) su una riga sola non ha bisogno del
   respiro di un paragrafo vero. */
.content-info h4 {
    font-family: var( --font-book );
    font-size: 0.75rem;
    line-height: 1.1rem;
    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;
}
/* ⚠️ `line-height: 1.2rem` ( era 1.5rem ) e `margin-bottom: 2px` ( era 5px ), stesso
   motivo: interlinea e distacco ridotti, richiesta esplicita. */
.content-info p { font-size: 0.875rem; line-height: 1.2rem; margin: 0 0 2px; }
/* ⚠️ 12px → 8px, richiesta esplicita ( ancora piu' compatte ): "data", "cliente",
   "luogo" restano righe della stessa scheda dati, ravvicinate ulteriormente. */
.content-info .info-group { margin-bottom: 8px; }
.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. */
/* ⚠️ `line-height: 1.2rem`, non piu' 1.5rem — richiesta esplicita, interlinea ridotta. */
.content-info .project-details { font-size: 0.875rem; line-height: 1.2rem; }
/* ⚠️ 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 ) ) );
}

/*
 * ⛔ NIENTE PIU' `scroll-snap`, tolto dopo una segnalazione vera, ripetuta su piu' galleria:
 * "si ferma prima che io possa leggere tutto il testo o l'intera immagine... lo fa in
 * tutte le gallerie". Lo snap era stato messo apposta perche' senza lasciava un riquadro
 * a META' fuori dal bordo — ma `proximity`, quando la rotella manda un colpo che finisce
 * GIA' vicino a un bordo ( capita spesso, non e' un caso raro ), aggancia e FERMA li' lo
 * scorrimento: la persona voleva continuare a leggere o a scorrere oltre, e si ritrovava
 * bloccata a un bordo che lo snap aveva scelto per lei. Il rimedio era peggiore del
 * difetto che correggeva: un riquadro a meta' fuori bordo si legge scorrendo un altro
 * poco, uno scorrimento che si blocca da solo non si sblocca scorrendo di piu' — la
 * stessa identica causa, misurata in sessione, dietro al difetto gia' corretto
 * sull'ultima fotografia della striscia ( l'aggancio *impediva* di arrivare al fondo
 * corsa ). Tolto tutto: `scroll-snap-type`, `scroll-padding-left` ( serviva solo allo
 * snap ) e gli `scroll-snap-align` sui riquadri piu' sotto. Resta `scroll-behavior:
 * smooth`: quello ammorbidisce il movimento, non lo blocca.
 */
.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-behavior: smooth;

    /* ⚠️ 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 */

/* ⚠️ IL RIQUADRO CHE AVVOLGE: serve solo perche' la freccia di scorrimento qui sotto
   ( `position: absolute` ) deve restare ANCORATA a un angolo fermo mentre le fotografie
   scorrono sotto di lei — se l'ancestro posizionato fosse `.project-strip` stessa
   ( che scorre ), la freccia scorrerebbe via insieme al contenuto invece di restarci
   sopra. Nessun'altra proprieta': non deve toccare ne' l'altezza ne' la larghezza gia'
   decise dalla striscia dentro. */
.project-strip-wrap { position: relative; }

/* ⚠️ LA FRECCIA CHE RICORDA LO SCORRIMENTO ORIZZONTALE — la striscia scorre di lato, un
   gesto che su desktop ( trackpad o rotella verticale ) non e' scontato finche' non lo
   si prova. Sparisce appena si inizia a sfogliare ( il primo scorrimento vero ), o
   subito se le fotografie ci stanno gia' tutte senza bisogno di scorrere —
   js/strip-scroll-hint.js decide quando, richiesta esplicita.
   ⚠️ NIENTE PALLINO, richiesta esplicita: solo il segno, centrato in verticale
   sull'angolo destro della fotografia — grande ed evidente, non un piccolo pulsante
   in un angolo. */
.strip-scroll-hint {
    position: absolute;
    /* ⚠️ PIU' A SINISTRA ANCORA, richiesta esplicita ( 20px → 100px dal gutter ): non
       piu' vicina al bordo destro, ben dentro la fotografia, in una posizione che si
       vede subito invece di doverla cercare vicino al bordo. */
    right: calc( var( --gutter ) + 100px );
    top: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;   /* e' un suggerimento, non un pulsante: lo scorrimento resta quello vero, sotto */
    opacity: 0.9;
    z-index: 2;
    transition: opacity 0.5s var( --ease ) 0s;
    animation: strip-scroll-hint-nudge 1.6s ease-in-out infinite;
}
/* ⚠️ `--ink-strong`: nero nel tema chiaro, bianco in quello scuro, come il marchio in
   testata.
   ⚠️ NIENTE PIU' CONTORNO, richiesta esplicita ( "se la freccia e' nera nello sfondo
   chiaro e viceversa sara' sempre leggibile" ): il segno nudo, senza alcun alone ne'
   bordo intorno. ⛔ GIA' PROVATO E TOLTO UNA VOLTA per lo stesso motivo opposto — su
   una fotografia dai toni vicini al colore della freccia ( non al TEMA del sito, che e'
   un'altra cosa: una foto scura resta scura anche in tema chiaro ) il segno puo'
   sparire a occhio nudo, verificato allora colorandolo di rosso per prova. Rimesso nudo
   ora su scelta esplicita, consapevole di questo. */
.strip-scroll-hint .chevron {
    transform: rotate( 180deg );
    --chevron-size: 40px;
    --chevron-weight: 4;
    stroke: var( --ink-strong );
}

/* sparita ( al primo scorrimento, o perche' non serviva ): niente piu' transizione di
   ritorno, resta cosi' per il resto della visita a quella striscia */
.strip-scroll-hint.is-hidden { opacity: 0; }

/* un piccolo scatto verso le fotografie, non un rimbalzo vistoso: solo quanto basta a
   farla notare con la coda dell'occhio. `translateY( -50% )` ripetuto in ogni fotogramma:
   e' quello che la centra in verticale ( vedi `top: 50%` qui sopra ), e l'animazione,
   scrivendo `transform` per conto suo, lo dovrebbe altrimenti cancellare. */
@keyframes strip-scroll-hint-nudge {
    0%, 100% { transform: translateY( -50% ) translateX( 0 ); }
    50%      { transform: translateY( -50% ) translateX( 8px ); }
}

/* ⛔ SOLO SOPRA I 767px: sotto la striscia e' verticale ( fotografie impilate, la pagina
   scorre gia' cosi' com'e' naturale ) — niente da segnalare la'. */
@media ( max-width: 767px ) {
    .strip-scroll-hint { display: none; }
}

.project-strip .strip-box {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    height: 100%;
}
/*
 * ⚠️ 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; }

/*
 * ⚠️ L'UNICA AREA DOVE SI SCRIVE `itemDescription`, visibile solo nell'editor — vedi il
 * commento in project_page.php su perche' i riquadri distribuiti nella striscia non sono
 * piu' editabili. `display: none` di base e' la stessa difesa gia' usata per
 * `figcaption.alt-text` in `inline-edit.css`: il PHP la disegna gia' solo quando
 * `IS_EDITING`, questo e' solo un secondo cancello nel caso il parziale finisse incollato
 * altrove senza quella condizione.
 * ⚠️ UN PAVIMENTO DI ALTEZZA ( `min-height` ), non zero: un riquadro vuoto non avrebbe
 * area su cui cliccare per iniziare a scrivere — lo stesso motivo del `:empty::before`
 * sull'alt delle fotografie.
 */
.description-editor { display: none; }
.editing .description-editor {
    display: block;
    margin-top: 24px;
    min-height: 120px;
    font-size: 0.875rem;
    line-height: 1.4rem;
}
.editing .description-editor:empty::before {
    content: 'descrizione\2026';
    opacity: 0.45;
}

/* ⚠️ 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;
    }
    .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`/`.social-links` NON CI SONO PIU': la navigazione e i
   segni social nel piede sono andati via ( footer.php, richiesta esplicita — doppioni
   di quello che sta gia' in testata ). Le regole che li disegnavano erano scoped a
   quelle classi, andate via con loro. */

.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. */
    /* ⚠️ `justify-content: flex-start`, non piu' il `center` di sopra: quello centrava la
       coppia testo+fotografia DENTRO LA RIGA quando erano affiancate — impilate in colonna
       ( qui sotto ) centrarle vorrebbe dire staccarle dal bordo sinistro senza motivo. */
    .project-row, .project-row > a { flex-direction: column; align-items: flex-start; justify-content: flex-start; gap: 20px; }
    /* ⚠️ `max-width: none`: annulla il freno messo sopra per tenere il titolo vicino alla
       fotografia — impilato, il testo va a piena larghezza come il resto della riga. */
    .project-row .details { width: 100%; max-width: none; }
    /* ⚠️ `aspect-ratio: auto` — annulla il riquadro di sopra: impilate, le righe non hanno
       piu' un ritmo da allineare fra loro, e l'altezza torna quella vera della fotografia. */
    .project-row figure { width: 100%; aspect-ratio: auto; justify-content: flex-start; }
    /* ⚠️ QUI LA LARGHEZZA FISSA NON SERVE: le righe sono impilate, non affiancate — una
       sola alla volta sotto l'occhio, niente ritmo da allineare fra loro. Torna l'altezza
       LIBERA ( non piu' un riquadro con le due misure ferme di sopra ) e `object-fit`
       smette di servire visto che non c'e' piu' un riquadro da riempire. */
    .project-row img { width: 100%; height: auto; max-height: none; object-fit: initial; }

    .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; }
    .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: sticky; top: 0; 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: var( --content-inset )`, NON PIU' il solo `--gutter` — corretto dopo una
 * segnalazione ( "deve essere allineato con il marchio" ): `--gutter` e' dove comincia
 * `.header-side`, non dove comincia il MARCHIO dentro di lei — `.header-side` ha un suo
 * `padding-left` ( un altro gutter ) prima del logo, e su schermi larghi il `.container`
 * si centra aggiungendo ANCORA dello spazio prima di li'. Misurato: su un container da
 * 1260px il marchio partiva a 45,2px, il pannello ( col solo `--gutter` ) a 20px —
 * 25px di scarto. `--content-inset` ( gia' usato per la striscia della scheda progetto,
 * stessa aritmetica: meta' dello spazio di centratura piu' un gutter ) e' esattamente
 * la distanza a cui il marchio arriva, in ogni larghezza di schermo.
 * ⚠️ `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.
 */
/*
 * ⛔ ORIZZONTALE, NON PIU' UNA COLONNA — cambio di metodo, richiesta esplicita: ogni
 * aggiustamento di interlinea/margini/carattere ( i commit precedenti ) restringeva il
 * pannello di qualche pixel alla volta, ma con undici voci impilate una sotto l'altra
 * bastava un titolo di progetto un poco piu' alto ( due righe invece di una, come nello
 * screenshot segnalato ) per farla tornare a toccarlo — un rincorrersi senza fine.
 * Disposte in RIGA invece che in colonna ( `.has-menu-panel .main-nav ul` qui sotto,
 * `flex-direction: row` con `flex-wrap: wrap` ), undici voci corte occupano 2-3 righe
 * invece di undici: il pannello resta basso per costruzione, non perche' misurato a
 * pixel contro un titolo che puo' sempre tornare a crescere.
 */
.has-menu-panel .site-header .main-nav {
    position: absolute;
    top: 100%;
    left: var( --content-inset );
    /* ⚠️ `width: auto` con un tetto, non piu' 275px fissi: una colonna stretta andava
       bene voce sotto voce, ma una riga che va a capo ha bisogno di tutta la larghezza
       disponibile per starci in meno righe possibili. */
    width: auto;
    max-width: calc( 100vw - var( --content-inset ) - var( --gutter ) );
    max-height: calc( 100vh - 100% - var( --gutter ) );
    overflow-y: auto;
    /* ⚠️ `padding-left: 30px`, NON PIU' 0 — richiesta esplicita ( "lascia un po' di
       margine bianco a sinistra tra la colonna e il rettangolo che la contiene" ),
       che supera quella di un passo precedente ( testo a filo col marchio, niente
       rientro ): ora che il riquadro ha un fondo vero ( qui sotto ) e si vede davvero
       come un riquadro, il testo a contatto col suo bordo sinistro sembrava stretto —
       lo stesso margine del bordo destro, simmetrico. */
    padding: 16px 30px;
    /* ⚠️ UN FONDO VERO, non piu' "niente fondo" — corretto dopo una segnalazione vera:
       "quando apro il menu le categorie finiscono sopra le immagini e non si leggono".
       "Niente fondo" ( tolto in un passo precedente, voci lette direttamente sopra la
       pagina sottostante ) andava bene finche' il pannello si apriva quasi sempre su
       una pagina chiara — ora che la testata resta raggiungibile OVUNQUE si sia
       scorsi ( vedi `position: sticky` piu' sopra ), il pannello puo' aprirsi sopra
       una fotografia qualunque: un testo scuro senza un fondo proprio vi si legge
       male o per niente. `--paper` ( lo stesso usato dal pannello "Progetti" quando
       sta fuori da qui, vedi `.mega-menu-panel` ) e un'ombra leggera lo rendono di
       nuovo un riquadro vero, leggibile sopra qualunque cosa ci sia sotto. */
    background: var( --paper );
    box-shadow: 0 10px 30px rgba( 0, 0, 0, 0.12 );
    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;
}

/* ⚠️ COLONNA, non piu' riga — richiesta esplicita: "vorrei che il menu si aprisse in
   verticale con le categorie in colonna". `> ul`, FIGLIO DIRETTO e non piu' un
   discendente qualunque: scritto come discendente, questa regola ( due classi,
   piu' specifica della base di `.mega-menu-panel ul` qui sopra in questo foglio, UN
   solo classe ) vinceva ANCHE sull'`<ul>` delle categorie innestato dentro "Progetti"
   — le tipologie finivano in riga pure loro, "colonna" della base non contava mai
   niente. Fermandosi al figlio diretto, questa regola tocca SOLO la lista di primo
   livello ( Home/Progetti/Studio/News ); le categorie restano quelle della base,
   gia' in colonna com'era sempre stata pensata. */
.has-menu-panel .main-nav > ul {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
}
.has-menu-panel .main-nav li { margin: 0; font-size: 15px; }
/* ⚠️ `--ink`, NON PIU' `--paper`: da quando il pannello e' sul fondo della PAGINA
   ( `--paper` sopra ) e non piu' su un suo fondo grigio scuro, il testo bianco fisso
   di prima sarebbe sparito — bianco su bianco. `--ink` e' lo stesso colore che il
   menu usa gia' quando sta impilato in testata su schermo largo ( `.main-nav a`,
   piu' sopra in questo foglio ), non un colore inventato apposta per qui. */
.has-menu-panel .main-nav a,
.has-menu-panel .main-nav span,
.has-menu-panel .main-nav summary { color: var( --ink ); }
/* ⚠️ La voce attiva e quella sotto il dito restano il solito riquadro d'accento — quello
   NON dipende dal fondo del pannello, e' un suo colore proprio, `--paper` sopra
   `--accent` funziona identico su qualunque sfondo stia intorno. Il padding sta su
   TUTTE le voci, cosi' la voce evidenziata non si sposta rispetto alle altre. */
.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: 10px 0 0;
}
/* ⚠️ `--ink`, stesso motivo del blocco qui sopra: niente piu' `--paper` fisso, il
   sottomenu sta anche lui sul fondo della pagina adesso. */
.has-menu-panel .mega-menu-panel a { color: var( --ink ); font-size: 14px; }
/* ⚠️ SOLO `font-weight`, NIENTE PIU' `color` qui — corretto dopo una prova vera: la
   voce attiva della tassonomia e' ANCHE una voce `.active` dentro `.main-nav`, quindi
   le prende gia' tutte e due l'evidenziatore generale ( `.main-nav .active > a`, piu'
   sotto: riquadro `--accent`, testo `--paper` ) — un `color` scritto QUI, piu'
   specifico di quella regola ( due selettori di tipo contro uno ), vinceva SOLO sul
   colore e lasciava lo sfondo nero di quella regola: risultato, testo nero su
   riquadro nero, invisibile. Senza `color` qui, il testo resta quello ( bianco )
   dell'evidenziatore, leggibile sul suo sfondo scuro. */
.has-menu-panel .mega-menu-panel li.active a { font-weight: 700; }
.has-menu-panel .mega-menu .chevron { stroke: var( --ink ); }
/* ⚠️ GLI ANNI SONO UN SECONDO `<details class="mega-menu">`, INNESTATO dentro il
   pannello di "Progetti" — richiesta esplicita ( "non voglio vedere tutti gli anni,
   vanno dentro una categoria anni, visibili solo se clicco" ). Riusa di proposito lo
   STESSO disegno di "Progetti" ( stessa classe, stesso pannello ), quindi eredita gia'
   tutto: colori, `summary`/`chevron`, il pannello senza fondo. Serve solo LA STESSA
   regola di "tutta la riga quando aperto" che ha "Progetti" — qui pero' scritta contro
   `.mega-menu-panel`, non `.main-nav`, perche' l'antenato giusto e' un'altra `<li>`,
   quella dentro il pannello delle tipologie, non quella in cima al menu. */
.has-menu-panel .mega-menu-panel li:has( > details.mega-menu[ open ] ) { flex-basis: 100%; }

/* ⚠️ `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.
   ⚠️ SULL'`<html>`, non piu' sul `<body>` — corretto dopo una segnalazione vera
   ( "apro la home e non arrivo fino in alto, ne' in verticale ne' in orizzontale" ):
   `.has-menu-panel` E' gia' l'`<html>` ( lo scrive `menu.js` li' sopra ), quindi
   scriverci `overflow-x` sopra lo mette DIRETTAMENTE sull'elemento che il browser usa
   gia' come riquadro di scorrimento della pagina. Scritto invece sul `<body>`, come
   prima, l'accoppiamento automatico di CSS forza anche `overflow-y` a `auto` su di
   lui ( la regola: se un asse resta `visible` e l'altro no, quello `visible` diventa
   `auto` ) — e un `<body>` che diventa COSI' un secondo riquadro scorrevole, annidato
   dentro quello vero dell'`<html>`, e' una causa nota di scorrimento che si blocca a
   meta' su Safari iOS ( doppio contenitore, fisica dell'inerzia confusa fra i due ).
   Un riquadro solo, quello giusto, non ne crea un secondo per sbaglio. */
.has-menu-panel { overflow-x: hidden; }
/* ⚠️ SULL'`<html>`, non piu' sul `<body>` — corretto dopo una segnalazione vera: "se
   ci clicco sparisce e non si apre il menu". E' l'`<html>` il vero riquadro di
   scorrimento della pagina ( `overflow-x: hidden` qui sopra, vedi il commento ) — un
   `overflow: hidden` scritto invece sul `<body>` lo rendeva, per la testata
   `position: sticky` qui sotto in questo foglio, il suo "contenitore di scorrimento"
   piu' vicino: ma il `<body>` non si era mai scorso lui stesso, quindi la testata
   restava "incollata" alla posizione che avrebbe avuto SENZA scorrimento — con la
   pagina gia' scorsa in basso, quel punto finiva fuori dallo schermo, il marchio
   spariva insieme al solo modo di raggiungere il menu. Scritto sul contenitore
   GIUSTO, lo blocca comunque ( `js/menu.js` aggiunge `nav-active` anche li' ) senza
   confondere la testata su dove sia rimasta. */
.has-menu-panel.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; }
}

/* ⚠️ UN TETTO RESTA, come RETE DI SICUREZZA — non piu' come prima linea di difesa
   contro la sovrapposizione ( quella e' `--menu-open-height` qui sotto, che spinge giu'
   la pagina della sua vera misura, non un numero indovinato ). Serve solo a impedire
   che il pannello stesso ecceda l'altezza di uno schermo bassissimo ( un telefono in
   orizzontale ): oltre quel tetto scorre dentro se stesso, invece di uscire dalla
   finestra. 120px → 60vh: quel numero era tarato per non toccare un titolo che ora si
   sposta lui da solo, e su schermi normali tagliava il pannello via troppo presto. */
@media ( max-width: 767px ) {
    .has-menu-panel .site-header .main-nav { max-height: 60vh; }
}

/* ⚠️ LA PAGINA SOTTO SI SPOSTA GIU', della vera altezza del pannello — richiesta
   esplicita, dopo che un tetto fisso ( il commento qui sopra, versioni precedenti )
   si era gia' dimostrato un rincorrersi senza fine: 240px, poi 120px, e restava sempre
   un caso ( una scheda con la testata piu' bassa del previsto, un titolo piu' lungo )
   dove il pannello tornava a toccare il titolo. `--menu-open-height` la scrive
   `js/menu.js` MISURANDO il pannello ( `scrollHeight`, la sua altezza vera, non quella
   tagliata dal tetto qui sopra ) ogni volta che si apre o che "Progetti" dentro di lui
   si apre o chiude — non un numero scritto una volta per tutte, uno ricalcolato per
   ogni pagina e ogni stato del pannello.
   ⚠️ `.site-header + *`: il primo elemento DOPO la testata, qualunque pagina sia — la
   scheda di un progetto, l'elenco, qualunque altra. Non serve saperne il nome.
   ⚠️ OGNI SCHERMO, non piu' solo sotto i 767px — richiesta esplicita: prima, sopra
   quella misura, il pannello restava sovrapposto alla pagina ( verificato che non la
   toccasse mai, ma restava DAVANTI a lei, non sopra uno spazio suo ); ora scende come
   una tendina che fa posto a se stessa dovunque si apra, desktop compreso. */
.has-menu-panel .site-header + * {
    margin-top: var( --menu-open-height, 0px );
    transition: margin-top 0.35s var( --ease ) 0s;
}


/* ─── 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: sticky; top: 0; 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; }
