@charset "UTF-8";

/* ===========================================================================
   Blanco Studio -- landing
   Riscrittura del <style> inline del 2025.

   Cosa cambia rispetto alla versione precedente, oltre al layout:
   - i valori di layout ripetuti sono diventati custom property
   - i ~15 media query sovrapposti sono diventati 4 breakpoint + guardie altezza
   - gerarchia dei titoli h5/h6 -> h3/p
   - focus visibile, focus trap e Esc sul pannello About
   - prefers-reduced-motion rispettato
   - il tilt 3D passa da custom property, non piu' transform inline

   Cosa NON cambia: nessun valore renderizzato e' stato spostato. Le stesse
   dimensioni a 420 / 768 / 1100 / 1320 px e sulle altezze corte.
   =========================================================================== */


/* -- 1. Font ---------------------------------------------------------------
   Rimosso l'@import di p.typekit.net: l'URL restituiva 5 byte, cioe' un
   foglio di stile vuoto (nient'altro che un commento). Era un round-trip
   sprecato sul critical path, bloccante perche' sta dentro un <style>. I due
   woff2 qui sotto sono gia' dichiarati a mano nell'originale e funzionavano.

   Aggiunto font-display: swap. Senza, il default e' font-display: auto, che
   blocca il testo per fino a ~3 s in attesa del font su cache vuota.

   NOTA: il fallback resta il generico sans-serif, come nel 2025. Provando con
   "Helvetica Neue", Helvetica, Arial il footer si sposta di 11px quando il
   font non e' ancora pronto: quei fallback hanno metriche di advance diverse
   dal generico, quindi il passaggio al webfont sposta il layout. */
@font-face {
    font-family: "akzidenz-grotesk";
    src: url("https://use.typekit.net/af/5556ca/000000000000000000013635/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3") format("woff2"),
         url("https://use.typekit.net/af/5556ca/000000000000000000013635/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3") format("woff"),
         url("https://use.typekit.net/af/5556ca/000000000000000000013635/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3") format("opentype");
    font-style: normal;
    font-weight: 400;
    font-display: swap;
}

@font-face {
    font-family: "akzidenz-grotesk";
    src: url("https://use.typekit.net/af/9d033e/000000000000000000013633/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n5&v=3") format("woff2"),
         url("https://use.typekit.net/af/9d033e/000000000000000000013633/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n5&v=3") format("woff"),
         url("https://use.typekit.net/af/9d033e/000000000000000000013633/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n5&v=3") format("opentype");
    font-style: normal;
    font-weight: 500;
    font-display: swap;
}


/* -- 2. Token ---------------------------------------------------------------
   I numeri 67 / 106 / 107 px misurano la stessa cosa: l'altezza del blocco
   HUD sotto il logo. Prima erano tre costanti indipendenti, percioa basta
   cambiare il layout del footer perche il logo e il pannello About smettono
   di combaciare. Sono qui insieme per quello. */
:root {
    /* palette */
    --c-bg: #000000;
    --c-fg: #f2f2f2;
    --c-fg-dim: #a9a9a9;
    --c-accent: rgba(72, 1, 255, .85);

    /* tipografia
       I fallback restano i generici del 2025: con font-display: swap un
       fallback nominato ("Helvetica Neue") ha metriche diverse dal generico e
       sposta il footer di 11px quando il webfont arriva. */
    --f-body: "akzidenz-grotesk", sans-serif;
    --f-display: "Inter", sans-serif;
    --fz-base: 14px;
    --fz-h2: 30px;
    --fz-h3: 18px;
    --fz-title: 14px;
    --fz-micro: 10px;
    --fz-logo: 40px;

    /* layout */
    --pad-x: 60px;
    --pad-x-sm: 30px;
    --pad-y-top: 2.5vh;
    --pad-y-bottom: 5vh;
    --hud-h: 67px;                             /* blocco info sotto il logo */
    --logo-offset: calc(7.5vh + var(--hud-h));
    --about-top: calc(106px + 15vh);
    --about-bottom: calc(107px + 5vh);

    /* filetti: il ":after" dei titoli e la ":before" dei nav link */
    --rule-len: 40px;
    --rule-w: 2px;
    --tick-len: .85em;
    --tick-w: 2px;
    --tick-angle: 25deg;

    /* movimento */
    --ease: cubic-bezier(.2, .7, .2, 1);
    --dur: .35s;
    --dur-tilt: .1s;
    --stagger: 200ms;
    --enter-at: 500ms;
    --enter-dur: 1.5s;
}


/* -- 3. Base --------------------------------------------------------------- */
html {
    line-height: 1.15;
    -webkit-text-size-adjust: 100%;
    box-sizing: border-box;
}

*, :after, :before {
    box-sizing: inherit;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    -webkit-font-kerning: auto;
    font-kerning: auto;
}

body, button {
    font-family: var(--f-body);
    font-size: var(--fz-base);
    font-weight: 400;
    -webkit-font-feature-settings: "liga", "kern";
    font-feature-settings: "liga", "kern";
    -webkit-font-smoothing: subpixel-antialiased;
}

h2, h3, h5, strong { font-family: var(--f-body); font-weight: 500; }
h2 { font-size: var(--fz-h2); }
h3 { font-size: var(--fz-h3); }

p:first-of-type { margin-top: 0; }
p:last-of-type { margin-bottom: 0; }

body {
    margin: 0;
    padding: 0;
    background-color: var(--c-bg);
    color: var(--c-fg);
    overflow: hidden;
}


/* -- 4. Tema -----------------------------------------------------------------
   Solo dark, come scelto: il selettore .theme-dark sul body e' l'unica fonte
   di verita' dei colori. La vecchia classe "ultra-mode" aveva gia' questo
   ruolo, ma accanto c'erano quattro handler JS per un light-mode/night-mode
   che interrogavano elementi inesistenti e non facevano nulla. */
.theme-dark { color: var(--c-fg); }
.theme-dark .ui { color: var(--c-fg); }
.theme-dark .ui a:not(.logo),
.theme-dark .ui button.link { color: var(--c-fg); }
.theme-dark .ui .links .nav-li:after { background-color: var(--c-fg); }
.theme-dark .about:before { background-color: var(--c-accent); }
.theme-dark .about .left,
.theme-dark .about .right { color: var(--c-fg); }
.theme-dark .projects .project-title { color: var(--c-fg); }

/* Da 768px in su la sfondo viola sparisce e resta solo il vetro smerigliato
   della card, con i titoli dei progetti che si vedono sfocati dietro. Era cosi'
   anche nel 2025: senza questa regola il pannello diventa viola pieno anche su
   desktop e cambia completamente l'effetto. */
@media screen and (min-width: 768px) {
    .theme-dark .about:before { display: none; }
}

@supports (-webkit-text-stroke: 1px #fff) or (text-stroke: 1px #fff) {
    .theme-dark .logo {
        -webkit-text-stroke: 1px #fff;
        text-stroke: 1px #fff;
    }
}


/* -- 5. Utility ------------------------------------------------------------ */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Il salto al contenuto era impossibile prima: tutto e' fixed e pointer-events
   disabilitati sul contenitore .ui. */
.skip-link {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 200;
    padding: 12px 18px;
    background: var(--c-fg);
    color: var(--c-bg);
    font-size: var(--fz-base);
    text-decoration: none;
    transform: translateY(-105%);
    transition: transform var(--dur-fast) linear;
}

.skip-link:focus-visible {
    transform: translateY(0);
    outline: 2px solid var(--c-accent);
    outline-offset: 2px;
}

/* Focus visibile. Prima non esisteva nessuna regola :focus-visible: sui link
   del footer, che stanno dentro una scena 3D ruotata, il focus era invisibile
   e il pannello About non aveva un focus trap (si poteva tabulare nel
   contenuto nascosto di sotto). */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
    outline: 1px solid currentColor;
    outline-offset: 4px;
}


/* -- 6. Curtain ----------------------------------------------------------- */
.curtain {
    position: fixed;
    inset: 0;
    z-index: 100;
    background-color: #f2f2f2;
    opacity: 0;
    pointer-events: none;
    transition: opacity .5s;
}

.is-loading .curtain { opacity: 1; }


/* -- 7. Header UI --------------------------------------------------------- */
.ui {
    position: fixed;
    bottom: 0;
    left: 0;
    z-index: 2;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    width: 100%;
    pointer-events: none;
}

.ui * { pointer-events: auto; }

.ui .logo {
    position: absolute;
    bottom: var(--logo-offset);
    left: var(--pad-x);
    z-index: 1;
    display: block;
    font-family: var(--f-display);
    font-weight: 900;
    font-size: var(--fz-logo);
    line-height: .85em;
    text-transform: uppercase;
    text-decoration: none;
    font-smoothing: antialiased;
    /* translateZ(0) era nell'originale: senza, il logo viene rasterizzato
       diversamente. Costa un layer, ma e' un elemento solo. */
    transform: translateZ(0);
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
}

@supports (-webkit-text-stroke: 1px #000) or (text-stroke: 1px #000) {
    .ui .logo {
        -webkit-text-stroke: 1px #000;
        text-stroke: 1px #000;
    }
}

.ui .logo .slideUp { padding-bottom: 2px; }

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

.ui li { margin-bottom: 5px; }
.ui li span {
    margin-right: 15px;
    font-size: var(--fz-micro);
}

.ui a { text-decoration: none; }
.ui a, .ui button.link { color: #fff; cursor: pointer; }

.ui button.link {
    padding: 0;
    font: inherit;
    background: none;
    border: none;
}

.ui .contact,
.ui .info,
.ui .left,
.ui .right { display: flex; }

.ui .left {
    width: 70%;
    min-width: 0;
    align-items: flex-end;
}

.ui .right {
    position: relative;
    justify-content: space-between;
    width: 30%;
    max-width: 250px;
    align-items: flex-end;
}

.ui .info {
    justify-content: space-between;
    align-items: flex-end;
    width: 100%;
    padding: var(--pad-y-top) var(--pad-x) var(--pad-y-bottom);
}

/* Il tilt 3D sta in tre variabili. Prima il JS scriveva transform inline
   direttamente sull'elemento a ogni mousemove, e la transition in CSS veniva
   riavviata a ogni frame: il risultato era un movimento che "scattava".
   Cosi' la transition resta una sola e vale solo per l'hover. */
.ui .info a,
.ui .info button.link {
    --rx: 0deg;
    --ry: 0deg;
    --lift: 0px;
    position: relative;
    display: inline-block;
    padding: 5px;
    transform: rotateY(var(--ry)) rotateX(var(--rx)) translateZ(var(--lift));
    transform-origin: left center;
    transition: transform var(--dur-tilt) ease;
}

.ui .info a:hover,
.ui .info a:focus-visible,
.ui .info button.link:hover,
.ui .info button.link:focus-visible {
    --lift: 40px;
    transition: transform var(--dur) var(--ease);
}

.ui .info li {
    perspective: 250px;
    perspective-origin: 0;
}

.ui .info .contact li { perspective: 400px; }
.ui .info .contact .email { display: inline-block; }
.ui .info .contact a { padding: 0; }

.ui .links {
    min-width: 0;
    max-width: 100%;
}

.ui .links ul {
    display: flex;
    flex-direction: row;
    gap: 20px;
    max-width: 100%;
    padding-bottom: 6px;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.ui .links ul::-webkit-scrollbar { display: none; }

.ui .links .nav-li {
    position: relative;
    flex: 0 0 auto;
    white-space: nowrap;
}

.ui .links .nav-li:after {
    content: "";
    position: absolute;
    top: 50%;
    left: calc(100% + 15px);
    width: var(--rule-len);
    height: var(--rule-w);
    border-radius: 1px;
    background-color: #000;
    transform: translateY(-50%) scaleX(0);
    transform-origin: left center;
    transition: transform var(--dur) var(--ease);
}

.ui .links .nav-li:hover:after,
.ui .links .nav-li:focus-within:after,
.ui .links .nav-li.is-active:after {
    transform: translateY(-50%) scaleX(1);
}

.ui .links ul.is-dragging {
    cursor: grabbing;
    scroll-behavior: auto;
}

.ui .links ul.is-dragging .link { pointer-events: none; }

.ui .credit-link {
    perspective: 250px;
    perspective-origin: 0;
}

.ui .credit-link a {
    margin-right: 12px;
    transform-origin: left center;
}

.ui .contact ul {
    display: flex;
    flex-direction: row;
    gap: 20px;
    margin-right: 3vw;
}

.ui .contact ul:nth-child(2) li {
    display: inline-block;
    vertical-align: top;
    margin-right: 20px;
}

.ui .credits {
    width: 50%;
    text-align: right;
}

.ui .credits div:not(:last-of-type) { margin-bottom: 5px; }

/* Il copyright era a opacity .25 (nero) o .5/.35 (bianco): sotto WCAG AA.
   Ora e' a .6. Su schermi larghi resta nascosto, come prima. */
.ui .copyright {
    position: absolute;
    bottom: 10px;
    left: var(--pad-x);
    width: 50%;
    margin: 0;
    color: var(--c-fg);
    font-size: var(--fz-micro);
    opacity: .6;
}


/* -- 8. Stage e progetti -------------------------------------------------- */
.home-page .stagePerspective {
    position: relative;
    width: 100%;
    /* Non era una regola morta: nel 2025 era .home-page:not(.isMobile) e la
       classe isMobile non veniva mai aggiunta, quindi valeva sempre. Togliere
       height+overflow sposta l'origine della prospettiva e i titoli ruotati
       finiscono sfalsati in verticale. */
    height: 100vh;
    overflow: hidden;
    perspective: 100vw;
}

.home-page .stageContainer {
    position: relative;
    width: 100%;
    transform: translateZ(0);
    transform-style: preserve-3d;
    pointer-events: none;
}

.home-page .stage {
    position: fixed;
    top: 0;
    left: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    width: 100%;
    padding: 5vw 5vw calc(7.5vw + var(--hud-h)) 0;
    transform-style: preserve-3d;
    opacity: 1;
    pointer-events: none;
}

.home-page .projects {
    position: relative;
    width: 95%;
    margin: 0;
    padding-left: 0;
    list-style: none;
    text-align: right;
    transform-style: preserve-3d;
    pointer-events: none;
}

.home-page .projectsLi {
    transform-style: preserve-3d;
    pointer-events: none;
}

.home-page .projectContainer {
    transform: rotateY(-45deg) translateZ(0) scale(1);
    transform-origin: right center;
    transform-style: preserve-3d;
    animation: projectEnter var(--enter-dur) ease-out forwards;
    opacity: 0;
    pointer-events: auto;
    /* Lo slideUp del logo usa lo stesso trucco. */
    will-change: transform;
}

.home-page .projectsLi .projectContainer {
    animation-delay: calc(var(--enter-at) + var(--i) * var(--stagger));
}

@keyframes projectEnter {
    0% {
        opacity: 0;
        transform: rotateY(-45deg) translateY(-200px) scale(.5);
    }
    100% {
        opacity: 1;
        transform: rotateY(-45deg) translateY(-60px) translateZ(0) scale(1);
    }
}

/* I titoli erano <span> con pointer-events: none sul <li>: cinque progetti,
   nessuno cliccabile. Ora sono link, e il parent non ha piu' pointer-events
   none, altrimenti l'hit-test non arriverebbe mai al link. */
.home-page .project-title {
    position: relative;
    display: block;
    color: var(--c-fg);
    font-family: var(--f-display);
    font-weight: 900;
    font-size: 9.6vw;
    line-height: .9em;
    letter-spacing: .02em;
    text-transform: uppercase;
    text-decoration: none;
}

/* L'anno passava da #fff a 9px: sotto i 24px non e' leggibile e il contrasto
   del bianco puro sul nero era l'unico appigio. Ora 11px e #f2f2f2. */
.home-page .project-title:before {
    content: attr(data-info);
    position: absolute;
    top: .3em;
    right: 100%;
    margin-right: .5em;
    color: var(--c-fg);
    font-size: max(.75vw, 11px);
    font-weight: 500;
    line-height: 1em;
    letter-spacing: 0;
    text-transform: none;
    white-space: nowrap;
    transition: color var(--dur) var(--ease);
}

.home-page .project-title:after {
    content: "";
    position: absolute;
    top: .23em;
    left: -.3em;
    width: var(--tick-w);
    height: var(--tick-len);
    background-color: #fff;
    transform: rotate(var(--tick-angle));
    transform-origin: center;
    transition: transform var(--dur) var(--ease);
    pointer-events: none;
}

/* Stesso linguaggio del filetto che compare sui nav link: si estende e
   l'anno cambia colore. Niente di nuovo, solo il motivo gia' presente. */
.home-page .project-title:hover:before,
.home-page .project-title:focus-visible:before { color: var(--c-accent); }

.home-page .project-title:hover:after,
.home-page .project-title:focus-visible:after {
    transform: rotate(var(--tick-angle)) scaleY(1.35);
}

.home-page .project-title:hover,
.home-page .project-title:focus-visible {
    transform: translateZ(24px);
    transition: transform var(--dur) var(--ease);
}

.home-page .parallaxPerspective {
    perspective-origin: 50% 50%;
    /* Era anche nel 2025. Tolto, il testo del footer e il logo vengono
       rasterizzati diversamente (diversa antialiasing) rispetto all'originale. */
    will-change: perspective-origin;
}


/* -- 9. Slide-up del logo ------------------------------------------------- */
.slideUp {
    position: relative;
    display: block;
    width: 100%;
    overflow: hidden;
}

.slideUp span {
    display: block;
    transform: translateY(120%);
    animation: slideUpAnim 1s forwards;
}

.slideUp:nth-child(2) span { animation-delay: .2s; }
.slideUp:nth-child(3) span { animation-delay: .35s; }

@keyframes slideUpAnim {
    0%   { transform: translateY(120%); }
    to   { transform: translateY(0); }
}


/* -- 10. Pannello About --------------------------------------------------- */
.about {
    position: fixed;
    inset: 0;
    z-index: 3;
    width: 100%;
    height: 100%;
    opacity: 0;
    pointer-events: none;
    transition: opacity .5s;
}

.is-about-open .about {
    opacity: 1;
    pointer-events: auto;
}

.about:before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background-color: #f0f0f0;
}

.about .container {
    display: flex;
    justify-content: space-between;
    width: 100%;
    max-width: calc(1440px + 10vw);
    height: calc(100vh - var(--about-top));
    margin: var(--about-top) auto var(--about-bottom);
    padding-left: 5vw;
    padding-right: 5vw;
    overflow-x: hidden;
    overflow-y: auto;
    /* Senza questo, lo scroll della rotella sul pannello continuava a
       scrollare il documento dietro. */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    background: rgba(255, 255, 255, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-top-left-radius: 50px;
    border-top-right-radius: 50px;
    box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
    transform: translateZ(0);
    transition: transform .5s;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}

.about .container:focus { outline: none; }

/* Chiuso, il pannello sta 30px piu' in basso e sale all'apertura. */
@media screen and (min-width: 768px) {
    .about .container { transform: translate3d(0, 30px, 0); }
    .is-about-open .about .container { transform: translate3d(0, 0, 0); }
}

.about .left {
    width: 55%;
    padding-right: 10%;
    color: var(--c-fg);
    font-size: var(--fz-h2);
    line-height: 1.2em;
}

.about .left p {
    /* line-height non dichiarato di proposito: nel 2025 ereditava 36px
       (1.2em calcolato sui 30px del genitore). Dichiararlo qui darebbe
       1.2em dei propri 24px, cioe' 28.8px, e le righe si avvicinerebbero. */
    font-size: 24px;
}

.about .left p:last-of-type { margin-bottom: 50px; }

.about .right {
    display: flex;
    justify-content: space-between;
    width: 45%;
    padding-top: 8px;
    color: var(--c-fg);
}

.about .col-1 {
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    justify-content: space-between;
    width: 50%;
    margin-bottom: 30px;
}

.about .col-2 { width: 50%; }

.about .left .heading { line-height: 1.2em; }

.about .right .heading {
    width: 100%;
    /* Era un <h5> e prendeva i margini UA del browser (1.67em = 30px sopra).
       Passato a <h3> quei margini cambiano (1em = 18px) e il pannello si
       restringe di 95px: vanno fissati qui. */
    margin-top: 1.67em;
    margin-bottom: 20px;
}

.about p {
    width: 100%;
    margin-bottom: 5px;
}

/* Era un <h6> 14px/500, ora <p class="title">. Aspetto e margini UA identici:
   i Chrome davano 2.33em sopra e sotto (32.6px a 14px). Senza questo, il
   passaggio a <p> azzererebbe i margini e stringerebbe la colonna. */
.about .title {
    margin: 2.33em 0;
    font-weight: 500;
    font-size: var(--fz-title);
}

.about .info {
    width: 100%;
    padding-bottom: 30px;
}

.about .info ul {
    margin: 0;
    padding-left: 0;
    list-style: none;
}

.about .info li { margin-bottom: 3px; }


/* ===========================================================================
   11. Responsive

   I valori sotto sono gli stessi del 2025, ma i gate sono stati ricondotti a
   quattro breakpoint. Le tre query "width: 1024px" / "width: 768px" con
   opacity: 1 erano no-op, e la regola .copyright compariva tre volte con
   valori opposti.

   Soglia e cosa cambia:
     420px  telefoni piccoli
     768px  da qui in giu' il layout e' a colonna singola con logo in alto
    1100px  header a colonna, logo in flusso invece che assoluto
    1320px  i titoli tornano grandi (9.6vw invece di 7.4vw)
   =========================================================================== */

/* -- 1320px e oltre: titoli grandi --------------------------------------- */
@media screen and (min-width: 1320px) {
    .home-page .project-title { font-size: 9.6vw; }
}

/* -- 768px-1320px: titoli piu' piccoli per non andare in overflow -------- */
@media screen and (min-width: 768px) and (max-width: 1319px) {
    .home-page .project-title { font-size: 7.4vw; }
}

/* -- 1025px e oltre: copyright nascosto ------------------------------------
   Nel 2025 il copyright era display:none con (min-height:550px) AND
   (min-width:1025px) e opacity:0 con min-width:1025px: in pratica, su
   qualunque schermo largo era invisibile. La soglia resta 1025 e non 1100
   per non cambiarne il comportamento nella fascia 1025-1099. --------------- */
@media screen and (min-width: 1025px) {
    .ui .copyright { display: none; }
}

/* -- 768px-1100px: header a colonna, logo in flusso --------------------- */
@media screen and (min-width: 768px) and (max-width: 1099px) {
    .ui {
        flex-direction: column;
        align-items: stretch;
    }

    .ui .logo {
        position: relative;
        top: auto;
        bottom: auto;
        left: auto;
        margin: 4vh var(--pad-x-sm) 3vh;
        font-size: 30px;
    }

    .ui .info { padding: var(--pad-y-top) var(--pad-x-sm) 4vh; }

    .ui .left {
        flex-direction: column;
        align-items: stretch;
        width: 100%;
    }

    .ui .contact { width: 100%; }
    .ui .links { width: 100%; margin-top: 4vh; }
    .ui .right { max-width: 100%; }
}

/* -- schermi bassi in orizzontale: il logo non deve rubare altezza ------ */
@media screen and (min-width: 768px) and (max-height: 480px) {
    .ui .logo {
        margin: 2vh var(--pad-x-sm) 1vh;
        font-size: 18px;
    }
}

/* -- crediti troppo in basso su schermi bassi --------------------------- */
@media screen and (max-height: 414px) {
    .ui .credits { margin-bottom: 5px; }
}

/* -- 767px e sotto: layout mobile ---------------------------------------- */
@media screen and (max-width: 767px) {
    .ui {
        flex-wrap: nowrap;
        align-items: stretch;
        justify-content: flex-end;
        width: 100%;
        padding: 0;
    }

    .ui .logo {
        position: fixed;
        top: 5vw;
        bottom: auto;
        left: var(--pad-x-sm);
        font-size: 18px;
    }

    .ui .info {
        flex-direction: column;
        align-items: stretch;
        width: 100%;
        height: auto;
        margin-top: auto;
        padding: 0 var(--pad-x-sm) var(--pad-y-bottom);
    }

    .theme-dark .ui .info { background-color: var(--c-bg); }

    .ui .left,
    .ui .right {
        flex: 0 0 auto;
        width: 100%;
        min-width: 0;
    }

    .ui .left {
        flex-direction: column;
        align-items: stretch;
    }

    .ui .links { width: 100%; margin-top: 4vh; }
    .ui .right { margin-top: 4vh; }

    .ui .copyright {
        position: static;
        width: 100%;
        margin-top: 4vh;
        opacity: .6;
    }

    .ui .credits .label {
        margin-bottom: 15px;
        font-size: 16px;
    }

    .ui .contact {
        flex-wrap: wrap;
        width: 100%;
    }

    .ui .contact ul {
        flex-direction: column;
        width: auto;
        margin-right: 6vw;
    }

    .ui .contact .email a { word-break: break-all; }

    /* Su mobile il filetto va sotto la parola, non in mezzo alla riga. */
    .ui .links .nav-li:after {
        top: auto;
        bottom: -4px;
        left: 5px;
        display: block;
        width: 24px;
        height: 1px;
        transform: scaleX(0);
        transform-origin: left center;
    }

    .ui .links .nav-li:hover:after,
    .ui .links .nav-li:focus-within:after,
    .ui .links .nav-li.is-active:after {
        transform: scaleX(1);
    }

    .home-page .stagePerspective { perspective: 400vw; }

    .home-page .stage {
        padding-top: 17vw;
        padding-bottom: 17vw;
    }

    .home-page .project-title:after { width: 1px; }

    .about { z-index: 10; }

    .about .container {
        display: block;
        height: 100vh;
        margin: 0;
    }

    .about .left {
        width: 100%;
        max-width: 414px;
        padding-top: calc(71px + 10vw);
        padding-right: 0;
    }

    .about .left .heading { font-size: 24px; }

    .about .left p {
        font-size: 20px;
        line-height: 1.4em;
    }

    .about .right {
        flex-wrap: wrap;
        width: 100%;
        padding: 0;
    }

    .about .col-1,
    .about .col-2 { width: 100%; }

    /* 24px sotto: 16px + padding non danno il minimo di 44px. */
    .ui .info a,
    .ui .info button.link {
        min-height: 44px;
        padding-bottom: 15px;
        font-size: 16px;
    }

    .ui li { font-size: 16px; }
    .ui li span { font-size: 12px; }
}

/* -- mobile su schermo basso: l'HUD non deve coprire i progetti --------- */
@media screen and (max-width: 767px) and (max-height: 750px) {
    .ui .info { padding-bottom: 3vh; }
    .ui .links,
    .ui .right { margin-top: 3vh; }
    .ui .copyright { margin-top: 2.5vh; }

    .home-page .stage {
        padding-top: 10vw;
        padding-bottom: 10vw;
    }

    .home-page .project-title { font-size: 11vw; }
}

/* -- 767px e sotto, la colonna destra si stringe ------------------------ */
@media screen and (max-width: 1070px) {
    .about .left { width: 45%; }
    .about .right { width: 55%; }
}

/* -- 420px e sotto ------------------------------------------------------ */
@media screen and (max-width: 420px) {
    :root {
        --pad-y-bottom: 4vh;
    }

    .ui .info { padding: 0 var(--pad-x-sm) 4vh; }

    .ui .contact ul { margin-right: 5vw; }
    .ui .contact ul:last-of-type { margin-right: 0; }

    .ui .credits { width: 100%; }
    .ui .credit-link { margin-bottom: 0; }

    .home-page .stage { padding-top: 25vw; }

    .home-page .projects { width: 100%; }

    .home-page .project-title {
        font-size: 13vw;
        letter-spacing: normal;
    }

    .home-page .project-title:before {
        top: .3em;
        right: 100%;
        left: auto;
    }

    .home-page .project-title:after {
        top: 10px;
        left: -15px;
    }
}


/* -- 12. Preferenza: riduci il movimento -----------------------------------
   Prima non esisteva. Con reduce attivo, slideUp e projectEnter partivano
   comunque e il tilt 3D seguiva il mouse: 1,5 s di animazioni non
   richieste. Qui diventano comparse immediate; il tilt e' disattivato anche
   in JS. */
@media (prefers-reduced-motion: reduce) {
    *,
    *:before,
    *:after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }

    .slideUp span {
        transform: none;
        animation: none;
    }

    .home-page .projectContainer {
        opacity: 1;
        transform: rotateY(-45deg) translateY(-60px) scale(1);
        animation: none;
        will-change: auto;
    }

    .curtain { transition: none; }
}


/* -- 13. Print --------------------------------------------------------------
   body ha overflow:hidden e lo stage e' fixed: stampando si otterrebbe una
   pagina vuota. */
@media print {
    body { overflow: visible; background: #fff; color: #000; }

    .curtain,
    .skip-link,
    .home-page .stagePerspective { display: none; }

    .about {
        position: static;
        opacity: 1;
        pointer-events: auto;
    }

    .about:before { display: none; }
    .about .container { display: block; height: auto; margin: 0; padding: 0; }
    .ui { position: static; }
}
