/* ============================================================
   MVP MODE — versione pubblicabile ridotta
   ------------------------------------------------------------
   Si attiva SOLO con <html data-mvp>. Niente qui cancella o
   riscrive il sito completo: spegne per selettore quello che
   non fa parte dell'MVP e disegna i tre elementi che restano —
   fascia di avviso, marchio, "Scrivimi".

   PER TORNARE AL SITO PIENO bastano tre gesti:
     1. togliere data-mvp da <html> in index.html
     2. togliere il <link> a questo file
     3. togliere il blocco "CHROME MVP" da index.html
   Le guardie JS (grid.js, main.js) leggono lo stesso attributo,
   quindi si disarmano da sole al punto 1.

   Caricato DOPO style.css: vince per ordine, non per !important,
   così le regole restano leggibili e sovrascrivibili.
   ============================================================ */

/* ---------- 1. quello che in MVP non esiste ----------
   display:none e non visibility: devono uscire dal layout e dal
   focus da tastiera, non solo dalla vista. Il markup resta in
   pagina, inerte, pronto a riaccendersi. */
[data-mvp] .topbar,          /* logo, orologi, CTA, menu */
[data-mvp] .menu,            /* overlay di navigazione   */
[data-mvp] .dock,            /* filtri · mani · preferenze */
[data-mvp] .hud,             /* titolo della card sotto il cursore */
/* NOTA: .cookie NON sta più in questo elenco. Google Analytics è attivo anche
   in MVP (vedi il tag gtag in <head>), quindi il consenso va chiesto: era
   spento per una svista, non per una scelta. */
[data-mvp] .sitefoot,        /* copyright + link legali  */
[data-mvp] .section,         /* about · journal · contact · legal · notice · article · project */
[data-mvp] .handtrack-btn,
[data-mvp] .handtrack-preview,
[data-mvp] .handtrack-cursor{
  display:none !important;
}

/* ---------- 2. la griglia si prende tutto ---------- */
[data-mvp] body{overflow:hidden;}
[data-mvp] .archive{position:fixed;inset:0;}
/* niente cursore "pointer": in MVP le card non aprono niente, e un
   puntatore a manina prometterebbe un click che non arriva. Il JS
   tiene 'grab'; questa è la rete di sicurezza per il primo frame. */
[data-mvp] .archive__canvas{cursor:grab;}
[data-mvp] .archive__canvas:active{cursor:grabbing;}

/* ---------- 2b. base scura sotto il piede ----------
   .bottom-distort è la fascia che sfoca e scurisce il fondo dello schermo.
   Qui la alzo un po': il pulsante bianco e la riga smorzata sopra di lui
   passano su card di qualunque colore, e senza un fondo un filo più deciso
   la riga al 72% sparisce quando sotto scorre un'immagine chiara.
   Override scoped all'MVP: nel sito pieno la fascia resta come l'hai tarata
   per il dock. Spostare questi due valori in style.css la promuove ovunque. */
[data-mvp] .bottom-distort{height:250px;}
[data-mvp] .bottom-distort::after{
  background:linear-gradient(to bottom,
    rgba(0,0,0,0)   0%,
    rgba(0,0,0,.08) 30%,
    rgba(0,0,0,.23) 50%,
    rgba(0,0,0,.45) 68%,
    rgba(0,0,0,.66) 84%,
    rgba(0,0,0,.80) 100%);
}

/* ---------- 3. tipografia della chrome MVP ----------
   Niente etichette mono maiuscole: qui si parla in prima persona,
   quindi frase normale nel sans, corpo di lettura e tracking dei
   titoli. Le maiuscole spaziate sono per le etichette di sistema,
   non per una frase che deve suonare come una voce. */
[data-mvp] .wipbar__text,
[data-mvp] .wipcta{
  font-family:var(--font);
  font-size:15px;
  font-weight:var(--w-regular);
  letter-spacing:0;        /* niente tracking: è una frase, non un'etichetta */
  text-transform:none;
  line-height:1.2;
}

/* ---------- 4. fascia di avviso, a tutta larghezza ---------- */
.wipbar{display:none;}
[data-mvp] .wipbar{
  position:fixed;
  top:0;left:0;right:0;
  z-index:210;                      /* sopra .top-distort (z 88), come la topbar del sito */
  display:flex;
  align-items:center;
  justify-content:center;
  padding:13px var(--s24);
  text-align:center;
  pointer-events:none;              /* la griglia si trascina anche sotto la fascia */
  /* vetro arancione: gli rgba sono var(--accent) #ff6347. Serve il literal
     perché rgba() non accetta una variabile colore; se un giorno cambi
     --accent, questi tre valori vanno rifatti a mano. La sfumatura scende
     da .60 a .20: carica in alto, dissolve verso la griglia. */
  border-bottom:0.5px solid rgba(255,99,71,.10);
  background:linear-gradient(to bottom,rgba(255,99,71,.60) 0%,rgba(255,99,71,.20) 100%);
  -webkit-backdrop-filter:blur(20px) saturate(1.8) brightness(1.08);
          backdrop-filter:blur(20px) saturate(1.8) brightness(1.08);
}
/* bianco pieno, non var(--ink): il testo sta sull'arancione in entrambi i
   temi, quindi non deve seguire il tema ma il fondo su cui poggia. */
[data-mvp] .wipbar__text{color:#fff;}

/* ---------- 5. marchio, in alto al centro sotto la fascia ---------- */
.wipmark{display:none;}
[data-mvp] .wipmark{
  position:fixed;
  /* appena sotto la fascia. Come lo switch, usa l'altezza misurata invece di
     un numero fisso: con un testo lungo la fascia va a capo più volte e a
     64px il marchio le finirebbe sotto. */
  top:calc(var(--wipbar-h,48px) + 16px);
  left:50%;
  transform:translateX(-50%);
  z-index:210;                       /* idem: .top-distort è alta 150px e lo prendeva in pieno */
  pointer-events:none;
  line-height:0;                     /* niente discendente sotto il canvas */
}
[data-mvp] .wipmark canvas{display:block;width:54px;height:54px;}

/* ---------- 6. "Scrivimi", in basso al centro ----------
   Faccia bianca piatta + anello di luce che gira dietro. Tre strati
   sovrapposti, nell'ordine in cui vengono dipinti:

     ::after   bloom      z-index -1   la stessa luce, sfocata → alone
     ::before  anello     z-index  0   il filo di luce netto sul bordo
     __face    faccia     z-index  1   la pillola bianca con la scritta

   L'ordine non è decorativo: la faccia DEVE stare sopra, altrimenti
   l'anello le passa sopra la scritta. Per questo il testo è dentro uno
   span invece che nudo dentro il link — uno pseudo-elemento non si può
   mettere sotto il testo del proprio genitore.
   Il fondo del link è trasparente: è quello che permette al bloom con
   z-index negativo di finire davvero in fondo alla pila. */

/* L'angolo va registrato come proprietà tipizzata, altrimenti il browser
   lo tratta come stringa e una stringa non si può interpolare: il gradiente
   scatterebbe da 0 a 360 senza passare per i gradi in mezzo. Con @property
   diventa un <angle> vero e l'animazione è continua.
   Se un browser non conosce @property, l'angolo resta fermo a 0deg: il
   bordo sfumato c'è comunque, semplicemente non ruota. */
@property --wip-angle{
  syntax:'<angle>';
  initial-value:0deg;
  inherits:false;
}
@keyframes wip-spin{to{--wip-angle:360deg;}}

/* il piede: riga di invito + pulsante, impilati e centrati.
   Il pulsante da solo, rimpicciolito, si perdeva in fondo allo schermo. La
   riga sopra non serve a spiegare — serve a dare massa al gruppo: due
   elementi allineati pesano più di uno, senza dover ingrossare la pillola.
   pointer-events:none sul contenitore, auto sul solo link: la riga di testo
   è larga, e senza questo intercetterebbe il trascinamento della griglia. */
.wipfoot{display:none;}
[data-mvp] .wipfoot{
  position:fixed;
  bottom:64px;                      /* 40 + 24 di respiro in più dal fondo */
  left:50%;
  transform:translateX(-50%);
  /* sopra .bottom-distort (z 88), che in fondo allo schermo sfoca il backdrop
     e ci stende sopra un velo nero fino al 68%: sotto quello il pulsante
     risultava smorzato e fuori fuoco. 210 è la quota della topbar del sito
     completo — stessa convenzione, non un numero a caso. */
  z-index:210;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:14px;
  pointer-events:none;
}
/* la riga dei due comandi: primario + secondario.
   L'altezza è UN numero solo, --wip-h, letto da tutti e due: il primario ci
   costruisce la pillola, il secondario ci fa un cerchio esatto (larghezza =
   altezza). Prima mi affidavo a align-items:stretch + aspect-ratio, ma su un
   flex item la larghezza si calcola dal contenuto prima che lo stretch
   assegni l'altezza — quindi il "quadrato" usciva ovale. Con una misura
   dichiarata non può sbagliare, e cambiandola si muovono insieme. */
[data-mvp] .wipfoot__actions{
  --wip-h:44px;
  display:flex;
  align-items:center;
  gap:10px;
}
[data-mvp] .wipfoot .wipcta,
[data-mvp] .wipfoot .wipsec{pointer-events:auto;}

/* la riga di invito: stessa misura del pulsante ma smorzata, così guida
   l'occhio verso il bianco pieno invece di competerci. */
[data-mvp] .wipfoot__note{
  font-family:var(--font);
  font-size:15px;
  font-weight:var(--w-regular);
  letter-spacing:0;
  line-height:1.2;
  color:rgba(255,255,255,.72);
  text-shadow:0 1px 12px rgba(0,0,0,.55);   /* regge anche su una card chiara */
}

.wipcta{display:none;}
[data-mvp] .wipcta{
  position:relative;                /* la centratura la fa .wipfoot */
  display:inline-flex;
  border-radius:999px;
  background:transparent;
  border:0;
  /* nessun font-size qui: resta il 15px del blocco tipografico condiviso,
     lo stesso della fascia. Due misure diverse per due sole scritte in
     pagina si notavano. */
  /* strato 1 — l'alone, fatto con box-shadow e NON con un elemento sfocato.
     Un `filter:blur()` su un elemento che sta animando viene rasterizzato in
     un layer di composizione, e la sfocatura si taglia netta ai bordi di quel
     layer: si vedeva un rettangolo attorno alla luce. box-shadow non ha un
     riquadro proprio — viene disegnato dal compositore attorno alla forma —
     quindi non può clippare. Sta sul link, il cui fondo è trasparente, così
     l'alone finisce sotto sia all'anello sia alla faccia. */
  box-shadow:
    0 0 24px rgba(255,99,71,.50),
    0 0 60px rgba(255,99,71,.24);
}

/* strato 2 — la luce: un pennello che percorre il perimetro. Gli stop stretti
   fanno una cometa invece di un alone uniforme: è il movimento che si legge,
   non il colore. Bianco al culmine del lampo, accent ai due lati. */
[data-mvp] .wipcta::before{
  content:'';
  position:absolute;
  inset:-1.5px;
  border-radius:inherit;
  background:conic-gradient(from var(--wip-angle),
    rgba(255,99,71,0)    0deg,
    rgba(255,99,71,.95) 68deg,
    #ffffff            104deg,
    rgba(255,99,71,.95) 140deg,
    rgba(255,99,71,0)  208deg,
    rgba(255,99,71,0)  360deg);
  animation:wip-spin 4.5s linear infinite;
}
/* strato 3 — la faccia: copre il centro dell'anello e ne lascia scoperto
   solo il filo esterno. È lei a dare la forma del pulsante. */
[data-mvp] .wipcta__face{
  position:relative;
  z-index:1;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  /* padding proporzionato al testo, non al vuoto: 13/30 su un corpo 15 tiene
     l'altezza sui 44px del target tattile senza far sembrare la scritta persa
     dentro la pillola. Prima era 19/46 — un pulsante grande con dentro un
     testo piccolo. */
  height:var(--wip-h);
  padding:0 30px;                   /* altezza dichiarata: il padding resta solo orizzontale */
  border-radius:inherit;
  /* bombato per davvero. La versione prima andava da #fff a #efeeec: sei punti
     di luminanza, cioè niente — a schermo restava piatta. Qui il salto è di
     ~20 punti e la sfumatura ha tre tappe, non due: il bianco tiene la metà
     alta (la parte che guarda la luce), poi cade in fretta nell'ultimo terzo.
     È quella caduta asimmetrica a leggersi come curvatura; una rampa lineare
     legge sempre come inclinazione piatta.
     Sopra, il filo bianco è il colmo; sotto, l'ombra interna scura è il bordo
     che rientra. Le due esterne staccano la pillola dal fondo. */
  background:linear-gradient(180deg,
    #ffffff 0%,
    #fbfaf9 42%,
    #e6e3de 78%,
    #d2cec7 100%);
  /* La stessa grammatica di bordo del vetro (.glass in style.css), applicata a
     una faccia OPACA. Il vetro e la pillola bianca non sono lo stesso
     materiale — questa è piena, quella è trasparente — ma devono essere
     illuminati dalla STESSA luce, o accanto sembrano ritagliati da due
     immagini diverse.
     Quindi: colmo sopra-sinistra, rientro sotto-destra, filo tutto intorno.
     Gli alfa sono più alti che sul vetro perché una superficie opaca riflette
     di più: sul bianco pieno, gli stessi valori del vetro sparirebbero.
     Niente ombra portata QUI: sotto c'è già l'alone arancione, e due ombre
     sovrapposte si sporcano a vicenda. */
  box-shadow:
    inset 0 0 0 .5px      rgba(0,0,0,.07),
    inset 0 1px 1px       rgba(255,255,255,.9),
    inset 0 -1px 3px -1px rgba(0,0,0,.18);
  color:#0b0b0b;
  font-weight:var(--w-regular);
  transition:background .4s var(--ease-glass),box-shadow .4s var(--ease-glass);
}
/* hover.
   Prima alzavo la SOLA faccia di 2px lasciando fermi anello e alone: su un
   pulsante piccolo la pillola bianca scivolava fuori dal proprio bordo
   luminoso, e si vedeva il disallineamento. E l'anello ingrossava animando
   `inset`, cioè una proprietà di layout: a ogni frame il browser rifaceva la
   geometria dello pseudo-elemento, da cui lo scatto.
   Ora si muove il pulsante INTERO — faccia, anello e alone insieme, quindi
   niente può disallinearsi — e si toccano solo transform e box-shadow, che il
   compositore gestisce senza ricalcolare il layout.
   Da quando la centratura la fa .wipfoot, il transform qui è libero: non
   c'è più nessun translateX(-50%) da ricomporre a ogni stato. */
[data-mvp] .wipcta{
  transition:box-shadow .35s var(--ease),transform .35s var(--ease);
}
[data-mvp] .wipcta:hover{
  transform:translateY(-2px);
  box-shadow:
    0 0 34px rgba(255,99,71,.74),
    0 0 84px rgba(255,99,71,.38);
}
/* alzandosi, la pillola stacca l'ombra da sé: è quello che vende i 2px */
[data-mvp] .wipcta:hover .wipcta__face{
  background:linear-gradient(180deg,
    #ffffff 0%,
    #ffffff 46%,
    #eceae6 80%,
    #dbd7d1 100%);
}

/* ---------- 6c. la firma, sotto tutto ----------
   Una riga sola, piccola e smorzata, ancorata al fondo dello schermo.

   Perché non dentro .wipfoot: quel blocco è centrato e cresce verso l'alto.
   Attaccandoci una terza riga, ad ogni cambio di lingua — dove "Tutti i
   diritti riservati" e "All rights reserved" non hanno la stessa larghezza e
   su schermo stretto vanno a capo un numero diverso di volte — la CTA si
   sarebbe alzata e riabbassata da sola. Ancorata per conto suo, invece, la
   firma vive nei 64px sotto il piede e i due blocchi non si toccano mai:
   .wipfoot parte da bottom:64px, questa sta a 22px.

   pointer-events:none: è una firma, non un comando. Senza, questa riga larga
   intercetterebbe il trascinamento della griglia che le passa sotto — lo
   stesso motivo per cui ce l'ha .wipfoot.

   Niente vetro qui, di proposito: sul fondo dello schermo ci sono già la
   pillola bianca e il tondo LinkedIn. Una terza lastra a 10px di distanza
   sarebbe rumore, e la gerarchia del piede (invito → azione → firma) si
   leggerebbe peggio, non meglio. */
.wipsign{display:none;}
[data-mvp] .wipsign{
  position:fixed;
  bottom:22px;
  left:50%;
  transform:translateX(-50%);
  z-index:210;                      /* stessa quota del piede: sopra .bottom-distort */
  display:flex;
  align-items:center;
  justify-content:center;
  gap:10px;
  padding:0 var(--s16);
  max-width:100%;
  pointer-events:none;
  font-family:var(--font);
  /* 11px e non var(--fs-label): questa riga deve stare SOTTO la soglia
     dell'invito (15px) in modo netto. A 12px competeva. */
  font-size:12px;
  font-weight:var(--w-regular);
  line-height:1;
  white-space:nowrap;
  /* .48 è il punto in cui la riga si legge se la cerchi e scompare se non la
     cerchi. Più su faceva concorrenza alla CTA, più giù spariva sulle card
     chiare. L'ombra la tiene leggibile su qualunque immagine ci scorra sotto,
     come per l'invito qui sopra. */
  color:rgba(255,255,255,.48);
  text-shadow:0 1px 10px rgba(0,0,0,.6);
}
/* i separatori: due punti, non due "·" tipografici. Un carattere dipende dal
   font e dalla sua altezza della x — questi sono cerchi veri, sempre della
   stessa misura e sempre allineati alla mezzeria del testo. */
[data-mvp] .wipsign__dot{
  width:2.5px;height:2.5px;flex:none;
  border-radius:50%;
  background:currentColor;
  opacity:.55;
}
:root[data-theme="light"][data-mvp] .wipsign{
  color:rgba(0,0,0,.42);
  text-shadow:0 1px 10px rgba(255,255,255,.6);
}

/* ---------- 6b. secondario: LinkedIn ----------
   Quadrato con gli angoli pieni, largo quanto è alto, e l'altezza gliela dà
   il flex del contenitore: se un giorno cambi il padding del primario, questo
   lo segue da solo invece di sballare.
   Vetro invece che bianco pieno, e nessun anello luminoso: la gerarchia fra i
   due deve leggersi prima ancora di riconoscere l'icona. */
.wipsec{display:none;}
[data-mvp] .wipsec{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:var(--wip-h);               /* larghezza = altezza → cerchio esatto */
  height:var(--wip-h);
  flex:none;
  border-radius:50%;
  color:rgba(255,255,255,.92);
  /* la superficie la porta .glass (style.css): stessa lastra dello switch
     lingua e del tondo XR. Qui restano solo misura, forma e colore
     dell'icona. Prima questo pulsante aveva una pila di ombre tutta sua —
     più chiara di quella dei comandi in alto — e affiancato alla CTA bianca
     sembrava un terzo materiale. */
}
[data-mvp] .wipsec svg{display:block;flex:none;
  transition:transform .4s var(--ease-glass);}
[data-mvp] .wipsec:hover{
  /* si alza di 2px come la CTA accanto: i due comandi del piede devono
     rispondere con lo stesso gesto, o la riga sembra montata da due pezzi
     diversi. Il translateY sostituisce quello di .glass:hover — stessa
     proprietà, regola più specifica. */
  transform:translateY(-2px);
  color:#fff;
}
[data-mvp] .wipsec:hover svg{transform:scale(1.06);}
[data-mvp] .wipsec:active{transform:translateY(0) scale(.985);}
[data-mvp] .wipsec:focus-visible{outline:2px solid #fff;outline-offset:3px;}

:root[data-theme="light"][data-mvp] .wipsec{color:rgba(0,0,0,.8);}
/* al click torna giù: premere deve dare una risposta fisica */
[data-mvp] .wipcta:active{transform:translateY(0);}
[data-mvp] .wipcta:focus-visible{outline:2px solid #fff;outline-offset:5px;}

/* motion ridotto: la luce resta, ferma. Un bordo sfumato immobile è
   ancora un bel bordo; una cometa che gira per chi soffre di motion
   sickness non lo è. */
@media (prefers-reduced-motion:reduce){
  [data-mvp] .wipcta::before{animation:none;}
}

/* ---------- 7. tema chiaro: stesso vetro invertito del resto del sito ---------- */
/* la fascia non ha override di tema: al 60% l'arancione copre abbastanza da
   reggere il testo bianco anche su fondo chiaro. Un colore di stato, uguale
   nei due temi. */
/* in chiaro il pulsante resta bianco, ma su fondo chiaro perderebbe il
   bordo: una hairline lo tiene staccato senza tradire il "flat". */
/* in chiaro la faccia bianca perderebbe il bordo su fondo chiaro: la hairline
   sta sulla faccia, non sul link, o coprirebbe l'anello luminoso. Va ripetuta
   tutta la pila — box-shadow non si somma fra regole, l'ultima sostituisce. */
:root[data-theme="light"][data-mvp] .wipcta__face{
  box-shadow:
    0 0 0 0.5px rgba(0,0,0,.14),
    inset 0 1.5px 0 rgba(255,255,255,1),
    inset 0 -2px 3px rgba(0,0,0,.18);
}

/* ---------- 8. entrata ----------
   Agganciata a body.is-entered, che il preloader accende quando ha
   finito: la chrome non compare mai sopra il nero, arriva insieme
   alle card. Stessa curva del resto del sito (--ease), nessun
   rimbalzo — la fascia scende, marchio e pulsante salgono di poco.
   `backwards` tiene lo stato iniziale anche durante il ritardo,
   altrimenti si vedrebbero in posizione per una frazione di secondo. */
@keyframes wip-bar-in{
  from{opacity:0;transform:translateY(-100%);}
  to  {opacity:1;transform:none;}
}
@keyframes wip-rise-in{
  from{opacity:0;transform:translateX(-50%) translateY(10px);}
  to  {opacity:1;transform:translateX(-50%);}
}
[data-mvp] body.is-entered .wipbar{animation:wip-bar-in .9s .45s var(--ease) backwards;}
[data-mvp] body.is-entered .wipmark{animation:wip-rise-in 1s .70s var(--ease) backwards;}
/* entra il piede intero — invito e pulsante insieme, come un blocco solo.
   L'animazione sta qui e non sul link perché wip-rise-in porta la centratura
   nel proprio transform, e la centratura ora è di .wipfoot. */
[data-mvp] body.is-entered .wipfoot{animation:wip-rise-in 1s .90s var(--ease) backwards;}
/* la firma entra per ultima, dopo il piede: è l'informazione meno urgente
   della pagina, e arrivare in coda è esattamente ciò che lo dice.
   Riusa wip-rise-in perché anche lei è centrata con translateX(-50%): serve
   che l'animazione se lo porti dietro, o durante la corsa scatterebbe di
   mezza larghezza a destra. */
[data-mvp] body.is-entered .wipsign{animation:wip-rise-in 1s 1.15s var(--ease) backwards;}

/* Lo switch lingua ha un'animazione propria e non wip-rise-in: quella porta
   translateX(-50%) nel transform (serve alla centratura del piede) e qui
   sposterebbe il pulsante di mezza larghezza fuori posto. Entra per ultimo,
   dopo il piede: è un comando di servizio, non parte del messaggio. */
@keyframes lang-in{from{opacity:0;transform:translateY(8px);}to{opacity:1;transform:none;}}
/* `both` invece di `backwards`: a fine corsa lo stato finale resta congelato.
   Con `backwards` l'animazione rilascia l'elemento appena finisce, e ogni
   ricalcolo di stile successivo poteva rimetterla in moto — cliccando IT/EN
   lo switch scivolava giù di 8px e risaliva in un secondo e mezzo, come se
   stesse rientrando in scena ad ogni cambio lingua. */
body.is-entered .topctl{animation:lang-in .8s 1.05s var(--ease) both;}
body:not(.is-entered) .topctl{opacity:0;}
/* L'animazione è d'ingresso: una volta entrata, non deve più ripartire.
   I bottoni cambiano testo ad ogni cambio lingua, e senza questo il
   ricalcolo la riattivava. */
body.is-entered .topctl.is-settled{animation:none;opacity:1;transform:none;}

/* In MVP la fascia arancione occupa tutta la cima della pagina: lo switch
   deve scendere sotto, o le finirebbe addosso.
   Fuori da MVP quella fascia non esiste e vale la posizione di style.css.

   --wipbar-h è l'altezza REALE della fascia, misurata da js/i18n.js e
   riscritta quando cambia lingua, quando ruoti il telefono o quando il font
   finisce di caricare. Serve perché quel testo va a capo un numero diverso
   di volte a seconda di larghezza e lingua: un valore fisso sarebbe giusto
   su un telefono e sbagliato sul successivo.
   Il fallback 48px vale solo per i millisecondi prima che JS misuri.

   Niente env(safe-area-inset-top) qui: la fascia parte da top:0, quindi la
   sua altezza misurata comprende già la zona del notch. Sommarlo di nuovo
   spingerebbe lo switch 40-50px più in basso del dovuto su iPhone. */
[data-mvp] .topctl{
  top:calc(var(--wipbar-h,48px) + 16px);
}

/* Nessun marchio sulla griglia: il logo 3D resta al preloader, dove ha lo
   spazio e il tempo per essere guardato. Sopra le card sarebbe un segno in
   competizione col contenuto — e un contesto WebGL in meno da tenere vivo
   accanto a quello della griglia.
   Il canvas #mvpLogo non viene nemmeno inizializzato (vedi js/main.js). */
[data-mvp] .wipmark{display:none;}

/* prima dell'ingresso non devono esistere: senza questo, chi apre la
   pagina con il preloader già saltato li vedrebbe fermi sullo schermo */
[data-mvp] body:not(.is-entered) .wipbar,
[data-mvp] body:not(.is-entered) .wipmark,
[data-mvp] body:not(.is-entered) .wipfoot,
[data-mvp] body:not(.is-entered) .wipsign{opacity:0;}

/* ---------- 9. mobile ---------- */
@media (max-width:600px){
  [data-mvp] .wipbar{padding:12px var(--s16);}   /* i 15px restano: cala solo il respiro */
  /* niente top fisso qui: sovrascriverebbe la misura reale della fascia con
     un numero tarato su un testo che nel frattempo è cambiato. Su schermo
     stretto basta stringere il distacco da 16 a 12px. */
  [data-mvp] .wipmark{top:calc(var(--wipbar-h,48px) + 12px);}
  [data-mvp] .wipmark canvas{width:46px;height:46px;}
  [data-mvp] .wipfoot{bottom:52px;gap:12px;}        /* 28 + 24, come sul desktop */
  /* la firma sale con il piede e si stringe: a 10px con meno tracking le tre
     voci restano su una riga sola anche sui telefoni più stretti, che è la
     condizione perché resti una firma e non diventi un paragrafo. */
  [data-mvp] .wipsign{bottom:16px;gap:8px;font-size:10px;letter-spacing:.03em;}
  /* una riga sola muove entrambi: la pillola si accorcia e il cerchio si
     rimpicciolisce con lei, restando cerchio */
  [data-mvp] .wipfoot__actions{--wip-h:42px;}
  [data-mvp] .wipcta__face{padding:0 26px;}
}

/* Sotto i 340px (iPhone SE 1ª gen e affini) la riga intera non ci sta più:
   a 320px avanzano ~5px per lato, e il primo device un filo più stretto la
   taglierebbe. Invece di rimpicciolire ancora il testo — sotto i 10px non si
   legge — cade il pezzo ridondante: "Tutti i diritti riservati" è la formula
   di rito, mentre © anno e firma sono l'informazione vera.
   Cade la voce marcata --opt e il suo separatore, o resterebbero due punti
   di fila. Le due classi sono esplicite nel markup e non contate per
   posizione: i figli sono tutti <span>, e un :nth-of-type() conterebbe anche
   i punti finendo sull'elemento sbagliato. */
@media (max-width:340px){
  [data-mvp] .wipsign__item--opt,
  [data-mvp] .wipsign__dot--opt{display:none;}
}

/* ---------- 10. motion ridotto: compaiono, non si muovono ---------- */
@media (prefers-reduced-motion:reduce){
  [data-mvp] body.is-entered .wipbar,
  [data-mvp] body.is-entered .wipmark,
  [data-mvp] body.is-entered .wipfoot,
  [data-mvp] body.is-entered .wipsign{
    animation:wip-fade-in .4s linear backwards;
  }
  @keyframes wip-fade-in{from{opacity:0;}to{opacity:1;}}
  [data-mvp] .wipmark,
  [data-mvp] .wipfoot,
  [data-mvp] .wipsign{transform:translateX(-50%);}
  /* niente sollevamento al passaggio: restano solo alone e schiarita */
  [data-mvp] .wipcta:hover,
  [data-mvp] .wipcta:active,
  [data-mvp] .wipsec:hover,
  [data-mvp] .wipsec:active{transform:none;}
}
