/* ==========================================================================
   Pianarosa — foglio di stile unico.

   Direzione: poster. L'impatto lo fa la tipografia, non gli effetti: titoli in
   grottesco condensato enormi, sovrapposti alle fotografie, che occupano tutta
   la larghezza dello schermo. Sotto quel livello il sito torna sobrio —
   etichette in maiuscoletto spaziato, filetti sottili, un solo accento ambra.

   Regola non negoziabile: la tipografia da manifesto vale solo per i titoli.
   I testi di lettura restano in Source Serif su colonna stretta, perché un
   titolo spettacolare non deve costare nulla in leggibilità.
   ========================================================================== */

/* Source Serif 4 variabile, ospitata sul sito: nessuna richiesta a server
   esterni, quindi nessuna dipendenza da terzi e nessun dato dei visitatori
   che esce.
   Una serif da lettura, non un grottesco da interfaccia: è la scelta che
   distingue il testo dell'articolo dai titoli e dalle etichette, e che fa
   leggere la pagina come una rivista invece che come un pannello.
   font-display: swap fa comparire subito il testo con il carattere di sistema
   anziché lasciare uno spazio bianco durante il caricamento.

   Del carattere esiste anche una versione con asse ottico, che adatta il
   contrasto alla dimensione: qui non serve, perché la serif compare in una
   sola fascia di corpo, e costerebbe settanta kilobyte in più sul file che
   viene precaricato. Questi file hanno il solo asse di peso. */
@font-face {
    font-family: 'Source Serif 4';
    font-style: normal;
    font-weight: 200 900;
    font-display: swap;
    src: url('fonts/serif-latin-var.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                   U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
                   U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Source Serif 4';
    font-style: normal;
    font-weight: 200 900;
    font-display: swap;
    src: url('fonts/serif-latin-ext-var.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                   U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                   U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Il corsivo vero, non l'obliquo sintetico. Negli articoli il corsivo c'è
   davvero — il testo arriva in Markdown e gli autori lo usano — e in una serif
   è un disegno diverso, non lo stesso alfabeto inclinato dal browser: la «a»
   cambia forma, le grazie si ammorbidiscono. È metà della resa.
   Il browser scarica questi due file solo quando in pagina c'è del corsivo. */
@font-face {
    font-family: 'Source Serif 4';
    font-style: italic;
    font-weight: 200 900;
    font-display: swap;
    src: url('fonts/serif-italic-latin-var.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                   U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
                   U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Source Serif 4';
    font-style: italic;
    font-weight: 200 900;
    font-display: swap;
    src: url('fonts/serif-italic-latin-ext-var.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                   U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                   U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Archivo variabile: ha un asse di larghezza (wdth 62–125) oltre a quello di
   peso. È questo che permette i titoli condensati e pesantissimi da manifesto
   senza caricare un secondo file per ogni variante.
   font-display: block, non swap: un titolo gigante che cambia forma a metà
   caricamento è molto più fastidioso di un breve ritardo. */
@font-face {
    font-family: 'Archivo';
    font-style: normal;
    font-weight: 100 900;
    font-stretch: 62% 125%;
    font-display: block;
    src: url('fonts/archivo-latin-var.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                   U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
                   U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Archivo';
    font-style: normal;
    font-weight: 100 900;
    font-stretch: 62% 125%;
    font-display: block;
    src: url('fonts/archivo-latin-ext-var.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                   U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                   U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Monospaziato per tutto ciò che è dato: date, conteggi, dati di scatto,
   etichette. È questo, più di ogni decorazione, a dare al sito il carattere
   tecnico — e ha anche una ragione pratica, perché le cifre restano allineate. */
@font-face {
    font-family: 'PianarosaMono';
    font-style: normal;
    font-weight: 100 800;
    font-display: swap;
    src: url('fonts/mono-latin-var.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                   U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
                   U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'PianarosaMono';
    font-style: normal;
    font-weight: 100 800;
    font-display: swap;
    src: url('fonts/mono-latin-ext-var.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                   U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                   U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
    /* Nero mai pieno: un fondo appena desaturato affatica meno la vista e fa
       respirare i neri delle fotografie invece di schiacciarli. */
    --bg: #0a0a0b;
    --bg-raised: #121215;
    --bg-sunken: #070708;

    --text: #ece9e3;
    --text-dim: #93908a;
    --text-faint: #6b6963;

    /* Un solo accento, ambra smorzata: segnala la lingua attiva, la sezione
       corrente e i collegamenti nel testo. Usarlo altrove lo svaluterebbe. */
    --accent: #c9a227;
    --accent-dim: #8a7a55;

    --rule: #212125;
    --rule-strong: #33333a;

    --wrap: 1240px;
    /* Due rem in più di quando il testo era in grottesco: la serif si legge a un
       corpo leggermente maggiore, e sulla vecchia misura la riga si era accorciata
       da 68 a 64 caratteri. Questa larghezza riporta la riga ai 68 di progetto. */
    --wrap-reading: 48rem;

    /* Scala di spaziatura: tutti i distacchi verticali escono da qui, ed è
       questa regolarità a far leggere la pagina come composta e non assemblata. */
    --s1: 0.5rem;
    --s2: 1rem;
    --s3: 1.75rem;
    --s4: 3rem;
    --s5: 5rem;
    --s6: 8rem;

    /* Le riserve sono serif anch'esse: se il file non arriva, la pagina resta
       una pagina composta in serif e non cambia registro a metà. */
    --font: 'Source Serif 4', Charter, 'Iowan Old Style', 'Palatino Linotype', Georgia, serif;
    --font-display: 'Archivo', 'Arial Narrow', Impact, sans-serif;
    --font-mono: 'PianarosaMono', ui-monospace, SFMono-Regular, Consolas, monospace;

    /* Passo del reticolo tecnico di sfondo. */
    --grid-step: 52px;
    --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

/* --------------------------------------------------------- Titoli poster -- */

/* La classe che porta tutto il carattere del sito: condensata al massimo,
   pesantissima, crenatura molto stretta e interlinea sotto l'unità, così le
   righe si incastrano l'una nell'altra come su un manifesto stampato. */
.poster {
    font-family: var(--font-display);
    font-variation-settings: 'wdth' 68, 'wght' 800;
    font-weight: 800;
    font-stretch: 68%;
    text-transform: uppercase;
    letter-spacing: -0.035em;
    line-height: 0.82;
    margin: 0;
    /* I titoli arrivano dal pannello: una parola sola molto lunga, a queste
       dimensioni, sfonderebbe la pagina in larghezza su uno schermo stretto.
       Spezzarla è brutto, ma lo è molto meno di una barra di scorrimento
       orizzontale. Non ha effetto sui titoli che ci stanno. */
    overflow-wrap: break-word;
    /* Le maiuscole condensate hanno una spalla sinistra che le fa sembrare
       rientrate rispetto al resto: il margine negativo le riallinea otticamente. */
    margin-left: -0.02em;
}

/* Una parola non si spezza mai a metà. Le lettere sono elementi separati per
   l'animazione d'ingresso, e senza questo vincolo il browser andrebbe a capo
   fra una lettera e l'altra: «Pianarosa» diventerebbe «Pianar / osa». */
.poster .word {
    white-space: nowrap;
}

.poster .word-space {
    display: inline-block;
    width: 0.24em;
}

/* Titolo impilato: una parola per riga. Sul nome dell'autore è la resa giusta —
   nome sopra, cognome sotto — e toglie di mezzo qualunque a capo automatico. */
.poster-stack .word {
    display: block;
}

.poster-stack .word-space {
    display: none;
}

/* Il titolo cresce con la finestra invece di stare in una misura fissa:
   è quello che gli fa occupare davvero tutta la larghezza dello schermo.
   La misura tiene conto che il nome sta su due righe: più grande di così,
   nome e cognome non entrerebbero insieme sopra la fotografia. */
.poster-xl { font-size: clamp(2.6rem, 10.5vw, 9rem); }
.poster-lg { font-size: clamp(2.8rem, 11vw, 8.5rem); }
.poster-md { font-size: clamp(2.1rem, 6.4vw, 4.4rem); }
.poster-sm {
    font-size: clamp(1.5rem, 3.2vw, 2.3rem);
    font-variation-settings: 'wdth' 78, 'wght' 700;
    font-stretch: 78%;
    line-height: 0.95;
    letter-spacing: -0.02em;
}

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

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    /* Il colore di fondo sta su html e non su body: se lo mettessimo su body,
       verrebbe promosso a sfondo della pagina e coprirebbe lo strato .backdrop,
       che è posizionato dietro al contenuto. */
    background: var(--bg);
}

body {
    margin: 0;
    background: transparent;
    color: var(--text);
    font-family: var(--font);
    /* Un pixel in più rispetto al grottesco di prima: Source Serif ha l'occhio
       medio più piccolo, quindi a parità di corpo dichiarato le minuscole
       risultano più basse e il testo sembra rimpicciolito. Diciotto pixel
       riportano la lettera all'altezza apparente di prima. */
    font-size: 18px;
    /* E interlinea appena più stretta, non più larga: le grazie guidano
       l'occhio lungo la riga, quindi serve meno aria fra una riga e l'altra
       per non perdere il segno. */
    line-height: 1.7;
    /* Peso pieno e non 380: su fondo scuro i tratti sottili di una serif si
       assottigliano ancora, e sotto il peso normale le grazie cominciano a
       sparire. */
    font-weight: 400;
    /* Qui prima c'era l'antialiasing assottigliato (-webkit-font-smoothing:
       antialiased e il suo equivalente per Firefox). Su un grottesco chiaro
       su fondo scuro ripulisce il tratto; su una serif toglie peso proprio
       alle grazie e ai tratti sottili, che sono già la parte più fragile del
       disegno. Meglio la resa predefinita del sistema. */
}

img { max-width: 100%; height: auto; display: block; }

/* ------------------------------------------------------- Sfondo del sito -- */

/* Fotografia in trasparenza e reticolo tecnico, dietro a tutto.
   Sono in posizione fissa e non con background-attachment: fixed, che iOS
   ignora del tutto e che sugli altri browser costa un ridisegno a ogni
   scorrimento. Uno strato fisso separato non ha nessuno dei due problemi. */
.backdrop {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: var(--bg);
}

.backdrop-photo {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    /* L'opacità arriva dal pannello, non da qui: è impostata nello stile in
       linea perché è un dato di contenuto, non una scelta di stile. */
}

.backdrop-grid {
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(rgba(236, 233, 227, 0.045) 1px, transparent 1px),
        linear-gradient(90deg, rgba(236, 233, 227, 0.045) 1px, transparent 1px);
    background-size: var(--grid-step) var(--grid-step);
    /* Il reticolo svanisce verso il basso: a piena intensità su tutta l'altezza
       diventa rumore dietro ai testi lunghi. */
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.35) 60%, rgba(0, 0, 0, 0.12) 100%);
    mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.35) 60%, rgba(0, 0, 0, 0.12) 100%);
}

a { color: inherit; text-decoration: none; }

/* Questi sono i titoli interni agli articoli, non quelli da manifesto: ereditano
   la serif del testo. Il peso sale da 400 a 500 perché il grottesco di prima, a
   parità di numero, rendeva un titolo più deciso di quanto renda una serif. */
h1, h2, h3 {
    font-weight: 500;
    line-height: 1.15;
    /* I titoli grandi hanno bisogno di crenatura più stretta: alle dimensioni
       da display la spaziatura pensata per il testo corrente sembra slegata. */
    letter-spacing: -0.02em;
    margin: 0 0 var(--s2);
}

h1 { font-size: clamp(2rem, 4.2vw, 3.1rem); }
h2 { font-size: clamp(1.4rem, 2.4vw, 1.85rem); }
h3 { font-size: 1.15rem; }

p { margin: 0 0 1.3em; }

.wrap {
    max-width: var(--wrap);
    margin: 0 auto;
    padding: 0 var(--s3);
}

/* --------------------------------------------------------- Elementi base -- */

/* L'etichetta è la cifra ricorrente del sito: compare sopra ogni sezione, nelle
   date, nei conteggi e nei dati di scatto. In monospaziato, perché è sempre un
   dato — e perché le cifre restano incolonnate fra una riga e l'altra. */
.label {
    font-family: var(--font-mono);
    font-size: 0.64rem;
    font-weight: 450;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-faint);
}

.label-accent { color: var(--accent); }

.rule {
    height: 1px;
    background: var(--rule);
    border: 0;
    margin: 0;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    background: var(--accent);
    color: #14120a;
    padding: 0.7rem 1.2rem;
    font-weight: 500;
    z-index: 20;
}

.skip-link:focus { left: 0; }

/* Visibile solo agli screen reader: serve a fornire il titolo per intero
   quando quello a schermo è spezzato lettera per lettera. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

/* ---------------------------------------------------------------- Header -- */

.site-header {
    position: sticky;
    top: 0;
    z-index: 10;
    background: rgba(10, 10, 11, 0.82);
    /* Il fondo semitrasparente sfoca ciò che scorre sotto: l'intestazione resta
       leggibile anche sopra una fotografia chiara. */
    backdrop-filter: saturate(140%) blur(14px);
    -webkit-backdrop-filter: saturate(140%) blur(14px);
    border-bottom: 1px solid var(--rule);
}

.header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s3);
    flex-wrap: wrap;
    padding-top: 1.15rem;
    padding-bottom: 1.15rem;
}

.logotype {
    font-family: var(--font-mono);
    font-size: 0.76rem;
    font-weight: 500;
    letter-spacing: 0.36em;
    text-transform: uppercase;
    /* La spaziatura finale sposta otticamente la parola a destra: il rientro
       negativo la riallinea al margine. */
    margin-right: -0.36em;
}

.site-nav {
    display: flex;
    align-items: center;
    gap: var(--s3);
}

.nav-link {
    position: relative;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    font-weight: 450;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-dim);
    padding: 0.35rem 0;
    transition: color 220ms var(--ease);
}

/* Filetto che cresce da sinistra: un segnale netto ma silenzioso, senza
   spostare il testo né cambiarne il peso. */
.nav-link::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    height: 1px;
    width: 100%;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 260ms var(--ease);
}

.nav-link:hover { color: var(--text); }
.nav-link:hover::after { transform: scaleX(1); }

.nav-link.is-active {
    color: var(--text);
}

.nav-link.is-active::after { transform: scaleX(1); }

.lang-switch {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    font-weight: 500;
    letter-spacing: 0.1em;
    color: var(--text-faint);
    border: 1px solid var(--rule-strong);
    padding: 0.3rem 0.6rem;
    transition: color 220ms var(--ease), border-color 220ms var(--ease);
}

.lang-switch:hover {
    color: var(--accent);
    border-color: var(--accent-dim);
}

/* ------------------------------------------------------------------ Hero -- */

.hero {
    position: relative;
    background: var(--bg-sunken);
    /* Toglie l'altezza dell'intestazione, così la fotografia riempie esattamente
       lo schermo residuo senza far comparire una striscia vuota. */
    min-height: calc(100vh - 58px);
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    overflow: hidden;
}

.hero-media {
    position: absolute;
    inset: 0;
    overflow: hidden;
}

.hero img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Ingrandimento lentissimo e continuo: dà profondità all'immagine ferma
       senza che si percepisca come un'animazione. */
    animation: hero-drift 26s var(--ease) forwards;
}

.hero-media::after {
    /* Velo scuro in basso: rende il titolo leggibile su qualunque fotografia
       senza appoggiarci sopra un pannello opaco. */
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(5, 5, 6, 0.9) 0%, rgba(5, 5, 6, 0.45) 38%, rgba(5, 5, 6, 0.05) 72%);
    pointer-events: none;
}

@keyframes hero-drift {
    from { transform: scale(1.0); }
    to { transform: scale(1.07); }
}

.hero-caption {
    position: relative;
    z-index: 1;
    width: 100%;
    padding-bottom: var(--s3);
}

.hero-title {
    color: #f6f4f0;
    /* Sul chiaro di una fotografia le lettere bianche perdono definizione:
       un'ombra appena percettibile le stacca senza sembrare un effetto. */
    text-shadow: 0 2px 40px rgba(0, 0, 0, 0.5);
}

.hero-meta {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--s2);
    flex-wrap: wrap;
    margin-top: var(--s2);
    padding-top: 0.9rem;
    border-top: 1px solid rgba(236, 233, 227, 0.22);
}

.hero-tagline {
    margin: 0;
    max-width: 30rem;
    color: #cbc8c2;
    font-size: 0.98rem;
}

/* Riga di dati tecnici sotto al titolo: le voci sono separate da un filetto
   verticale, come in una barra di stato. */
.hero-data {
    display: flex;
    align-items: center;
    gap: var(--s2);
    flex-wrap: wrap;
    color: #a8a49d;
}

.hero-data > span + span {
    padding-left: var(--s2);
    border-left: 1px solid rgba(236, 233, 227, 0.2);
}

.hero-scroll {
    color: var(--accent);
    white-space: nowrap;
}

/* -------------------------------------------- Titolo che si compone -- */

/* Le lettere sono già nell'HTML, ognuna nel proprio <span>: l'effetto è tutto
   in CSS, quindi non dipende dal JavaScript. Il ritardo cresce per lettera ed
   è calcolato lato server, non qui, perché dipende dalla lunghezza del testo. */
.letter {
    display: inline-block;
    animation: letter-in 780ms var(--ease-out) both;
}

@keyframes letter-in {
    from {
        opacity: 0;
        transform: translateY(0.42em);
        /* La lettera entra leggermente più larga e si stringe arrivando a posto:
           è questo, più della dissolvenza, a dare l'impressione che il titolo
           si "componga" invece di comparire. */
        font-variation-settings: 'wdth' 95, 'wght' 500;
    }
    to {
        opacity: 1;
        transform: translateY(0);
        font-variation-settings: 'wdth' 68, 'wght' 800;
    }
}


/* --------------------------------------------------------------- Sezioni -- */

.section { padding: var(--s5) 0; }

.section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s2);
    padding-bottom: var(--s2);
    border-bottom: 1px solid var(--rule);
    margin-bottom: var(--s4);
}

.section-link {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    font-weight: 450;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-dim);
    transition: color 200ms var(--ease);
}

.section-link:hover { color: var(--accent); }

.page-head {
    padding: var(--s5) 0 var(--s3);
}

.page-head .label { display: block; margin-bottom: var(--s2); }

.page-intro {
    color: var(--text-dim);
    margin: var(--s3) 0 0;
    font-size: 1.05rem;
    max-width: 40rem;
}

/* Testata delle gallerie: la fotografia di copertina a tutta larghezza con il
   titolo sopra, come la home ma più bassa — deve introdurre la galleria, non
   sostituirsi a essa. */
.cover-head {
    position: relative;
    min-height: min(66vh, 620px);
    display: flex;
    align-items: flex-end;
    overflow: hidden;
    background: var(--bg-sunken);
    margin-bottom: var(--s5);
}

.cover-head-media {
    position: absolute;
    inset: 0;
}

.cover-head-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.cover-head-media::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(5, 5, 6, 0.92) 0%, rgba(5, 5, 6, 0.5) 40%, rgba(5, 5, 6, 0.1) 74%);
}

.cover-head-inner {
    position: relative;
    z-index: 1;
    width: 100%;
    padding-bottom: var(--s3);
}

.cover-head-title {
    color: #f6f4f0;
    text-shadow: 0 2px 40px rgba(0, 0, 0, 0.5);
}

/* ------------------------------------------------------- Griglia gallerie -- */

.gallery-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--s3);
}

.gallery-card { display: block; }

.gallery-card figure {
    margin: 0;
}

.gallery-frame {
    position: relative;
    overflow: hidden;
    background: var(--bg-raised);
}

.gallery-card img {
    width: 100%;
    /* Verticale: nel formato ritratto le copertine si allineano in una griglia
       compatta e ordinata, che è l'effetto "parete di sala" cercato. */
    aspect-ratio: 3 / 4;
    object-fit: cover;
    /* Le copertine partono appena smorzate e si accendono al passaggio:
       un invito discreto, non un effetto. */
    filter: brightness(0.82) saturate(0.92);
    transform: scale(1.005);
    transition: filter 520ms var(--ease), transform 620ms var(--ease);
}

.gallery-card:hover img,
.gallery-card:focus-visible img {
    filter: brightness(1) saturate(1);
    transform: scale(1.035);
}

/* Numero progressivo dell'opera, come su un cartellino di sala. */
.gallery-index {
    position: absolute;
    top: 0.75rem;
    left: 0.85rem;
    font-size: 0.62rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    color: rgba(236, 233, 227, 0.72);
    font-variant-numeric: tabular-nums;
    mix-blend-mode: difference;
}

.gallery-card figcaption {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s2);
    margin-top: 0.85rem;
    padding-top: 0.7rem;
    border-top: 1px solid var(--rule);
    transition: border-color 300ms var(--ease);
}

.gallery-card:hover figcaption { border-color: var(--accent-dim); }

/* Il titolo del cartellino sotto la fotografia. Era a 420, un peso appena
   sopra il normale che sul grottesco bastava a staccarlo dalla didascalia;
   in serif, a questo corpo, si legge invece come testo corrente. */
.card-title {
    font-size: 1.06rem;
    font-weight: 520;
    letter-spacing: -0.01em;
}

/* ------------------------------------------------ Galleria a scorrimento -- */

/* Il layout scelto: una fotografia per riga, grande, con cartellino sotto.
   La larghezza massima impedisce che sui monitor molto ampi le immagini
   diventino ingestibili con lo sguardo. */
.photo-stream {
    max-width: 1500px;
    margin: 0 auto;
    padding: 0 var(--s3) var(--s6);
}

.photo-stream figure { margin: 0 0 var(--s5); }

.photo-stream img {
    width: 100%;
    background: var(--bg-raised);
}

.photo-caption {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--s2) var(--s3);
    align-items: baseline;
    margin-top: 0.9rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--rule);
}

.photo-caption-text {
    color: var(--text-dim);
    font-size: 0.95rem;
}

/* I dati di scatto sono il punto in cui il carattere tecnico del sito è più
   giustificato: sono letteralmente le impostazioni della macchina fotografica. */
.photo-exif {
    color: var(--text-faint);
    font-family: var(--font-mono);
    font-size: 0.66rem;
    font-weight: 450;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-align: right;
}

/* -------------------------------------------------------------- Articoli -- */

.article-list {
    list-style: none;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--rule);
}

.article-list li { border-bottom: 1px solid var(--rule); }

.article-link {
    display: grid;
    grid-template-columns: 6.5rem 1fr auto;
    gap: var(--s3);
    padding: var(--s3) 0;
    align-items: center;
    transition: background-color 300ms var(--ease), padding 300ms var(--ease);
}

.article-link:has(.article-cover-thumb) {
    grid-template-columns: 6.5rem 5rem 1fr auto;
    gap: 0.5rem;
}

.article-cover-thumb {
    width: 5rem;
    height: 5rem;
    object-fit: cover;
    border-radius: var(--radius);
    justify-self: center;
}

.article-link:hover {
    background: var(--bg-raised);
    /* Il rientro al passaggio sostituisce la sottolineatura: si nota, ma non
       altera il colore né il peso del testo. */
    padding-left: var(--s2);
    padding-right: var(--s2);
}

.article-date {
    color: var(--text-faint);
    font-family: var(--font-mono);
    font-size: 0.64rem;
    font-weight: 450;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.article-summary {
    display: block;
    color: var(--text-dim);
    margin-top: 0.3rem;
    font-size: 0.96rem;
}

.article-arrow {
    color: var(--text-faint);
    font-size: 1rem;
    transform: translateX(-0.35rem);
    opacity: 0;
    transition: opacity 260ms var(--ease), transform 260ms var(--ease);
}

.article-link:hover .article-arrow {
    opacity: 1;
    transform: translateX(0);
    color: var(--accent);
}

/* ---------------------------------------------------------- Testo lungo -- */

.article-header {
    max-width: var(--wrap-reading);
    margin: 0 auto;
    padding: var(--s5) var(--s3) var(--s3);
}

.article-header .article-date { display: block; margin-bottom: var(--s2); }

.article-cover {
    max-width: 1500px;
    margin: 0 auto var(--s4);
    padding: 0 var(--s3);
    display: flex;
    justify-content: center;
}

/* Colonna di lettura stretta, circa 68 caratteri: è il fattore che incide di
   più sulla leggibilità, molto più della scelta del carattere. */
.prose {
    max-width: var(--wrap-reading);
    margin: 0 auto;
    padding: 0 var(--s3) var(--s6);
    /* Stessa correzione fatta sul body, e per la stessa ragione: questa misura
       è in rem, quindi non eredita il corpo del body e va rialzata a parte,
       altrimenti l'articolo finirebbe più piccolo del resto della pagina. */
    font-size: 1.125rem;
    line-height: 1.72;
}

.prose h2 {
    margin-top: 2.2em;
    font-size: 1.4rem;
}

.prose h3 { margin-top: 1.8em; }

.prose a {
    color: var(--text);
    border-bottom: 1px solid var(--accent-dim);
    transition: border-color 200ms var(--ease), color 200ms var(--ease);
}

.prose a:hover {
    color: var(--accent);
    border-color: var(--accent);
}

.prose blockquote {
    margin: 2em 0;
    padding-left: var(--s3);
    border-left: 2px solid var(--accent-dim);
    color: var(--text-dim);
}

.prose code {
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: 0.88em;
    background: var(--bg-raised);
    padding: 0.12em 0.4em;
}

.prose pre {
    background: var(--bg-raised);
    border: 1px solid var(--rule);
    padding: var(--s2);
    overflow-x: auto;
}

.prose pre code { background: none; padding: 0; }

.prose img { margin: 2em 0; }

.back-link {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    margin-top: var(--s4);
    color: var(--text-dim);
    font-family: var(--font-mono);
    font-size: 0.66rem;
    font-weight: 450;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    transition: color 200ms var(--ease);
}

.back-link:hover { color: var(--accent); }

.back-link::before {
    content: '';
    width: 1.6rem;
    height: 1px;
    background: currentColor;
    transition: width 260ms var(--ease);
}

.back-link:hover::before { width: 2.4rem; }

/* --------------------------------------------------- Link esterni -- */

.project-links {
    max-width: var(--wrap-reading);
    margin: 0 auto var(--s3);
    padding: 0 var(--s3);
    display: flex;
    flex-wrap: wrap;
    gap: var(--s2);
}

.project-links a {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    padding: 0.4em 1em;
    border: 1px solid var(--rule-strong);
    border-radius: 4px;
    font-size: 0.9rem;
    color: var(--text);
    text-decoration: none;
    transition: border-color 200ms var(--ease), color 200ms var(--ease);
}

.project-links a::before {
    content: "\2197";  /* freccia nord-est */
    font-size: 0.8em;
}

.project-links a:hover {
    color: var(--accent);
    border-color: var(--accent);
}

/* --------------------------------------------------- Diario di progetto -- */

.project-diary {
    max-width: var(--wrap-reading);
    margin: 0 auto;
    padding: 0 var(--s3) var(--s5);
}

.project-diary-heading {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-faint);
    margin-bottom: var(--s3);
    padding-bottom: var(--s2);
    border-bottom: 1px solid var(--rule);
}

.project-entry {
    padding: var(--s3) 0 var(--s4);
    border-bottom: 1px solid var(--rule);
}

.project-entry:last-child { border-bottom: none; }

.project-entry-head { margin-bottom: var(--s2); }

.project-entry-title {
    margin-top: var(--s2);
    font-size: 1.35rem;
}

/* Stessa misura di lettura del corpo principale, alzata a parte perché i rem
   non ereditano il corpo del body. */
.project-entry-body {
    font-size: 1.125rem;
    line-height: 1.72;
}

.project-entry-body p { margin: 1em 0; }

/* Griglia delle foto allegate a una sezione (o alla galleria collegata):
   le proporzioni dichiarate via aspect-ratio riservano lo spazio prima che
   l'immagine arrivi, così la pagina non sobbalza durante il caricamento. */
.photo-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--s2);
    margin: var(--s3) 0;
}

.photo-item { margin: 0; }

.photo-item img {
    display: block;
    width: 100%;
    height: auto;
    margin: 0;
}

.photo-item figcaption {
    margin-top: 0.5rem;
    font-size: 0.85rem;
    color: var(--text-dim);
}

/* ------------------------------------------------------------ Chi sono -- */

.about-section {
    max-width: var(--wrap-reading);
    margin: 0 auto;
    padding: 0 var(--s3) var(--s5);
}

.about-section-title {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-faint);
    margin-bottom: var(--s4);
    padding-bottom: var(--s2);
    border-bottom: 1px solid var(--rule);
}

/* Esperienze lavorative */

.experience-list {
    display: flex;
    flex-direction: column;
    gap: var(--s4);
}

.experience-item {
    display: flex;
    flex-direction: column;
    gap: var(--s1);
}

.experience-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--s2);
}

.experience-title {
    font-size: 1.15rem;
    font-weight: 520;
    margin: 0;
    letter-spacing: -0.01em;
}

.experience-company {
    display: block;
    color: var(--text-dim);
    font-size: 0.95rem;
    margin-top: 0.2rem;
}

.experience-period {
    white-space: nowrap;
    flex-shrink: 0;
}

.experience-description {
    color: var(--text-dim);
    font-size: 0.96rem;
    margin: 0;
    max-width: 38rem;
}

/* Competenze */

.skills-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--s4);
}

.skill-category-name {
    font-size: 1rem;
    font-weight: 520;
    margin: 0 0 var(--s2);
    color: var(--text);
}

.skill-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.skill-item {
    font-family: var(--font-mono);
    font-size: 0.64rem;
    font-weight: 450;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
    background: var(--bg-raised);
    border: 1px solid var(--rule);
    padding: 0.4rem 0.8rem;
    transition: border-color 200ms var(--ease), color 200ms var(--ease);
}

.skill-item:hover {
    border-color: var(--accent-dim);
    color: var(--text);
}

/* ---------------------------------------------------------------- Moduli -- */

.form-field { margin-bottom: var(--s3); max-width: 34rem; }

.form-field label {
    display: block;
    font-family: var(--font-mono);
    font-size: 0.64rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-faint);
    margin-bottom: 0.5rem;
}

.form-field input,
.form-field textarea {
    width: 100%;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--rule-strong);
    color: var(--text);
    font: inherit;
    padding: 0.55rem 0;
    transition: border-color 220ms var(--ease);
}

.form-field textarea { min-height: 8rem; resize: vertical; }

.form-field input:focus,
.form-field textarea:focus {
    border-bottom-color: var(--accent);
    outline: none;
}

.button {
    display: inline-block;
    background: transparent;
    border: 1px solid var(--rule-strong);
    color: var(--text);
    font-family: var(--font-mono);
    font-size: 0.68rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    padding: 0.75rem 2rem;
    cursor: pointer;
    transition: background-color 240ms var(--ease), border-color 240ms var(--ease), color 240ms var(--ease);
}

.button:hover:not(:disabled) {
    background: var(--accent);
    border-color: var(--accent);
    color: #14120a;
}

.button:disabled { opacity: 0.4; cursor: not-allowed; }

.notice {
    border-left: 2px solid var(--accent-dim);
    background: var(--bg-raised);
    color: var(--text-dim);
    padding: var(--s2) var(--s3);
    max-width: 34rem;
    font-size: 0.94rem;
    margin-bottom: var(--s4);
}

/* ---------------------------------------------------------------- Footer -- */

.site-footer {
    border-top: 1px solid var(--rule);
    margin-top: var(--s5);
    /* Semitrasparente e non pieno: altrimenti il piè di pagina coprirebbe lo
       sfondo del sito proprio nell'ultima schermata. */
    background: rgba(7, 7, 8, 0.72);
}

.footer-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--s2);
    flex-wrap: wrap;
    padding-top: var(--s4);
    padding-bottom: var(--s4);
}

.copyright {
    margin: 0;
    color: var(--text-faint);
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.social {
    list-style: none;
    display: flex;
    gap: var(--s3);
    margin: 0;
    padding: 0;
}

.social a {
    color: var(--text-dim);
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    transition: color 200ms var(--ease);
}

.social a:hover { color: var(--accent); }

/* ------------------------------------------------- Comparsa allo scorrimento -- */

/* Movimento discreto: gli elementi entrano con uno scarto minimo, quel tanto
   che basta a dare vita alla pagina.

   Nota importante: lo stato nascosto non è il valore di partenza in CSS, ma una
   classe che lo script applica soltanto agli elementi ancora sotto la finestra.
   Se lo script non gira, il contenuto è visibile e basta: nascondere per
   impostazione predefinita significherebbe che un guasto al JavaScript rende
   la pagina bianca. */
.reveal {
    transition: opacity 700ms var(--ease), transform 700ms var(--ease);
}

.reveal.is-hidden {
    opacity: 0;
    transform: translateY(14px);
}

.reveal.is-visible {
    opacity: 1;
    transform: none;
}

/* --------------------------------------------------------------- Mobile -- */

@media (max-width: 820px) {
    :root {
        --s4: 2.2rem;
        --s5: 3.2rem;
        --s6: 4.5rem;
    }

    body { font-size: 16px; }

    .header-inner {
        padding-top: 0.9rem;
        padding-bottom: 0.9rem;
    }

    .site-nav {
        gap: var(--s2);
        flex-wrap: wrap;
        width: 100%;
        justify-content: space-between;
    }

    .nav-link { font-size: 0.64rem; letter-spacing: 0.14em; }

    .article-link {
        grid-template-columns: 1fr auto;
        gap: 0.3rem var(--s2);
    }

    .article-date { grid-column: 1 / -1; }

    .photo-caption { grid-template-columns: 1fr; }

    .photo-exif { text-align: left; }

    .hero img { height: clamp(340px, 62vh, 560px); }
}

/* Chi ha chiesto meno animazioni al sistema operativo non ne riceve:
   il contenuto resta identico, cambia solo il modo in cui compare. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    *, *::before, *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
        /* Azzerare anche il ritardo è indispensabile: con una durata quasi nulla
           ma un ritardo intatto, le lettere resterebbero invisibili per tutta
           l'attesa prima di scattare al valore finale. */
        animation-delay: 0ms !important;
        animation-iteration-count: 1 !important;
    }

    .reveal.is-hidden {
        opacity: 1;
        transform: none;
    }
}

/* ==========================================================================
   Tag filter
   ========================================================================== */
.tag-filter {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0 0 var(--s2);
    border-bottom: 1px solid var(--rule);
    margin-bottom: var(--s2);
}

.tag-chip {
    display: inline-block;
    padding: 0.3em 0.8em;
    border: 1px solid var(--rule);
    border-radius: 2em;
    font-family: var(--font);
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--text);
    transition: background-color 0.2s, color 0.2s, border-color 0.2s;
}

.tag-chip:hover {
    border-color: var(--accent);
    color: var(--accent);
}

.tag-chip-active,
.tag-chip-active:hover {
    background-color: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

.tag-chip-sm {
    font-size: 0.6rem;
    padding: 0.2em 0.6em;
}

.article-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-top: 0.35rem;
}

/* ---------------------------------------------------------------- Lightbox -- */

.lightbox {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 100;
    background: rgba(0, 0, 0, 0.95);
    align-items: center;
    justify-content: center;
    flex-direction: column;
}

.lightbox.is-active {
    display: flex;
}

.lightbox-close {
    position: absolute;
    top: 1rem;
    right: 1.5rem;
    background: none;
    border: none;
    color: #fff;
    font-size: 2.5rem;
    cursor: pointer;
    opacity: 0.7;
    transition: opacity 0.2s;
    z-index: 101;
    line-height: 1;
}

.lightbox-close:hover { opacity: 1; }

.lightbox-prev,
.lightbox-next {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: #fff;
    font-size: 3rem;
    cursor: pointer;
    opacity: 0.7;
    transition: opacity 0.2s;
    z-index: 101;
    padding: 1rem;
}

.lightbox-prev:hover,
.lightbox-next:hover { opacity: 1; }

.lightbox-prev { left: 0.5rem; }
.lightbox-next { right: 0.5rem; }

.lightbox-content {
    max-width: 90vw;
    max-height: 85vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

.lightbox-img {
    max-width: 100%;
    max-height: 85vh;
    object-fit: contain;
    border-radius: var(--radius);
}

.lightbox-caption {
    color: var(--text-dim);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    text-align: center;
    margin-top: 0.75rem;
    max-width: 80vw;
}
