/* ============================================================
   GYZZ — Giovanni Carlini | Personal Trainer
   Design system: mono freddo (ink / ash / bone)
   Zero dipendenze. Animazioni solo su transform + opacity.
   ============================================================ */

/* ---------- 0. CARATTERI ----------------------------- */
/* Anton e Inter stanno nel sito invece che sui server di Google: il testo
   non aspetta piu' due collegamenti in piu' prima di comparire, e chi visita
   non manda il proprio indirizzo IP a Google. Solo l'alfabeto latino (accenti
   italiani compresi). Inter e' un file unico per tutti i pesi; il sito ne usa
   300, 400 e 500, come quando arrivava da Google. I due file sono anche
   precaricati nella <head> delle pagine. */
@font-face{
  font-family: 'Anton';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../assets/fonts/anton-latin.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: 'Inter';
  font-style: normal;
  font-weight: 300 500;
  font-display: swap;
  src: url('../assets/fonts/inter-latin.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;
}

/* ---------- 1. TOKENS -------------------------------- */
:root{
  /* Superfici — freddi. La texture di riferimento vive sullo scarto
     di temperatura: luce fredda, ombra calda. I neri virano al blu,
     il rame resta l'unico caldo della pagina. */
  --ink:        #07090B;
  --charcoal:   #0E1114;
  --graphite:   #171B1F;
  --graphite-2: #1F242A;
  --bone:       #EFF1F3;
  --bone-2:     #E1E5E9;

  /* Grigi freddi. Erano quasi neutri (1-3% di saturazione) mentre i fondi
     ne portano 15-22%: il testo non apparteneva alla stessa luce e leggeva
     piatto. Ora stanno sulla tinta delle superfici (210°), e ogni valore
     tiene la luminanza di prima fino alla quarta cifra — quindi nessun
     rapporto di contrasto gia' verificato si muove di un punto.
     Il fondo banda resta piu' sobrio: una campitura larga mostra la tinta
     molto piu' di quanto faccia una riga di testo. */
  --ash:       #616E7B;  /* decorativo, mai testo                        12% */
  --band:      #7A848E;  /* fondo banda, testo ink 5.23:1                 8% */
  --silver:    #BBC1C7;  /* lettura su fondo scuro 11.01:1               10% */
  --mute:      #8F9BA7;  /* etichette e meta su fondo scuro 7.03:1       12% */
  --mute-deep: #535E69;  /* testo su fondo chiaro 5.85:1                 12% */

  /* Il rosso dell'eroe, portato giu' nella pagina. Serve a dare un battito a
     una tavolozza che e' tutta grigia per scelta, quindi compare solo dove
     segna una posizione o un'azione: il numero della sezione, la riga sotto
     la voce di menu, la freccia che stai per cliccare, i passi gia' fatti nel
     modulo, la domanda aperta, il testo che selezioni. Mai su una campitura
     larga e mai sul pulsante principale: li' smetterebbe di essere un
     dettaglio e diventerebbe il colore del sito.
     Due valori perche' un rosso solo non regge tutt'e due i fondi: quello
     dell'eroe su carta scende a 3.43:1, sotto il minimo per un testo piccolo.
     Stessa logica di --mute / --mute-deep.
     Misurati: pulse 5.60:1 su ink, 5.32 su charcoal, 4.86 su graphite;
     pulse-deep 4.96:1 su bone. Tutti sopra il 4.5 richiesto. */
  --pulse:      #FF3B22;  /* dettagli sui fondi scuri                        */
  --pulse-deep: #C62A12;  /* stesso rosso, sui fondi chiari                  */

  /* Linee */
  --line-on-dark:  rgba(239,241,243,.12);
  --line-on-dark-2:rgba(239,241,243,.22);
  --line-on-light: rgba(7,9,11,.14);
  --line-on-light-2:rgba(7,9,11,.28);

  /* Tipografia */
  --font-display: 'Anton', 'Arial Narrow', Impact, sans-serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  --t-hero:  clamp(2.75rem, 9vw, 8rem);
  --t-xxl:   clamp(2.6rem, 8vw, 7rem);
  --t-xl:    clamp(2.2rem, 5.6vw, 4.8rem);
  --t-lg:    clamp(1.75rem, 3.6vw, 3rem);
  --t-md:    clamp(1.3rem, 2.2vw, 1.85rem);
  /* I tre corpi piccoli erano fissi: su uno schermo largo il testo restava
     della misura che ha sul portatile e la pagina sembrava vuota. Ora salgono
     con la finestra e si fermano dove si ferma la colonna (--shell, 1400px a
     partire da 1556px di finestra): oltre quel punto crescerebbero dentro una
     colonna che non cresce piu'. Il minimo e' il valore di prima, quindi sul
     telefono non cambia niente. */
  --t-body:  clamp(1rem, 1.18vw, 1.1875rem);
  --t-small: clamp(.9375rem, 1.12vw, 1.0625rem);
  --t-kicker:clamp(.6875rem, .82vw, .8125rem);

  /* Spazio */
  --shell: min(90vw, 1400px);
  /* Ripiego e basta: la misura vera la scrive uno script subito dopo la nav,
     prima che la pagina compaia (index.html). Prima la scriveva main.js a
     pagina gia' disegnata, e la prima schermata scendeva di 13-25px. */
  --nav-h: 4.5rem;
  --gutter: clamp(1.25rem, 5vw, 5rem);
  --section-y: clamp(5.5rem, 12vw, 11rem);
  /* Su telefono il minimo del clamp vinceva sempre: 88px sopra e sotto per
     nove sezioni fanno 1584px di solo respiro. */
  --stack: clamp(1.5rem, 3vw, 2.5rem);

  /* Movimento */
  --ease:      cubic-bezier(.22, 1, .36, 1);
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --dur-fast:  .2s;
  --dur:       .45s;
  --dur-slow:  .9s;

  /* Livelli */
  --z-base: 1;
  --z-sticky: 10;
  --z-nav: 20;
  --z-fab: 30;
  --z-progresso: 40;   /* sopra la nav: la barra non deve interrompersi */
  --z-overlay: 50;

  /* Grana: SVG inline, ~1kb, nessuna richiesta di rete */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}

@media (max-width: 700px){
  :root{ --section-y: 2.75rem; }
}

/* ---------- 2. RESET --------------------------------- */
*, *::before, *::after{ box-sizing: border-box; }

html{
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
}

body{
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: 1.7;
  font-weight: 300;
  letter-spacing: .005em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

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

h1, h2, h3, h4{ margin: 0; font-weight: 400; }
p{ margin: 0; }
ul, ol{ margin: 0; padding: 0; list-style: none; }

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

button, input, textarea, select{
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  margin: 0;
}
button{ cursor: pointer; }

/* Il rosso scuro perche' questo fondo deve reggere il testo chiaro sopra:
   5.13:1, mentre il rosso chiaro darebbe 3.08:1. */
::selection{ background: var(--pulse-deep); color: var(--bone); }


/* Focus visibile e coerente ovunque */
:focus-visible{
  outline: 2px solid var(--bone);
  outline-offset: 3px;
  border-radius: 2px;
}
.on-light :focus-visible{ outline-color: var(--ink); }

/* Skip link */
.skip{
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: var(--z-overlay);
  background: var(--bone);
  color: var(--ink);
  padding: .875rem 1.25rem;
  font-size: var(--t-small);
  font-weight: 500;
}
.skip:focus{ left: 1rem; top: 1rem; }

/* ---------- 3. TIPOGRAFIA ---------------------------- */
.display{
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  line-height: .92;
  letter-spacing: .005em;
  text-wrap: balance;
}

.kicker{
  font-family: var(--font-body);
  font-size: var(--t-kicker);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .26em;
  line-height: 1.4;
  color: var(--mute);
}
.on-light .kicker,
.kicker--dark{ color: var(--mute-deep); }

/* Le due cifre davanti al titolo di sezione. Sono l'unico segno che si
   ripete identico sei volte scendendo: colorarle da' alla pagina un battito
   regolare senza toccare niente di quello che si legge. */
.pulse{ color: var(--pulse); }
.on-light .pulse{ color: var(--pulse-deep); }

.lede{
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
  line-height: 1.6;
  font-weight: 300;
  max-width: 46ch;
}

.muted{ color: var(--silver); }
.on-light .muted{ color: var(--mute-deep); }

.measure{ max-width: 62ch; }

/* ---------- 4. LAYOUT -------------------------------- */
.shell{
  width: var(--shell);
  margin-inline: auto;
}

.section{
  position: relative;
  padding-block: var(--section-y);
}

.on-dark{ background: var(--ink); color: var(--bone); }
.on-light{ background: var(--bone); color: var(--ink); }

/* Risultati sta sul carbone, uno scalino sopra il nero. E' nato quando
   Risultati e Contatti erano due scure di fila; ora fra loro c'e' Chi sono,
   ma lo scalino resta: distingue le foto prima/dopo dal resto delle scure.
   Contatti resta sul nero perche' la sua scheda della form e' gia' carbone
   e sullo stesso fondo sparirebbe. */
.on-dark--2{ background: var(--charcoal); }


/* Grana su tutte le superfici scure */
.on-dark::before{
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--grain);
  /* Niente mix-blend-mode: una fusione di colori sopra sezioni intere, che
     scorrono e si sovrappongono, il browser la rifa' a ogni fotogramma (su
     Safari pesava). Senza, a questa opacita' la grana resta la stessa. */
  opacity: .025;
  pointer-events: none;
}

/* La testa di ogni sezione: occhiello, titolo, paragrafo d'attacco. Prima
   la usavano due sezioni su sei e le altre quattro si arrangiavano con
   margini scritti a mano nel tag: da li' i tre stacchi diversi fra titolo e
   testo (40, 48 e 76 px) che facevano sembrare l'impaginazione casuale.
   Ora la struttura e' una sola e il ritmo esce uguale ovunque. */
.section-head{
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}
/* Il paragrafo respira piu' del titolo: e' il gradino che separa il nome
   della sezione da quello che ha da dire. */
.section-head .lede{ margin-top: .75rem; }
/* Nelle sezioni a due colonne la testa non ha niente sotto di se': lo
   stacco lo fa la colonna accanto, e quel margine lascerebbe solo un buco
   in fondo alla colonna. */
.faq__grid > .section-head,
.cta__grid > .section-head{ margin-bottom: 0; }

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


/* ---------- 5. BOTTONI ------------------------------- */
.btn{
  --btn-fg: var(--ink);
  --btn-bg: var(--bone);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .75rem;
  min-height: 3rem;
  padding: .875rem 1.75rem;
  font-size: var(--t-small);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--btn-fg);
  background: var(--btn-bg);
  border: 1px solid var(--btn-bg);
  border-radius: 999px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
/* Riempimento che sale dal basso: solo transform, zero reflow */
.btn::after{
  content: "";
  position: absolute;
  inset: 0;
  background: var(--btn-fg);
  transform: translate3d(0, 101%, 0);
  transition: transform var(--dur) var(--ease);
  z-index: -1;
}
.btn:hover::after,
.btn:focus-visible::after{ transform: translate3d(0, 0, 0); }
.btn:hover, .btn:focus-visible{ color: var(--btn-bg); }

.btn--ghost{
  --btn-bg: transparent;
  --btn-fg: var(--bone);
  color: var(--bone);
  border-color: var(--line-on-dark-2);
}
.btn--ghost::after{ background: var(--bone); }
.btn--ghost:hover, .btn--ghost:focus-visible{ color: var(--ink); border-color: var(--bone); }

.on-light .btn--ghost{
  --btn-fg: var(--ink);
  color: var(--ink);
  border-color: var(--line-on-light-2);
}
.on-light .btn--ghost::after{ background: var(--ink); }
.on-light .btn--ghost:hover,
.on-light .btn--ghost:focus-visible{ color: var(--bone); border-color: var(--ink); }

.btn--dark{ --btn-bg: var(--ink); --btn-fg: var(--bone); color: var(--bone); }

/* Link con freccia (reference: "READ OUR STORY ->") */
.link-arrow{
  display: inline-flex;
  align-items: center;
  gap: .75rem;
  min-height: 2.75rem;
  font-size: var(--t-kicker);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .2em;
  padding-bottom: .5rem;
  border-bottom: 1px solid var(--line-on-dark-2);
  transition: border-color var(--dur) var(--ease), gap var(--dur) var(--ease);
}
.link-arrow svg{ width: 1.125rem; height: auto; flex: none; transition: transform var(--dur) var(--ease); }
/* Sono i punti da cui si entra nel modulo: "Parliamone" e i tre "Richiedi il
   piano" sulle schede. Al passaggio si vede quale hai preso. */
.link-arrow:hover, .link-arrow:focus-visible{ color: var(--pulse); border-color: currentColor; }
.on-light .link-arrow:hover,
.on-light .link-arrow:focus-visible{ color: var(--pulse-deep); }
.link-arrow:hover svg, .link-arrow:focus-visible svg{ transform: translate3d(.35rem, 0, 0); }
.on-light .link-arrow{ border-bottom-color: var(--line-on-light-2); }

/* ---------- 6. REVEAL ALLO SCROLL -------------------- */
/* Stato di partenza applicato solo se JS e' attivo: no-JS vede tutto */
.js [data-reveal]{
  opacity: 0;
  transform: translate3d(0, 1.75rem, 0);
  transition:
    opacity var(--dur-slow) var(--ease),
    transform var(--dur-slow) var(--ease);
  transition-delay: calc(var(--i, 0) * 90ms);
  /* Niente will-change qui: su una pagina lunga significherebbe centinaia di
     layer promossi contemporaneamente. opacity e transform sono gia'
     accelerati, il livello lo crea il browser solo durante la transizione. */
}
.js [data-reveal].is-in{
  opacity: 1;
  transform: none;
}
.js [data-reveal="mask"]{ transform: translate3d(0, 2.5rem, 0) scale(1.02); }
.js [data-reveal="fade"]{ transform: none; }

/* Titoli che salgono riga per riga da una maschera */
.line-mask{ display: block; overflow: hidden; }
.line-mask > span{ display: block; }
/* Le maiuscole accentate (È, Ù...) di Anton salgono .24em sopra le altre,
   e la riga e' stretta a .92: la maschera tagliava l'accento, e "È una
   domanda" si leggeva "E UNA DOMANDA". La riga che ne ha una prende sopra
   lo spazio dell'accento, e fra le righe resta lo stesso respiro. Lo spazio
   sta sulla <span>: dove il testo e' dipinto da un gradiente
   (background-clip) l'accento fuori dalla <span> resterebbe trasparente. */
.line-mask--accento > span{ padding-top: .24em; }
.js .line-mask > span{
  transform: translate3d(0, 105%, 0);
  transition: transform 1s var(--ease);
  transition-delay: calc(var(--i, 0) * 110ms);
}
.js .is-in .line-mask > span,
.js .line-mask.is-in > span{ transform: none; }

/* ---------- 7. PLACEHOLDER MEDIA --------------------- */
/* I file foto/video arriveranno dopo: il markup e' gia' definitivo.
   Finche' il file non esiste si vede un segnaposto art-directed,
   non un'immagine rotta. Appena il file viene caricato sparisce da solo. */
.media{
  position: relative;
  overflow: hidden;
  background: var(--graphite);
  isolation: isolate;
}
.media::before{
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(
      -45deg,
      rgba(239,241,243,.035) 0 1px,
      transparent 1px 11px
    ),
    linear-gradient(160deg, var(--graphite-2), var(--charcoal) 70%);
  z-index: 0;
}
.media::after{
  content: attr(data-slot);
  position: absolute;
  left: 1rem;
  bottom: 1rem;
  z-index: 1;
  font-size: var(--t-kicker);
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(239,241,243,.34);
  pointer-events: none;
}
/* <picture> porta la versione WebP: deve sparire dal disegno, cosi' l'img
   misura e si posiziona come se fosse figlia diretta del riquadro. */
.media picture{ display: contents; }
.media img,
.media video{
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .7s var(--ease);
}
.media img.is-loaded,
.media video.is-loaded{ opacity: 1; }
.media img.is-missing,
.media video.is-missing{ display: none; }

/* Trattamento B/N coerente su tutta la fotografia. Nelle foto (prima e
   dopo, Chi sono) e' gia' dentro i file: un filtro applicato dal browser si
   ricalcola mentre le sezioni scorrono una sopra l'altra, e su Safari si
   sentiva. Resta solo sull'eroe, che e' il video. */
.hero__media.media--bw img,
.hero__media.media--bw video{
  filter: grayscale(1) contrast(1.08) brightness(.96);
}

.media--3x4{ aspect-ratio: 3 / 4; }
.media--1x1{ aspect-ratio: 1 / 1; }
.media--4x3{ aspect-ratio: 4 / 3; }
.media--16x9{ aspect-ratio: 16 / 9; }

/* ---------- 8. NAV ----------------------------------- */
/* Fissa, fuori dal flusso della pagina. Era sticky, quindi occupava posto:
   quando si stringe (is-stuck, 16px in meno) spostava in su tutto il sito
   mentre scorrevi, e un link a una sezione arrivava nel punto sbagliato. */
.nav{
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.25rem var(--gutter);
  background: rgba(7,9,11,.72);
  backdrop-filter: blur(14px) saturate(1.1);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  border-bottom: 1px solid transparent;
  transition:
    padding var(--dur) var(--ease),
    background var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
}
.nav.is-stuck{
  padding-block: .75rem;
  background: rgba(7,9,11,.94);
  border-bottom-color: var(--line-on-dark);
}

.brand{
  min-height: 2.75rem;
  font-family: var(--font-display);
  font-size: 1.5rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  gap: .55rem;
}
.brand__mark{ color: var(--bone); }
.brand__sub{
  font-family: var(--font-body);
  font-size: var(--t-kicker);
  font-weight: 400;
  letter-spacing: .2em;
  color: var(--mute);
}
@media (max-width: 560px){ .brand__sub{ display: none; } }

.nav__links{
  display: flex;
  align-items: center;
  gap: clamp(1.25rem, 2.6vw, 2.5rem);
  font-size: var(--t-kicker);
  font-weight: 500;
  letter-spacing: .2em;
  text-transform: uppercase;
}
.nav__links a{
  position: relative;
  display: inline-block;
  padding-block: .625rem;
  color: var(--mute);
  transition: color var(--dur-fast) var(--ease);
}
.nav__links a::after{
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  /* Era currentColor, cioe' lo stesso bianco del testo sopra: la riga si
     vedeva appena. In rosso il menu risponde al passaggio. */
  background: var(--pulse);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.nav__links a:hover, .nav__links a:focus-visible{ color: var(--bone); }
.nav__links a:hover::after, .nav__links a:focus-visible::after{ transform: scaleX(1); }

.nav__cta{ display: inline-flex; }
/* Il CTA dentro la lista serve solo al menu mobile: su desktop sarebbe un doppione */
.nav__links > .btn{ display: none; }

.nav__burger{
  display: none;
  width: 2.75rem;
  height: 2.75rem;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 5px;
}
.nav__burger span{
  display: block;
  width: 22px;
  height: 1.5px;
  background: var(--bone);
  transition: transform var(--dur) var(--ease), opacity var(--dur-fast) var(--ease);
}
.nav__burger[aria-expanded="true"] span:nth-child(1){ transform: translateY(6.5px) rotate(45deg); }
.nav__burger[aria-expanded="true"] span:nth-child(2){ opacity: 0; }
.nav__burger[aria-expanded="true"] span:nth-child(3){ transform: translateY(-6.5px) rotate(-45deg); }

@media (max-width: 900px){
  /* backdrop-filter renderebbe la nav un blocco contenitore per i figli
     position:fixed: il pannello del menu si dimensionerebbe sulla nav
     invece che sul viewport, restando visibile a meta' schermo.
     Su mobile si rinuncia al vetro e si usa un velo semplice. */
  .nav{
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: rgba(7,9,11,.6);
  }
  .nav.is-stuck{ background: rgba(7,9,11,.96); }

  .nav__burger{ display: flex; }
  .nav__cta{ display: none; }
  .nav__links{
    position: fixed;
    inset: 0;
    flex-direction: column;
    justify-content: center;
    gap: 1.75rem;
    background: var(--ink);
    font-size: 1.125rem;
    letter-spacing: .18em;
    transform: translate3d(0, -100%, 0);
    transition: transform .6s var(--ease);
    z-index: -1;
  }
  .nav__links.is-open{ transform: none; }
  .nav__links a{
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    color: var(--bone);
  }
  .nav__links > .btn{ display: inline-flex; margin-top: .5rem; }
  body.is-locked{ overflow: hidden; }
}

/* Un link interno porta il fuoco sulla sezione (main.js, linkInterni):
   serve a chi poi prosegue col Tab, non va disegnato. */
#main > section:focus{ outline: none; }

/* ---------- 9. HERO ---------------------------------- */
.hero{
  position: relative;
  min-height: clamp(620px, 100svh, 1040px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--ink);
  padding-top: var(--nav-h);            /* la nav fissa sta sopra il video */
}
.hero__media{
  position: absolute;
  inset: 0;
  z-index: 0;
}
.hero__media img,
.hero__media video{
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Doppio velo: leggibilita' garantita a prescindere dal video caricato */
.hero__veil{
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* Un solo strato, non due sovrapposti. Due veli all'85% e al 72% si
     compongono al 96%: molto piu' di quanto serva a far passare i contrasti,
     ed e' li' che si perdeva il video. Questo e' calibrato sul minimo. */
  background: linear-gradient(to top,
    rgba(7,9,11,.93) 0%,
    rgba(7,9,11,.88) 30%,
    rgba(7,9,11,.86) 70%,
    rgba(7,9,11,.91) 100%);
}
@media (min-width: 900px){
  /* Da qui la colonna di testo sta sotto meta' schermo: la schermatura passa
     sull'asse orizzontale e la meta' destra resta libera, dove non c'e'
     niente da leggere e il video puo' finalmente vedersi. */
  .hero__veil{
    background:
      /* Tenuta piena fino al 56%: la riga piu' lunga del titolo arriva al 59%
         della larghezza, misurata sulle lettere e non sulla scatola. */
      linear-gradient(to right,
        rgba(7,9,11,.90) 0%,
        rgba(7,9,11,.88) 56%,
        rgba(7,9,11,.42) 74%,
        rgba(7,9,11,0)   88%),
      linear-gradient(to top,
        rgba(7,9,11,.78) 0%,
        rgba(7,9,11,.30) 42%,
        rgba(7,9,11,.24) 70%,
        rgba(7,9,11,.46) 100%);
  }
}
.hero__inner{
  position: relative;
  z-index: 2;
  width: var(--shell);
  margin-inline: auto;
  /* Il blocco riempie l'hero e distribuisce lo spazio libero in due punti:
     sopra il kicker e sopra i bottoni, meta' per ciascuno. Lo spazio sopra
     resta identico a quando il blocco era centrato, quindi la copy non si
     muove: scendono solo i pulsanti, fino al bordo inferiore.
     Margini automatici e non justify-content: se lo spazio diventa negativo
     si azzerano da soli e il titolo non finisce sotto la nav, irraggiungibile. */
  flex: 1;
  display: flex;
  flex-direction: column;
  padding-block: clamp(1.75rem, 4vw, 3.25rem) clamp(2.25rem, 5vw, 3.75rem);
}
/* Sul video il grigio attenuato non regge: sopra un fotogramma chiaro il
   contrasto crolla sotto 2:1. Nell'hero il kicker va in chiaro pieno. */
.hero__kicker{ margin-top: auto; margin-bottom: clamp(1.25rem, 3vw, 2rem); color: var(--bone); }
/* Sul telefono resta solo "Personal Trainer": la riga intera misura 355px e
   sotto i ~403px di viewport andrebbe a capo. Soglia 560px, la stessa gia'
   usata per il sottotitolo del marchio, cosi' copre ogni telefono in
   verticale senza toccare i tablet, dove lo spazio c'e'. */
@media (max-width: 560px){
  .hero__kicker__extra{ display: none; }
}
.hero__title{
  font-size: var(--t-hero);
  margin-bottom: clamp(1.25rem, 2.5vw, 1.75rem);
  max-width: 16ch;
}
/* Una luce sola attraversa tutta l'intestazione, un verso dopo l'altro: il
   ritardo di ogni riga la fa scendere in diagonale invece di accendersi tutta
   insieme. Il gradiente sta sulla <span> interna e non sulla .line-mask perche'
   e' la <span> a traslare durante la comparsa: cosi' lo sfondo viaggia col
   testo invece di restare indietro lasciandolo trasparente.
   Misurato sul video, 12 fotogrammi, alla larghezza dove l'inchiostro arriva
   piu' a destra: il fondo peggiore sotto le tre righe sta a 0.0212 / 0.0121 /
   0.0121 di luminanza. La tappa piu' scura di ogni riga tiene quindi 8.12:1
   sulle prime due e 5.97:1 sulla terza, sopra il 4.5 richiesto anche
   nell'istante peggiore dell'animazione.
   E' l'unico punto dove il sito anima qualcosa che non sia transform od
   opacity; il browser smette di dipingerlo appena l'intestazione esce dallo
   schermo. */
.hero__title .line-mask > span{
  --luce-fondo: var(--silver);
  --luce-mezzo: #D9DEE2;
  background: linear-gradient(100deg,
    var(--luce-fondo) 0%, var(--luce-mezzo) 30%, var(--bone) 46%, #FFFFFF 50%,
    var(--bone) 54%, var(--luce-mezzo) 70%, var(--luce-fondo) 100%);
  background-size: 250% 100%;
  background-position: 50% 0;   /* senza animazione la luce resta al centro */
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  animation: passaggioLuce 7s var(--ease-in-out) infinite;
  animation-delay: calc(var(--i, 0) * .6s);
}
/* Il verso in sordina parte da piu' in basso e resta il piu' scuro dei tre
   anche dopo che la luce e' passata: la gerarchia dell'intestazione regge. */
.hero__title .line-mask:last-child > span{
  --luce-fondo: var(--mute);
  --luce-mezzo: #A9B4BE;
}
.hero__title em{ font-style: normal; }
/* La luce passa, poi lascia respirare: il ritorno e' fuori campo. */
@keyframes passaggioLuce{
  0%       { background-position: 120% 0; }
  55%, 100%{ background-position: -20% 0; }
}
.hero__sub{ margin-bottom: clamp(1.5rem, 3vw, 2.25rem); }
/* Due margini auto, uno qui e uno sopra il primo blocco: lo spazio libero si
   divide in parti uguali e la coppia parole+pulsanti resta centrata nell'eroe.
   Preferiti a justify-content: center perche' se un giorno il contenuto
   diventasse piu' alto dell'eroe i margini auto valgono zero, mentre la
   centratura del flex spingerebbe il bordo alto fuori e lo renderebbe
   irraggiungibile. */
.hero__inner > *:first-child{ margin-top: auto; }
.hero__actions{
  margin-bottom: auto;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;
}
/* Da desktop i due pulsanti scendono sulla riga di "SCORRI", stesso bordo
   di sotto. La spia dello scroll e' agganciata al fondo dell'eroe, i
   pulsanti al fondo della colonna interna, che finisce piu' in alto di
   tutta la sua spaziatura di sotto: il margine e' la differenza fra le due,
   e resta esatta a ogni larghezza perche' segue gli stessi due clamp.
   Il margine di sopra resta automatico: lo spazio libero si divide a meta'
   fra sopra il titolo e sotto, come prima, e il titolo non si sposta se non
   di una ventina di pixel. Sotto i 1024px la spia e' nascosta e non c'e'
   niente a cui allinearsi: li' vale la regola di sopra. */
@media (min-width: 1024px){
  .hero__actions{
    margin-top: auto;
    margin-bottom: calc(clamp(3.5rem, 8vw, 7rem) - clamp(2.25rem, 5vw, 3.75rem));
  }
}

/* Indicatore di scroll */
.scroll-hint{
  position: absolute;
  right: var(--gutter);
  bottom: clamp(3.5rem, 8vw, 7rem);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .75rem;
  font-size: var(--t-kicker);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--mute);
  writing-mode: vertical-rl;
}
.scroll-hint::after{
  content: "";
  width: 1px;
  height: 3.5rem;
  background: linear-gradient(to bottom, var(--mute), transparent);
  animation: scrollPulse 2.4s var(--ease-in-out) infinite;
  transform-origin: top;
}
@keyframes scrollPulse{
  0%, 100%{ transform: scaleY(.3); opacity: .3; }
  50%     { transform: scaleY(1);  opacity: 1; }
}
@media (max-width: 900px){ .scroll-hint{ display: none; } }

/* Due sezioni scure di fila hanno bisogno di un filo che le separi */
.on-dark + .on-dark{ border-top: 1px solid var(--line-on-dark); }

/* ---------- 10. CHI SONO (principio + persona) -------- */
/* Titolo a sinistra e alla misura degli altri titoli di sezione (--t-xl):
   centrato e piu' grande sembrava un secondo eroe. */
.manifesto__title{
  font-size: var(--t-xl);
  max-width: 20ch;
}
/* Lo stesso passaggio, rovesciato: qui il fondo e' chiaro, quindi la luce
   che attraversa il verso e' scura. Nessuna tappa e' piu' chiara di
   --mute-deep, il colore di prima: anche qui il contrasto puo' solo salire. */
/* Il gradiente va sullo <span> dentro la line-mask, non sulla line-mask.
   Stava sulla line-mask e la riga non si vedeva affatto: il testo appartiene
   al figlio, quindi il ritaglio sul testo non trovava niente da ritagliare e
   restava solo il color:transparent ereditato. Nell'hero lo stesso effetto era
   gia' scritto cosi', sullo span interno; qui era rimasto indietro. */
/* Il verso centrale del manifesto porta il rosso dell'eroe dentro la
   sezione chiara. Resta il passaggio di luce di prima — stessa forma, stessi
   tempi — ma in rosso invece che in grigio: sono le uniche parole colorate
   di tutta la pagina insieme a quelle dell'eroe, e le lega.
   Il rosso e' quello dell'eroe alle due estremita' (#FF1A1A) e scende verso
   il centro, dove passa la banda scura. Su carta chiara il minimo per un
   testo di questa misura e' 3:1: la tappa piu' chiara sta a 3.43:1, il
   centro a 8.20:1. Il rosso caldo dell'eroe (#FF5A2B) qui non entra: su
   fondo bone sarebbe 2.75:1, sotto la soglia. */
.manifesto__title .dim > span{
  background: linear-gradient(100deg,
    #FF1A1A 0%, #E5321A 30%, #A8240F 46%, #8A1D0C 50%,
    #A8240F 54%, #E5321A 70%, #FF1A1A 100%);
  background-size: 250% 100%;
  background-position: 50% 0;   /* senza animazione la luce resta al centro */
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  animation: passaggioLuce 6s var(--ease-in-out) infinite;
}
/* Il principio e Chi sono sono una sezione sola. Sotto il titolo foto e
   testo vanno affiancati: impilati come prima, con tutto quello che c'e' ora
   da dire, la sezione diventava lunga il doppio. Cosi' sta in una schermata. */
.manifesto__grid{
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
}
@media (min-width: 800px){
  .manifesto__grid{ grid-template-columns: minmax(0, 4fr) minmax(0, 6fr); }
}
.manifesto__figure{
  width: min(340px, 70vw);
  margin: 0 auto;                    /* dentro la griglia non serve piu' staccarlo da sopra */
}
@media (min-width: 800px){
  .manifesto__figure{ margin: 0; width: 100%; }
}
.manifesto__nome{
  font-family: var(--font-display);
  font-size: var(--t-lg);
  line-height: 1.05;
}
.manifesto__ruolo{
  margin-top: .35rem;
  font-size: var(--t-kicker);
  text-transform: uppercase;
  letter-spacing: .18em;
  color: var(--mute-deep);
}
.manifesto__body{
  margin: clamp(1.25rem, 2.5vw, 1.75rem) 0 0;
  max-width: 54ch;
  color: #343B3F;
}
/* Le parole chiave: nero pieno e un peso in piu'. Chi scorre senza leggere
   prende quelle, e da sole devono gia' dire la promessa. */
.manifesto__body strong{
  font-weight: 600;
  color: var(--ink);
}
/* I tre dati in fila: sono la prova, non un elenco da leggere riga per riga. */
.manifesto__dati{
  list-style: none;
  margin: clamp(1.75rem, 3vw, 2.25rem) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  border-top: 1px solid var(--line-on-light);
  padding-top: clamp(1.25rem, 2.5vw, 1.5rem);
}
.manifesto__dati li{
  font-size: var(--t-small);
  color: var(--mute-deep);
  line-height: 1.35;
}
.manifesto__dati b{
  display: block;
  font-family: var(--font-display);
  font-size: var(--t-md);
  font-weight: 400;
  color: var(--ink);
}
.manifesto__azione{ margin-top: clamp(1.5rem, 3vw, 2rem); }

/* ---------- 11. METODO (la fila delle tre fasi) ------ */
/* Riproduce il componente "timeline" (components/ui/timeline.tsx) senza
   React e senza GSAP. Lo stesso markup ha tre disposizioni:
     - di base, una linea verticale con le tre fasi in colonna, tutta
       ferma e gia' disegnata. E' quella che resta senza JS o con "riduci
       animazioni";
     - .tl--colonna, la stessa colonna sul telefono: la sezione si ferma e
       la linea scende mentre continui a scorrere;
     - .tl--orizzontale, sugli schermi larghi: la sezione si blocca e la
       fila scorre di lato mentre scendi.
   Le ultime due le mette il JS.
   Il JS scrive quattro numeri da 0 a 1: --linea sulla sezione, --stelo,
   --punto e --testo su ogni fase. Il ripiego di tutti e quattro e' 1, cioe'
   tutto gia' disegnato: se il JS non arriva, non resta niente di nascosto. */
.tl{ --nome: clamp(1.75rem, 2.6vw, 2.75rem); }

.tl__fila{
  width: var(--shell);
  margin-inline: auto;
}
.tl__titolo{ font-size: var(--t-xl); }
.tl__testa-su{
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.tl__corso{
  position: relative;
  padding-left: 2.25rem;
}

/* La linea: un binario grigio e, sopra, il rosso che si allunga. E' il
   rosso delle parole dell'eroe, come la barra di avanzamento: un filo di
   1px resta un dettaglio anche a tutta lunghezza. */
.tl__linea{
  position: absolute;
  top: calc(var(--nome) * .475);
  bottom: 0;
  left: .375rem;
  width: 1px;
  background: var(--line-on-dark-2);
}
.tl__linea-pieno{
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, #FF1A1A, #E5321A);
  box-shadow: 0 0 10px rgba(255, 26, 26, .45);
  transform-origin: top;
  transform: scaleY(var(--linea, 1));
}
/* I due capi: da dove parte e dove arriva. In colonna il capo di partenza
   cadrebbe sotto il punto della prima fase, quindi si vede solo l'arrivo. */
.tl__linea::before,
.tl__linea::after{
  content: "";
  position: absolute;
  left: 50%;
  width: .5625rem;
  height: .5625rem;
  border-radius: 50%;
  background: #FF1A1A;
  transform: translate(-50%, -50%);
}
.tl__linea::before{ display: none; top: 0; }
.tl__linea::after{ top: 100%; }

.tl__tappe{
  display: flex;
  flex-direction: column;
  gap: clamp(2.25rem, 6vw, 3.5rem);
  padding-bottom: 1.5rem;
}
.tl__tappa{ position: relative; }
.tl__stelo{ display: none; }
/* Il punto sta sul binario, all'altezza del centro del nome. */
.tl__punto{
  position: absolute;
  left: calc(.375rem + .5px - 2.25rem);
  top: calc(var(--nome) * .475);
  width: .875rem;
  height: .875rem;
  border-radius: 50%;
  background: #FF1A1A;
  box-shadow: 0 0 12px rgba(255, 26, 26, .5);
  transform: translate(-50%, -50%) scale(var(--punto, 1));
}

.tl__nome{
  font-family: var(--font-display);
  font-size: var(--nome);
  line-height: .95;
  text-transform: uppercase;
  letter-spacing: .01em;
}
/* Il numero ha il contorno dei vecchi numeri del Metodo: si legge come
   segno d'ordine, e il nome accanto resta la cosa piena. */
.tl__num{
  margin-right: .2em;
  color: rgba(106, 120, 135, .16);
  -webkit-text-stroke: 1px var(--ash);
}
.tl__frase{
  margin-top: .875rem;
  max-width: 30ch;
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
  line-height: 1.5;
  color: var(--silver);
}
/* Il testo sale da una maschera, come le righe di SplitText nell'originale.
   La frase usa un tragitto piu' lungo dello stesso numero: parte un attimo
   dopo il nome e arriva insieme a lui. */
.tl__maschera{ display: block; overflow: hidden; }
.tl__maschera > span{
  display: block;
  transform: translate3d(0, calc((1 - var(--testo, 1)) * 105%), 0);
}
.tl__frase .tl__maschera > span{
  transform: translate3d(0, calc((1 - var(--testo, 1)) * 140%), 0);
}

/* ---- In colonna e di lato (classi messe dal JS) ---- */
@media screen{
  /* Sul telefono la linea si disegnava solo mentre la sezione entrava:
     circa 300px di scroll, e un colpo di pollice la saltava tutta. Ora lo
     schermo si ferma e sotto di lui la sezione si allunga di 1,6 schermate
     (erano 0,8, e la linea si disegnava ancora troppo in fretta):
     e' la strada su cui la linea scende, con il contenuto immobile.
     Il valore e' in svh perche' non cambi quando il telefono nasconde la
     barra dell'indirizzo: la sezione cambierebbe altezza mentre scorri. */
  .tl.tl--colonna{ padding-block: 0; }
  .impila main > section.tl.tl--colonna{
    display: block;
    align-content: normal;
  }
  /* Lo schermo si ferma sotto la nav, non sotto il bordo del telefono:
     prima l'occhiello "01 — Il metodo" e la prima riga del titolo finivano
     dietro la nav, e il blocco non era centrato nello spazio che si vede.
     Il resto e' piu' raccolto perche' tutto stia in quello spazio. */
  .tl--colonna .tl__schermo{
    position: sticky;
    /* La nav se il contenuto ci sta; se e' piu' alto, il JS lo ferma
       quando ne mostra il fondo, cioe' le fasi (--fermo, negativo). */
    top: calc(var(--nav-h, 0px) + var(--fermo, 0px));
    min-height: calc(100vh - var(--nav-h, 0px));
    min-height: calc(100svh - var(--nav-h, 0px));
    padding-block: 1rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  .tl--colonna .tl__testa{ margin-bottom: 1.5rem; }
  .tl--colonna .tl__tappe{
    gap: 1.375rem;
    padding-bottom: .75rem;
  }
  .tl--colonna::after{
    content: "";
    display: block;
    height: 160vh;
    height: 160svh;
  }

  /* La sezione diventa alta quanto lo schermo piu' la strada che la fila
     deve fare di lato: --corsa la scrive il JS. */
  .tl.tl--orizzontale{
    padding-block: 0;
    height: calc(100vh + var(--corsa, 0px));
    height: calc(100svh + var(--corsa, 0px));
  }
  /* Le sezioni impilate sono una griglia centrata: qui centrerebbe lo
     schermo bloccato a meta' sezione. Non basta tornare a block: i browser
     recenti applicano align-content anche ai blocchi, e lo schermo finiva
     548px piu' in basso. Va spento anche quello. */
  .impila main > section.tl.tl--orizzontale{
    display: block;
    align-content: normal;
  }

  .tl--orizzontale .tl__schermo{
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100svh;
    padding-top: var(--nav-h);
    overflow: hidden;
    display: flex;
    align-items: center;
  }
  .tl--orizzontale .tl__fila{
    position: relative;
    flex: none;
    display: flex;
    width: max-content;
    height: clamp(26rem, 64vh, 42rem);
    margin: 0;
    /* Il margine e' quello della colonna del sito, cosi' all'inizio il
       titolo sta dove stanno tutti gli altri e alla fine l'ultima fase
       si ferma sul bordo destro della colonna. */
    padding-inline: calc((100% - var(--shell)) / 2);
    transform: translate3d(var(--sposta, 0px), 0, 0);
    will-change: transform;
  }

  /* La testa diventa la prima colonna: titolo sopra la linea, frase sotto. */
  .tl--orizzontale .tl__testa{
    flex: none;
    width: clamp(20rem, 30vw, 32rem);
    display: grid;
    grid-template-rows: 1fr 1fr;
    gap: 0;
    margin: 0;
  }
  .tl--orizzontale .tl__testa-su{
    align-self: end;
    padding-bottom: clamp(1.5rem, 4vh, 2.5rem);
  }
  /* Nella colonna il titolo va su tre righe, e tutte e tre devono stare
     sopra la linea, cioe' in meta' fila. Sui portatili bassi (1280x720) il
     corpo pieno ci arrivava sopra: qui si ferma anche sull'altezza. */
  .tl--orizzontale .tl__titolo{ font-size: min(var(--t-xl), 8vh); }
  .tl--orizzontale .tl__testa .lede{
    align-self: start;
    margin-top: 0;
    padding-top: clamp(1.5rem, 4vh, 2.5rem);
  }

  .tl--orizzontale .tl__corso{
    flex: none;
    height: 100%;
    margin-left: clamp(2rem, 4vw, 4rem);
    padding-left: clamp(3rem, 6vw, 6rem);
  }
  .tl--orizzontale .tl__linea{
    top: 50%;
    bottom: auto;
    left: 0;
    right: 0;
    width: auto;
    height: 1px;
  }
  .tl--orizzontale .tl__linea-pieno{
    background: linear-gradient(to right, #FF1A1A, #E5321A);
    transform-origin: left;
    transform: scaleX(var(--linea, 1));
  }
  .tl--orizzontale .tl__linea::before{ display: block; top: 50%; left: 0; }
  .tl--orizzontale .tl__linea::after{ top: 50%; left: 100%; }

  /* Tre colonne e due piani: le fasi si alternano sopra e sotto la linea,
     quindi il testo di una puo' allargarsi sopra lo stelo della successiva
     senza toccarla. L'ultima colonna e' larga quanto il suo testo. */
  .tl--orizzontale .tl__tappe{
    --passo: clamp(19rem, 36vw, 36rem);
    display: grid;
    grid-template-columns: var(--passo) var(--passo) auto;
    grid-template-rows: 1fr 1fr;
    gap: 0;
    height: 100%;
    padding-bottom: 0;
  }
  .tl--orizzontale .tl__tappa{
    display: flex;
    padding-left: clamp(1.25rem, 2vw, 2rem);
  }
  .tl--orizzontale .tl__tappa:nth-child(1){ grid-column: 1; }
  .tl--orizzontale .tl__tappa:nth-child(2){ grid-column: 2; }
  .tl--orizzontale .tl__tappa:nth-child(3){ grid-column: 3; }
  .tl--orizzontale .tl__tappa--su{ grid-row: 1; align-items: flex-start; }
  .tl--orizzontale .tl__tappa--giu{ grid-row: 2; align-items: flex-end; }

  /* Lo stelo nasce dalla linea e va verso il punto: in su per le fasi di
     sopra, in giu' per quella di sotto. */
  .tl--orizzontale .tl__stelo{
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 1px;
    background: #FF1A1A;
    transform: scaleY(var(--stelo, 1));
  }
  .tl--orizzontale .tl__tappa--su .tl__stelo{ transform-origin: bottom; }
  .tl--orizzontale .tl__tappa--giu .tl__stelo{ transform-origin: top; }
  .tl--orizzontale .tl__punto{ left: .5px; }
  .tl--orizzontale .tl__tappa--su .tl__punto{ top: 0; }
  .tl--orizzontale .tl__tappa--giu .tl__punto{ top: 100%; }

  .tl--orizzontale .tl__testo{ width: min(24rem, calc(var(--passo) * 1.4)); }
  /* Sopra: il nome a meta' altezza del punto. Sotto: l'ultima riga della
     frase a meta' altezza del punto. */
  .tl--orizzontale .tl__tappa--su .tl__testo{ margin-top: calc(var(--nome) * -.475); }
  .tl--orizzontale .tl__tappa--giu .tl__testo{ margin-bottom: -.9rem; }
  .tl--orizzontale .tl__frase{ max-width: none; }
}

/* Su carta niente deve restare a meta' disegno. */
@media print{
  .tl{ --linea: 1 !important; }
  .tl__tappa{ --stelo: 1 !important; --punto: 1 !important; --testo: 1 !important; }
}

/* ---------- 12. PERCORSI (la ruota) ------------------ */
/* Riproduce il componente "works wheel" (components/ui/works-wheel.tsx)
   senza React. Al posto delle copertine ci sono le tre schede dei percorsi,
   pannelli scuri con dentro tutto: nome, descrizione, cosa include, prezzo
   e pulsante.
   Di base le schede stanno ferme in fila, in colonna sul telefono: e' quello
   che resta senza JS o con "riduci animazioni". La ruota la accende il JS
   (main.js, sezione 13c) con .ruota--attiva: la sezione si allunga, lo
   schermo resta fermo e la ruota gira con lo scroll della pagina, su ogni
   dispositivo. Nessuno scorrimento intercettato: prima, col mouse, la
   rotellina girava una scheda per spinta e la pagina veniva riportata a
   forza a filo della sezione, e quel tira e molla con lo scorrimento morbido
   del browser dava scatti. In piu' una classe per l'aspetto:
     - .ruota--rotella, dove c'e' un mouse: l'aspetto da computer;
     - .ruota--scorre, dove c'e' un dito: il palco parte sotto l'occhiello e
       le schede sono piu' larghe. */
.ruota__palco{
  width: var(--shell);
  margin-inline: auto;
}
.ruota__giro{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(.75rem, 1.5vw, 1.25rem);
}
.ruota__card{
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  height: 100%;
  padding: clamp(1.5rem, 2.4vw, 2.25rem);
  border-radius: .875rem;
  box-shadow: 0 24px 48px -28px rgba(7, 9, 11, .55);
}
/* La scheda e' un pannello scuro dentro una sezione chiara: le regole
   .on-light qui sotto le arrivano dalla sezione, e vanno rimesse ai valori
   del fondo scuro. */
.ruota__card .kicker{ color: var(--mute); }
.ruota__card .rule{ background: var(--line-on-dark); }
.ruota__card .link-arrow{ border-bottom-color: var(--line-on-dark-2); }
.ruota__card .link-arrow:hover,
.ruota__card .link-arrow:focus-visible{ color: var(--pulse); }
.ruota__card :focus-visible{ outline-color: var(--bone); }

.percorso__head{
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}
.percorso__nome{
  font-family: var(--font-display);
  font-size: var(--t-md);
  text-transform: uppercase;
  line-height: 1.05;
}
.percorso__desc{
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--silver);
}
.percorso__lista{
  display: flex;
  flex-direction: column;
  gap: .5rem;
  font-size: var(--t-small);
  color: var(--mute);
}
.percorso__lista li{
  position: relative;
  padding-left: 1.375rem;
  line-height: 1.45;
}
.percorso__lista li::before{
  content: "";
  position: absolute;
  left: 0;
  top: .65em;
  width: .5rem;
  height: 1px;
  background: var(--mute);
}
.percorso__prezzo{
  margin-top: auto;
  font-size: var(--t-kicker);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--mute);
}
.percorso__cta{ align-self: flex-start; }

.ruota__numero,
.ruota__indice{ display: none; }

/* ---- La ruota accesa ---- */
@media screen{
  .ruota--attiva{
    /* Chi arriva da "Percorso" nel menu o da "Guarda i percorsi" deve
       trovarla a filo: la pagina tiene 5rem sopra ogni sezione per la nav,
       ma qui la nav e' gia' messa in conto dentro lo schermo. */
    scroll-margin-top: -5rem;
    /* Piu' larga e' la scheda, meno righe va a capo e piu' e' bassa: e piu'
       tamburo resta visibile sopra e sotto. */
    --larga-card: min(86vw, clamp(19rem, 30vw, 28rem));
    padding-block: 0;
  }
  /* Le sezioni impilate sono una griglia centrata: qui centrerebbe lo
     schermo a meta' sezione (stesso caso del Metodo). */
  .impila main > section.ruota.ruota--attiva{
    display: block;
    align-content: normal;
  }
  /* La sezione si allunga di --corsa, la strada su cui la ruota gira
     mentre lo schermo resta fermo. */
  .ruota--attiva{
    height: calc(100vh + var(--corsa, 0px));
    height: calc(100svh + var(--corsa, 0px));
  }

  .ruota--attiva .ruota__schermo{
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100svh;
    overflow: hidden;
  }

  /* La testa si scompone: occhiello in alto, titolo al centro dell'anello,
     paragrafo in basso. Titolo e paragrafo se ne vanno mentre l'anello si
     apre (--apertura, da 0 a 1, la scrive il JS); l'occhiello resta. */
  .ruota--attiva .ruota__testa{
    position: absolute;
    top: var(--nav-h);
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    display: block;
    margin: 0;
    pointer-events: none;
  }
  .ruota--attiva .ruota__kicker{
    position: absolute;
    top: clamp(1.25rem, 4vh, 2.5rem);
    left: 0;
  }
  .ruota--attiva .ruota__titolo{
    position: absolute;
    top: 50%;
    left: 50%;
    width: max-content;
    max-width: 11ch;
    transform: translate(-50%, -50%);
    font-size: clamp(1.75rem, 3vw, 2.75rem);
    text-align: center;
    opacity: calc(1 - var(--apertura, 0));
  }
  .ruota--attiva .ruota__lede{
    position: absolute;
    bottom: clamp(1.5rem, 5vh, 3rem);
    left: 0;
    max-width: 34ch;
    margin: 0;
    opacity: calc(1 - var(--apertura, 0));
  }

  /* Il palco: tutto lo schermo sotto la nav. La prospettiva la scrive il
     JS, perche' dipende dall'altezza della scheda. */
  .ruota--attiva .ruota__palco{
    position: absolute;
    top: var(--nav-h);
    right: 0;
    bottom: 0;
    left: 0;
    width: auto;
    margin: 0;
    z-index: 1;
    outline: none;
  }
  .ruota--attiva .ruota__palco:focus-visible{
    outline: 2px solid var(--ink);
    outline-offset: -6px;
  }
  /* Col dito il palco parte sotto l'occhiello, e quello che ne esce non
     si vede: la scheda davanti e quelle che girano via coprivano
     "02 — I percorsi", e a ruota aperta il nome della sezione spariva. */
  .ruota--scorre .ruota__palco{
    top: calc(var(--nav-h) + 3.5rem);
    overflow: hidden;
  }
  /* Piu' larga, la scheda va meno a capo e resta piu' bassa: cosi' sta nel
     palco senza rimpicciolire il testo. */
  .ruota--scorre{ --larga-card: min(90vw, 24rem); }

  .ruota--attiva .ruota__giro{
    display: block;
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0;
    height: 0;
    transform-style: preserve-3d;
  }
  .ruota--attiva .ruota__posto{
    position: absolute;
    width: var(--larga-card);
    height: var(--alta-card, auto);
    margin-left: calc(var(--larga-card) / -2);
    margin-top: calc(var(--alta-card, 0px) / -2);
    -webkit-backface-visibility: hidden;
            backface-visibility: hidden;
  }

  /* Da 900px: il numero del percorso davanti, grande e di contorno come i
     numeri del Metodo, e l'indice per saltare a uno dei tre. */
  @media (min-width: 900px){
    .ruota--attiva .ruota__numero{
      display: block;
      position: absolute;
      top: calc(50% + var(--nav-h) / 2);
      left: calc((100% - var(--shell)) / 2);
      margin: 0;
      transform: translateY(-50%);
      opacity: var(--apertura, 0);
      pointer-events: none;
    }
    .ruota__numero span{
      display: block;
      font-family: var(--font-display);
      font-size: clamp(6rem, 13vw, 13rem);
      line-height: .8;
      color: rgba(106, 120, 135, .12);
      -webkit-text-stroke: 1px var(--ash);
    }
    .ruota__numero small{
      display: block;
      margin-top: 1rem;
      font-size: var(--t-kicker);
      letter-spacing: .26em;
      color: var(--mute-deep);
    }

    .ruota--attiva .ruota__indice{
      display: flex;
      flex-direction: column;
      align-items: flex-end;
      position: absolute;
      top: calc(50% + var(--nav-h) / 2);
      right: calc((100% - var(--shell)) / 2);
      z-index: 2;
      transform: translateY(-50%);
    }
    .ruota__indice button{
      position: relative;
      min-height: 2.75rem;
      padding-left: 2rem;
      font-size: var(--t-small);
      color: var(--mute-deep);
      text-align: right;
      transition: color var(--dur) var(--ease);
    }
    /* Il trattino rosso segna il percorso davanti, come la riga sotto la
       voce di menu. */
    .ruota__indice button::before{
      content: "";
      position: absolute;
      left: 0;
      top: 50%;
      width: 1.25rem;
      height: 1px;
      background: var(--pulse-deep);
      transform: scaleX(0);
      transform-origin: right;
      transition: transform var(--dur) var(--ease);
    }
    .ruota__indice button:hover{ color: var(--ink); }
    .ruota__indice button[aria-current="true"]{
      color: var(--ink);
      font-weight: 500;
    }
    .ruota__indice button[aria-current="true"]::before{ transform: scaleX(1); }
  }

  /* Sul telefono il paragrafo prende tutta la colonna. */
  @media (max-width: 899px){
    .ruota--attiva .ruota__lede{ right: 0; max-width: none; }
  }
}

/* ---------- 13. RISULTATI (slider prima/dopo) -------- */
/* Sul telefono la sezione era alta poco piu' di una schermata: appena
   arrivata, Chi sono le scorreva sopra, e non c'era il tempo di trascinare
   una maniglia. Come nel Metodo lo schermo si ferma sotto la nav; qui la
   sezione si allunga di 0,8 schermate, la strada su cui resta immobile.
   La scheda si stringe quanto serve perche' tutto stia sotto la nav.
   Solo con .impila: senza JS o con "riduci animazioni" scorre normale. */
@media screen and (max-width: 900px){
  .impila main > section.risultati{
    display: block;
    align-content: normal;
    padding-block: 0;
  }
  .impila .risultati > .shell{
    position: sticky;
    top: var(--nav-h, 0px);
    min-height: calc(100vh - var(--nav-h, 0px));
    min-height: calc(100svh - var(--nav-h, 0px));
    padding-block: 1rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  .impila .risultati::after{
    content: "";
    display: block;
    height: 80vh;
    height: 80svh;
  }
  .impila .risultati .section-head{
    gap: .875rem;
    margin-bottom: 1.5rem;
  }
  .impila .risultati .section-head .lede{ margin-top: 0; }
  /* 16.25rem: occhiello, titolo, paragrafo, frecce e margini. Con le
     didascalie sotto le foto, quando arriveranno, servono circa 5.5rem in
     piu'. */
  .impila .risultati .compare{
    flex-basis: max(11rem, min(66vw, 21rem, (100svh - var(--nav-h, 0px) - 16.25rem) * .75));
  }
}

/* Fila unica scorrevole: occupa l'altezza di UNA scheda invece di tre file.
   I varchi da 1px lasciano trasparire il fondo del contenitore, cosi' i sei
   casi restano un riquadro unico. Le schede sono piu' strette del contenitore
   apposta: la successiva sbircia dal bordo e si capisce che si scorre. */
.results__grid{
  display: flex;
  /* Le schede erano saldate fra loro da un filo di 1px (lo sfondo del
     contenitore che traspariva dai vuoti). Ora sono staccate: nel vuoto si
     vede il fondo della sezione e il contorno se lo porta ogni scheda. */
  gap: clamp(.625rem, 2vw, 1rem);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  scrollbar-color: var(--line-on-dark-2) transparent;
}
.compare{
  /* <figure> porta un margine laterale di 40px dal foglio di stile del
     browser: dentro una fila scorrevole diventava spazio morto fra le
     schede e spostava il primo aggancio. */
  margin: 0;
  flex: 0 0 clamp(14rem, 66vw, 21rem);
  border: 1px solid var(--line-on-dark);
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  gap: 0;
  background: var(--ink);
}
.compare__stage{
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: var(--graphite);
  /* Al tocco il browser gestisce da solo entrambe le direzioni: lo swipe
     orizzontale sulla foto scorre la fila, e resta possibile scorrere la
     pagina in verticale. Il taglio si sposta trascinando la maniglia o con
     un tocco (vedi sotto, "Col dito"). Col mouse, dove touch-action non si
     applica, il trascinamento funziona per intero. */
  touch-action: pan-x pan-y;
  cursor: ew-resize;
}
.compare__layer{
  position: absolute;
  inset: 0;
}
.compare__layer .media{ width: 100%; height: 100%; }
/* Il layer "dopo" si scopre da sinistra: si sposta a destra di --pos, e la
   foto dentro torna indietro di altrettanto, quindi resta ferma. Prima era
   un clip-path: a ogni movimento il telefono ridipingeva la foto col filtro
   B/N, e la maniglia andava a scatti. Due spostamenti li fa la scheda
   grafica da sola, senza ridipingere niente. */
.compare__layer--after{
  overflow: hidden;
  transform: translateX(var(--pos, 50%));
}
.compare__layer--after > .media{
  transform: translateX(calc(var(--pos, 50%) * -1));
}
/* Mentre trascini i tre pezzi che si muovono stanno su un livello loro, e
   il telefono li sposta senza ridisegnarli. Solo allora: cinque coppie di
   foto sempre su livelli propri pesavano sulla memoria di Safari. Il JS
   (compare) li sposta in pixel; questi valori in % valgono senza JS. */
.compare__stage.is-tira .compare__layer--after,
.compare__stage.is-tira .compare__layer--after > .media,
.compare__stage.is-tira .compare__handle{
  will-change: transform;
}
.compare__tag{
  position: absolute;
  top: .875rem;
  z-index: 4;
  font-size: var(--t-kicker);
  font-weight: 500;
  letter-spacing: .2em;
  text-transform: uppercase;
  padding: .375rem .75rem;
  background: rgba(7,9,11,.72);
  color: var(--bone);
  pointer-events: none;
}
.compare__tag--before{ left: .875rem; }
.compare__tag--after{ right: .875rem; }

/* La maniglia e' un velo grande quanto la foto, spostato di --pos: linea e
   cerchio stanno sul suo bordo sinistro. Come il layer "dopo", si sposta
   senza ridisegnare (prima cambiava left, e il browser rifaceva i conti). */
.compare__handle{
  position: absolute;
  inset: 0;
  transform: translateX(var(--pos, 50%));
  z-index: 5;
  pointer-events: none;
}
.compare__handle::before{
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 2px;
  transform: translateX(-1px);
  background: var(--bone);
}
.compare__handle::after{
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 3rem;
  height: 3rem;
  transform: translate(-50%, -50%);
  border: 2px solid var(--bone);
  border-radius: 50%;
  /* Fondo pieno e non sfocato: la sfocatura dietro un cerchio che si muove
     va ricalcolata a ogni fotogramma, e faceva andare a scatti la maniglia.
     Per lo stesso motivo niente sfocatura dietro le etichette. */
  background: rgba(7,9,11,.55);
  background-image:
    linear-gradient(to right, transparent 40%, var(--bone) 40% 42%, transparent 42% 58%, var(--bone) 58% 60%, transparent 60%);
}
/* Range reale sopra lo stage: tastiera e lettori di schermo. I puntatori
   (mouse e dito) li prende la foto sotto, nel JS. */
.compare__range{
  pointer-events: none;
  position: absolute;
  inset: 0;
  z-index: 6;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: ew-resize;
  touch-action: pan-x pan-y;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
}
.compare__range::-webkit-slider-thumb{
  -webkit-appearance: none;
  width: 3rem; height: 100%;
}
.compare__range::-moz-range-thumb{
  width: 3rem; height: 100%; border: 0; background: transparent;
}
/* Col dito (main.js, compare e frecce): lo swipe di lato sulla foto muove
   il taglio, e al browser resta solo lo scroll verticale della pagina. Il
   range resta per tastiera e lettori di schermo, ma non prende i tocchi.
   Fra una coppia e l'altra si passa con le frecce sotto la fila. */
.results__nav{ display: none; }
@media (pointer: coarse){
  .compare__stage{ touch-action: pan-y; }
  .results__nav{
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
    margin-top: 1rem;
  }
  .results__freccia{
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 1px solid var(--line-on-dark-2);
    border-radius: 50%;
    background: none;
    color: var(--bone);
    cursor: pointer;
    transition: opacity var(--dur) var(--ease), border-color var(--dur) var(--ease);
  }
  .results__freccia svg{ width: 1.125rem; height: auto; }
  .results__freccia:disabled{ opacity: .3; cursor: default; }
  .results__freccia:focus-visible{ outline: 2px solid var(--bone); outline-offset: 3px; }
  .results__conta{
    margin: 0;
    min-width: 5ch;
    text-align: center;
    font-size: var(--t-kicker);
    font-weight: 500;
    letter-spacing: .2em;
    font-variant-numeric: tabular-nums;
    color: var(--silver);
  }
}
.compare__range:focus-visible + .compare__handle::after{
  outline: 2px solid var(--bone);
  outline-offset: 4px;
}
/* In cella stretta nome e durata non stanno affiancati: si impilano. */
.compare__caption{
  display: flex;
  flex-direction: column;
  gap: .25rem;
  padding: .75rem clamp(.75rem, 2vw, 1.125rem) clamp(.875rem, 2vw, 1.25rem);
}
.compare__caption .kicker{ overflow-wrap: anywhere; }
.compare__name{
  font-family: var(--font-display);
  font-size: clamp(1rem, 2.4vw, 1.25rem);
  text-transform: uppercase;
  letter-spacing: .03em;
}
/* Le etichette si restringono con la cella, altrimenti si toccano */
@media (max-width: 759px){
  .compare__tag{
    top: .5rem;
    padding: .25rem .45rem;
    letter-spacing: .12em;
    font-size: .625rem;
  }
  .compare__tag--before{ left: .5rem; }
  .compare__tag--after{ right: .5rem; }
}

/* ---------- 14. FAQ ---------------------------------- */
.faq__grid{
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
  gap: clamp(2.5rem, 6vw, 6rem);
  align-items: start;
}
@media (max-width: 900px){ .faq__grid{ grid-template-columns: 1fr; } }

/* Ogni domanda e' una scheda a se', non una riga di un elenco. Il bordo
   corre tutto intorno e la risposta si apre dentro la scheda, che cresce:
   cosi' si vede a colpo d'occhio quale domanda si sta leggendo, cosa che
   con i soli filetti orizzontali non succedeva. */
.faq__list{
  display: flex;
  flex-direction: column;
  gap: .5rem;
}
.faq__item{
  border: 1px solid var(--line-on-light);
  border-radius: clamp(.875rem, 1.5vw, 1.25rem);
  background: rgba(255,255,255,.45);
  transition: border-color var(--dur) var(--ease),
              background-color var(--dur) var(--ease);
}
.faq__item:hover{
  border-color: var(--line-on-light-2);
  background: rgba(255,255,255,.75);
}
.faq__item:has(.faq__q[aria-expanded="true"]){
  border-color: var(--line-on-light-2);
  background: rgba(255,255,255,.85);
}
/* Schede basse: la riga deve restare una riga sola, con il testo centrato
   fra i due bordi. L'altezza scende da 76 a 57 px sul desktop, sopra i 44
   richiesti dal dito, e le sette domande si leggono tutte insieme senza
   che la sezione diventi un elenco da scorrere. */
.faq__q{
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
  padding: clamp(.875rem, 1.5vw, 1.0625rem) clamp(1.125rem, 2vw, 1.5rem);
  text-align: left;
  font-size: clamp(1rem, 1.3vw, 1.0625rem);
  font-weight: 400;
  line-height: 1.35;
  color: var(--ink);
  /* Stesso raggio della scheda, scritto per esteso: `inherit` qui prende il
     valore dell'<h3> che avvolge il bottone, non quello della scheda, e
     l'anello del focus sarebbe uscito squadrato dentro un bordo tondo. */
  border-radius: clamp(.875rem, 1.5vw, 1.25rem);
}
.faq__icon{
  flex: none;
  position: relative;
  width: .875rem;
  height: .875rem;
  color: var(--mute-deep);
}
.faq__icon::before, .faq__icon::after{
  content: "";
  position: absolute;
  top: 50%; left: 0;
  width: 100%; height: 1.5px;
  background: currentColor;
  transition: transform var(--dur) var(--ease);
}
.faq__icon::after{ transform: rotate(90deg); }
.faq__q[aria-expanded="true"] .faq__icon{ color: var(--pulse-deep); }
.faq__q[aria-expanded="true"] .faq__icon::after{ transform: rotate(0deg); }

/* Apertura senza salti: grid-template-rows 0fr -> 1fr */
.faq__a{
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur) var(--ease);
}
.faq__a > div{ overflow: hidden; }
.faq__a[data-open="true"]{ grid-template-rows: 1fr; }
.faq__a p{
  /* stessi margini laterali della domanda, cosi' il testo resta incolonnato */
  padding: 0 clamp(1.125rem, 2vw, 1.5rem) clamp(1.125rem, 2vw, 1.5rem);
  color: #343B3F;
  max-width: 62ch;
}

/* ---------- 15. CTA + FORM --------------------------- */
/* La FAQ sopra e' chiara, quindi il passaggio al fondo scuro fa gia' da
   stacco: qui non serve nessuna riga in piu'. */
.cta{
  position: relative;
  overflow: hidden;
}

.cta__title{
  font-size: var(--t-xl);
  max-width: 15ch;
}
.cta__grid{
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
}
@media (max-width: 940px){ .cta__grid{ grid-template-columns: 1fr; } }

/* La colonna di destra della sezione Contatti: la form in cima, i due tasti
   (WhatsApp e mail) sotto. */
.cta__aside{
  display: flex;
  flex-direction: column;
  gap: clamp(2.5rem, 5vw, 4rem);
}

/* I due tasti, WhatsApp e mail. Prima erano righe di testo con un'icona
   piccola: si leggevano come la firma in fondo a una lettera, non come
   qualcosa da premere. Adesso sono bersagli larghi quanto la colonna e alti
   84px, con scritta prima l'azione e poi il recapito.
   Il primo e' pieno di bianco: su un fondo scuro e' il richiamo piu' forte
   che questa tavolozza ha, e non serve un colore per ottenerlo. Il secondo
   resta di contorno e si riempie al passaggio, cosi' l'occhio ha un primo
   posto dove andare invece di due inviti uguali. */
.contact-actions{
  display: flex;
  flex-direction: column;
  gap: .75rem;
}
.contact-btn{
  display: flex;
  align-items: center;
  gap: clamp(.875rem, 2vw, 1.25rem);
  min-height: 5.25rem;            /* 84px, il dito ne chiede 44 */
  padding: 1rem clamp(1.125rem, 2vw, 1.5rem);
  border: 1px solid var(--line-on-dark-2);
  border-radius: 1rem;
  color: var(--bone);
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}
.contact-btn__icona{ width: 1.5rem; height: 1.5rem; flex: none; }
.contact-btn__testo{ display: flex; flex-direction: column; gap: .25rem; min-width: 0; }
.contact-btn__azione{
  font-family: var(--font-display);
  font-size: clamp(1.125rem, 1.5vw, 1.375rem);
  line-height: 1.1;
  text-transform: uppercase;
}
/* mute su ink 7.04:1, mute-deep su bone 5.85:1: si legge su tutti e due gli
   stati del tasto, spento e acceso. */
.contact-btn__meta{ font-size: var(--t-small); color: var(--mute); }
.contact-btn__freccia{
  width: 1.25rem; height: 1.25rem; flex: none;
  margin-left: auto;
  color: var(--mute);
  transition: transform var(--dur) var(--ease), color var(--dur-fast) var(--ease);
}
.contact-btn:hover,
.contact-btn:focus-visible{
  background: var(--bone);
  border-color: var(--bone);
  color: var(--ink);
}
.contact-btn:hover .contact-btn__meta,
.contact-btn:focus-visible .contact-btn__meta,
.contact-btn:hover .contact-btn__freccia,
.contact-btn:focus-visible .contact-btn__freccia{ color: var(--mute-deep); }
.contact-btn:hover .contact-btn__freccia,
.contact-btn:focus-visible .contact-btn__freccia{ transform: translate3d(.35rem, 0, 0); }

.contact-btn--pieno{
  background: var(--bone);
  border-color: var(--bone);
  color: var(--ink);
}
.contact-btn--pieno .contact-btn__meta,
.contact-btn--pieno .contact-btn__freccia{ color: var(--mute-deep); }
.contact-btn--pieno:hover,
.contact-btn--pieno:focus-visible{
  background: var(--silver);
  border-color: var(--silver);
}


/* Form multi-step */
.form{
  border: 1px solid var(--line-on-dark);
  background: var(--charcoal);
  padding: clamp(1.5rem, 3vw, 2.75rem);
}
.form__progress{
  display: flex;
  gap: .5rem;
  margin-bottom: 2rem;
}
.form__progress span{
  flex: 1;
  height: 2px;
  background: var(--line-on-dark);
  position: relative;
  overflow: hidden;
}
.form__progress span::after{
  content: "";
  position: absolute;
  inset: 0;
  /* La barra dei tre passi: in bianco era una riga come tante, in rosso dice
     a colpo d'occhio quanto manca. */
  background: var(--pulse);
  transform: translate3d(-100%, 0, 0);
  transition: transform var(--dur) var(--ease);
}
.form__progress span.is-done::after{ transform: none; }

.form__step{ display: none; }
.form__step.is-active{ display: block; animation: stepIn .5s var(--ease) both; }
@keyframes stepIn{
  from{ opacity: 0; transform: translate3d(0, .875rem, 0); }
  to  { opacity: 1; transform: none; }
}

.form__legend{
  font-family: var(--font-display);
  font-size: var(--t-lg);
  text-transform: uppercase;
  line-height: 1;
  margin-bottom: .625rem;
  padding: 0;
}
.form__hint{
  font-size: var(--t-small);
  color: var(--mute);
  margin-bottom: 1.75rem;
}
.form fieldset{ border: 0; padding: 0; margin: 0; }

.choices{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  gap: .75rem;
  margin-bottom: 1.75rem;
}
.choice{ position: relative; }
.choice input{
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
  margin: 0;
}
.choice span{
  display: flex;
  align-items: center;
  min-height: 3.25rem;
  padding: .875rem 1.125rem;
  border: 1px solid var(--line-on-dark);
  font-size: var(--t-small);
  line-height: 1.35;
  cursor: pointer;
  transition:
    border-color var(--dur-fast) var(--ease),
    background var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease);
}
.choice input:hover + span{ border-color: var(--line-on-dark-2); }
.choice input:checked + span{
  background: var(--bone);
  border-color: var(--bone);
  color: var(--ink);
  font-weight: 500;
}
.choice input:focus-visible + span{
  outline: 2px solid var(--bone);
  outline-offset: 3px;
}

.field{ margin-bottom: 1.25rem; }
.field label{
  display: block;
  font-size: var(--t-kicker);
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--mute);
  margin-bottom: .625rem;
}
.field input,
.field textarea{
  width: 100%;
  min-height: 3rem;
  padding: .875rem 1rem;
  background: var(--ink);
  border: 1px solid var(--line-on-dark);
  color: var(--bone);
  font-size: 1rem;   /* >=16px: evita lo zoom automatico su iOS */
  transition: border-color var(--dur-fast) var(--ease);
}
.field textarea{ min-height: 7rem; resize: vertical; line-height: 1.6; }
.field input::placeholder,
.field textarea::placeholder{ color: rgba(143,155,167,.5); }
.field input:focus, .field textarea:focus{ outline: none; border-color: var(--bone); }
.field input:focus-visible, .field textarea:focus-visible{ outline: 2px solid var(--bone); outline-offset: 2px; }
.field--error input,
.field--error textarea{ border-color: #D9584E; }
.field__error{
  display: none;
  margin-top: .5rem;
  font-size: var(--t-small);
  color: #F0968E;
}
.field--error .field__error{ display: flex; align-items: center; gap: .5rem; }
.field__error svg{ width: 1rem; flex: none; }

.consent{
  display: flex;
  align-items: flex-start;
  gap: .75rem;
  margin-bottom: 1.75rem;
  font-size: var(--t-small);
  color: var(--mute);
  line-height: 1.5;
  cursor: pointer;
}
.consent input{
  flex: none;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: .25rem;
  accent-color: var(--bone);
  cursor: pointer;
}
.consent a{ text-decoration: underline; text-underline-offset: 3px; }

.form__nav{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: .5rem;
}
.form__back{
  min-height: 2.75rem;
  padding: .5rem 0;
  font-size: var(--t-kicker);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--mute);
  transition: color var(--dur-fast) var(--ease);
}
.form__back:hover{ color: var(--bone); }

.form__alt{
  margin-top: 1.75rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--line-on-dark);
  font-size: var(--t-small);
  color: var(--mute);
}
.form__alt a{
  color: var(--bone);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.form__done{
  display: none;
  text-align: center;
  padding-block: 2rem;
}
.form__done.is-active{ display: block; animation: stepIn .5s var(--ease) both; }
.form__done h3{
  font-family: var(--font-display);
  font-size: var(--t-lg);
  text-transform: uppercase;
  margin-bottom: 1rem;
}
.form__done p{ color: var(--silver); margin-inline: auto; max-width: 42ch; margin-bottom: 1.75rem; }

/* ---------- 16. FOOTER ------------------------------- */
/* position: relative tiene la grana dei fondi scuri (.on-dark::before, che
   e' assoluta) dentro il piede. Senza, la grana si appoggiava alla prima
   schermata della pagina finche' il JS non aggiungeva .impila, e poi saltava
   in fondo: per Google uno spostamento dell'intera schermata (CLS 1,0). */
.footer{
  position: relative;
  padding-block: clamp(3rem, 6vw, 5rem) 2rem;
  border-top: 1px solid var(--line-on-dark);
}
.footer__top{
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: end;
  margin-bottom: clamp(3rem, 6vw, 4.5rem);
}
@media (max-width: 800px){ .footer__top{ grid-template-columns: 1fr; align-items: start; } }

.footer__word{
  font-family: var(--font-display);
  font-size: clamp(4rem, 17vw, 15rem);
  line-height: .78;
  letter-spacing: .01em;
  text-transform: uppercase;
  color: transparent;
  -webkit-text-stroke: 1px var(--line-on-dark-2);
  user-select: none;
}
.footer__cols{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr));
  gap: 2rem;
}
.footer__cols h4{
  font-size: var(--t-kicker);
  font-weight: 500;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--mute);
  margin-bottom: 1rem;
}
.footer__cols li + li{ margin-top: .625rem; }
.footer__cols a{
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-size: var(--t-small);
  transition: color var(--dur-fast) var(--ease);
}
.footer__cols a:hover{ color: var(--mute); }

.footer__bottom{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 2rem;
  border-top: 1px solid var(--line-on-dark);
  font-size: var(--t-kicker);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--mute);
}
.footer__bottom nav{ display: flex; flex-wrap: wrap; gap: 1.5rem; }
.footer__bottom a{
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  transition: color var(--dur-fast) var(--ease);
}
.footer__bottom a:hover{ color: var(--bone); }

/* ---------- 17. WHATSAPP FLOTTANTE ------------------- */
.fab{
  position: fixed;
  right: clamp(1rem, 3vw, 2rem);
  bottom: clamp(1rem, 3vw, 2rem);
  z-index: var(--z-fab);
  display: inline-flex;
  align-items: center;
  gap: .75rem;
  min-height: 3.25rem;
  padding: .875rem 1.375rem;
  background: var(--bone);
  color: var(--ink);
  border-radius: 999px;
  font-size: var(--t-kicker);
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  box-shadow: 0 10px 40px rgba(0,0,0,.5);
  /* Nascosto davvero finche' non serve: con la barra cookie aperta
     la sola traslazione lo lasciava sbucare dal bordo. */
  opacity: 0;
  visibility: hidden;
  transform: translate3d(0, 150%, 0);
  transition:
    transform .6s var(--ease),
    opacity .4s var(--ease),
    visibility 0s linear .6s,
    background var(--dur-fast) var(--ease);
}
.fab.is-visible{
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}
.fab:hover{ background: #fff; }
.fab svg{ width: 1.25rem; flex: none; }
@media (max-width: 560px){
  .fab__label{
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
  .fab{ padding: 1rem; width: 3.5rem; height: 3.5rem; justify-content: center; }
}

/* ---------- 18. COOKIE BANNER ------------------------ */
.cookie{
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-overlay);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding: 1rem var(--gutter);
  background: rgba(14,17,20,.96);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--line-on-dark-2);
  transform: translate3d(0, 100%, 0);
  transition: transform .6s var(--ease);
}
.cookie.is-visible{ transform: none; }
.cookie p{
  flex: 1 1 22rem;
  font-size: var(--t-small);
  color: var(--silver);
  line-height: 1.5;
  margin: 0;
  max-width: 68ch;
}
.cookie a{ color: var(--bone); text-decoration: underline; text-underline-offset: 3px; }
.cookie__actions{ display: flex; flex-wrap: wrap; gap: .75rem; flex: none; }
.cookie .btn{ min-height: 2.75rem; padding: .625rem 1.25rem; font-size: var(--t-kicker); }

/* Finche' la barra cookie e' aperta, il pulsante WhatsApp le sta sopra */
body.cookie-open .fab{ bottom: calc(clamp(1rem, 3vw, 2rem) + var(--cookie-h, 5rem)); }

@media (max-width: 620px){
  .cookie{ padding: 1rem; }
  .cookie__actions{ width: 100%; }
  .cookie__actions .btn{ flex: 1; }
}

/* ---------- 19. PAGINE LEGALI ------------------------ */
.legal{ padding-block: clamp(3rem, 8vw, 6rem); }
.legal h1{
  font-family: var(--font-display);
  font-size: var(--t-xl);
  text-transform: uppercase;
  margin-bottom: 2.5rem;
}
.legal h2{
  font-family: var(--font-display);
  font-size: var(--t-md);
  text-transform: uppercase;
  margin: 2.75rem 0 1rem;
}
.legal p, .legal li{ color: var(--silver); max-width: 68ch; }
.legal p + p{ margin-top: 1rem; }
.legal ul{ margin-top: 1rem; }
.legal li{ position: relative; padding-left: 1.375rem; margin-top: .625rem; }
.legal li::before{
  content: "";
  position: absolute;
  left: 0; top: .8em;
  width: .5rem; height: 1px;
  background: var(--mute);
}
.legal a{ color: var(--bone); text-decoration: underline; text-underline-offset: 3px; }
.legal__updated{ font-size: var(--t-small); color: var(--mute); margin-top: 3rem; }

/* Pagina 404: una schermata sola, col messaggio al centro e le due strade
   per uscirne. Senza main.js, quindi niente comparse animate. */
.errore{
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  align-content: center;
  padding-block: calc(var(--nav-h) + 2rem) 4rem;
}
.errore__titolo{
  font-size: var(--t-xl);
  margin: 1.25rem 0 1.5rem;
}
.errore__azioni{
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 2.5rem;
}

/* ---------- 20. MOVIMENTO RIDOTTO -------------------- */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto; }
  *, *::before, *::after{
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .js [data-reveal]{ opacity: 1 !important; transform: none !important; }
  .js .line-mask > span{ transform: none !important; }
  .scroll-hint::after{ animation: none; opacity: .6; transform: none; }
  .fab{ transform: none; }
  /* La regola generale qui sopra fa scattare le animazioni una volta sola e in
     un istante: il verso si fermerebbe dove capita. Lo fisso al centro,
     dove la luce copre tutte le lettere. */
  .hero__title .line-mask > span,
  .manifesto__title .dim > span{ background-position: 50% 0 !important; }
}

/* ---------- 21. STAMPA ------------------------------- */
@media print{
  .nav, .fab, .cookie, .hero__media, .scroll-hint{ display: none !important; }
  body{ background: #fff; color: #000; }
  .on-dark{ background: #fff !important; color: #000 !important; }
  /* In stampa nessuno scorre: i blocchi non ancora rivelati devono comunque uscire */
  .js [data-reveal]{ opacity: 1 !important; transform: none !important; }
  /* La ruota e' solo per lo schermo: su carta le tre schede tornano dritte,
     anche se il JS ha lasciato le sue trasformazioni nello stile. */
  .ruota__giro, .ruota__posto, .ruota__card{ transform: none !important; opacity: 1 !important; }
  .js .line-mask > span{ transform: none !important; }
  .faq__a{ grid-template-rows: 1fr !important; }
  .muted, .tl__frase{ color: #333 !important; }
  /* Su carta il fondo e' bianco: un riempimento a gradiente chiaro sparirebbe.
     I due versi tornano inchiostro pieno. */
  .manifesto__title .dim > span{
    background: none !important;
    -webkit-background-clip: border-box !important;
            background-clip: border-box !important;
    color: #000 !important;
    animation: none !important;
  }
  /* Stesso problema per le tre parole dell'eroe, che sono riempite da un
     gradiente ritagliato sul testo: senza questo su carta uscirebbero vuote.
     Il ::before porta la copia "spenta" della parola; in stampa ne basta una,
     quindi resta solo il testo vero, in nero pieno e senza alone. */
  .gyzz-tc h1 span{
    background: none !important;
    -webkit-background-clip: border-box !important;
            background-clip: border-box !important;
    color: #000 !important;
    opacity: 1 !important;
    animation: none !important;
  }
  .gyzz-tc h1 span[data-content]::before{ display: none !important; }
}

/* ---------- 22. SEGNAPOSTO: SPARIZIONE AUTOMATICA ---- */
/* Appena il file reale viene caricato, il segnaposto si spegne da solo.
   :has() per i browser moderni, .has-media come rete di sicurezza da JS. */
.media:has(img.is-loaded)::after,
.media:has(video.is-loaded)::after,
.media.has-media::after{ content: none; }

.media:has(img.is-loaded)::before,
.media:has(video.is-loaded)::before,
.media.has-media::before{ opacity: 0; }

/* Nell'hero il segnaposto non deve mai mostrare l'etichetta */
.hero__media::after{ content: none; }

/* ---------- 23. HERO: POSTER + VIDEO SOVRAPPOSTI ----- */
.hero__media img,
.hero__media video{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.hero__media img{ z-index: 2; }
.hero__media video{ z-index: 3; }

/* ---------- 24. COMPONENTE "TEXT COLOR" -------------- */
/* Integrato su richiesta esplicita, seguendo il prompt alla lettera.
   Il sorgente React sta in /components/ui/text-color.tsx e qui non gira:
   questa e' la stessa cosa scritta in HTML e CSS, con le classi identiche,
   perche' il progetto non ha React, Tailwind ne' un passaggio di build.

   25a — il blocco fornito con il componente, riportato tale e quale. */

.relative {
  position: relative;
}

@keyframes gradient-foreground-1 {
  from,
  16.667%,
  to {
    opacity: 1;
  }
  33.333%,
  83.333% {
    opacity: 0;
  }
}

.animate-gradient-foreground-1 {
  animation: gradient-foreground-1 8s infinite;
}

@keyframes gradient-foreground-2 {
  from,
  to {
    opacity: 0;
  }
  33.333%,
  50% {
    opacity: 1;
  }
  16.667%,
  66.667% {
    opacity: 0;
  }
}

.animate-gradient-foreground-2 {
  animation: gradient-foreground-2 8s infinite;
}

@keyframes gradient-foreground-3 {
  from,
  50%,
  to {
    opacity: 0;
  }
  66.667%,
  83.333% {
    opacity: 1;
  }
}

.animate-gradient-foreground-3 {
  animation: gradient-foreground-3 8s infinite;
}

.select-none {
  -webkit-user-select: none;
  user-select: none;
}

.bg-gradient-to-r {
  background-image: linear-gradient(to right, var(--tw-gradient-stops));
}

/* Neon-style gradients */
/* Le tre parole hanno lo stesso riempimento: il rosso che prima era solo di
   COSTANZA. Il componente d'origine ne dava una diversa a ognuna — METODO.
   era un metallico nero-argento-bianco, RISULTATO. un neon giallo-azzurro —
   ma tre tinte diverse sopra un video in movimento tirano l'occhio in tre
   punti invece che sulla frase. Con un colore solo la riga si legge come una
   cosa sola, e l'animazione resta com'era: le parole continuano ad accendersi
   a turno, una dopo l'altra.
   I due estremi restano nella meta' chiara del rosso per forza di cose: il
   rosso ha poca luminanza di suo (pesa 0.2126 su 1), e sul fondo scuro
   dell'eroe qualunque cremisi cupo scende sotto il 3:1 richiesto dal testo
   grande — #C1121F sarebbe 2.34:1, #A4161A addirittura 1.88:1. Questi due
   tengono 3.75:1 e 4.68:1 sul fotogramma peggiore del video. METODO. ci
   guadagna: il metallico partiva da nero pieno, e li' stava a 1.09:1. */
.from-gradient-1-start,
.from-gradient-2-start,
.from-gradient-3-start {
  --tw-gradient-from: #ff1a1a; /* Rosso pieno */
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgba(255, 26, 26, 0));
}

.to-gradient-1-end,
.to-gradient-2-end,
.to-gradient-3-end {
  --tw-gradient-to: #ff5a2b; /* Rosso caldo */
}

/* AI Variants */
.from-gradient-1-ai {
  --tw-gradient-from: #39ff14;
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgba(57, 255, 20, 0));
}

.to-gradient-1-ai {
  --tw-gradient-to: #ff00ff;
}

.from-gradient-2-ai {
  --tw-gradient-from: #ff6ec7;
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgba(255, 110, 199, 0));
}

.to-gradient-2-ai {
  --tw-gradient-to: #00fffb;
}

.from-gradient-3-ai {
  --tw-gradient-from: #faff00;
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgba(250, 255, 0, 0));
}

.to-gradient-3-ai {
  --tw-gradient-to: #00f0ff;
}

.bg-clip-text {
  -webkit-background-clip: text;
  background-clip: text;
}

.py-14 {
  padding-top: 3.5rem;
  padding-bottom: 3.5rem;
}

.px-2 {
  padding-left: 0.5rem;
  padding-right: 0.5rem;
}

.text-center {
  text-align: center;
}

.text-\[23vw\] {
  font-size: 12vw;
}

.leading-none {
  line-height: 1;
}

.tracking-tightest {
  letter-spacing: -0.09em;
}

.text-transparent {
  color: transparent;
}

.before\:absolute::before {
  content: "";
  position: absolute;
}

.before\:top-0::before {
  content: "";
  top: 0px;
}

.before\:bottom-0::before {
  content: "";
  bottom: 0px;
}

.before\:left-0::before {
  content: "";
  left: 0px;
}

.before\:z-0::before {
  content: "";
  z-index: 0;
}

.before\:w-full::before {
  content: "";
  width: 100%;
}

@keyframes gradient-background-1 {
  from,
  16.667%,
  to {
    opacity: 0;
  }
  25%,
  91.667% {
    opacity: 1;
  }
}

.before\:animate-gradient-background-1::before {
  content: "";
  animation: gradient-background-1 8s infinite;
}

@keyframes gradient-background-2 {
  from,
  to {
    opacity: 1;
  }
  33.333%,
  50% {
    opacity: 0;
  }
  25%,
  58.333% {
    opacity: 1;
  }
}

.before\:animate-gradient-background-2::before {
  content: "";
  animation: gradient-background-2 8s infinite;
}

@keyframes gradient-background-3 {
  from,
  58.333%,
  91.667%,
  to {
    opacity: 1;
  }
  66.667%,
  83.333% {
    opacity: 0;
  }
}

.before\:animate-gradient-background-3::before {
  content: "";
  animation: gradient-background-3 8s infinite;
}

.before\:px-2::before {
  content: "";
  padding-left: 0.5rem;
  padding-right: 0.5rem;
}

.before\:text-center::before {
  content: "";
  text-align: center;
}

.before\:text-black::before {
  content: "";
  --tw-text-opacity: 1;
  color: rgba(0, 0, 0, var(--tw-text-opacity));
}

.before\:content-\[attr\(data-content\)\]::before {
  content: attr(data-content);
}

/* 24b — le utility che il componente usa ma che il blocco fornito non
   contiene: in un progetto Tailwind le genererebbe il compilatore, qui
   vanno scritte. Valori presi dalla scala predefinita di Tailwind.
   Le regole di bordo, posizionamento e colore delle croci d'angolo sono
   state tolte insieme alla cornice viola: non le usava piu' nessuno. */

.gyzz-tc h1 {
  /* font-sans di Tailwind: il componente non dichiara un carattere, quindi
     eredita quello che il preflight mette su html. */
  font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto,
               'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
  /* METODO. COSTANZA. RISULTATO. sono molto piu' lunghe di Develop. Preview.
     Ship.: con i corpi fissi del componente (72px, 96px da 640px in su) la
     riga sbordava di 244px a 1440 e restava leggibile solo la parola centrale.
     I limiti qui sotto vengono dalla misura di dove la riga smette di entrare:
     40px a 375, 48px a 1024, 76px a 1440. */
  font-size: clamp(2rem, 10vw, 6rem);
  /* leading-none incolla le tre parole una sull'altra. Il salto e' in em,
     cosi' segue il corpo fluido. In fila (da 1024px) il vuoto fra le parole
     lo fanno gia' px-2 e sm:px-5, quindi qui muovo solo la spaziatura
     verticale e la larghezza della riga resta quella misurata. */
  row-gap: .28em;
}
@media (min-width: 1024px){
  /* Da qui le tre parole stanno in fila, e la riga non deve solo entrare:
     deve riempire la colonna del sito, altrimenti su un monitor largo
     l'intestazione resta un francobollo in mezzo al video.

     Il corpo non e' scelto a occhio, e' invertito da una misura presa sulla
     pagina viva: a un dato corpo X la riga occupa 13.9*X di glifi piu' 120px
     di spaziature fisse (px-5 sulle tre parole, un valore in px che non
     scala col corpo). Volendo che la riga occupi il 95% della colonna:

         corpo = (0.95 * colonna - 120px) / 13.9

     A 1440px viene 80px invece di 64.8; da 1556px in su la colonna e' ferma
     a 1400px e quindi si ferma anche il corpo, a 87px. Il 5% avanzato e'
     l'aria ai due lati: senza, la riga toccherebbe i bordi.
     Il 13.9 vale per il carattere di sistema del Mac; su Windows e Linux la
     stessa riga cambia di qualche punto percentuale, e quell'aria e' anche
     il margine che le lascia. */
  .gyzz-tc h1{
    font-size: calc((var(--shell) * .95 - 120px) / 13.9);
    /* text-center allinea il testo dentro ogni parola, non le tre parole fra
       loro: in fila restavano appiccicate a sinistra con un vuoto a destra. */
    justify-content: center;
  }
  /* I 44px di padding orizzontale (p-8 sul riquadro, px-3 sull'h1) toglievano
     larghezza proprio dove serve. In fila non servono: il respiro laterale lo
     da' gia' il 5% lasciato dal calcolo qui sopra. */
  .gyzz-tc .p-8,
  .gyzz-tc h1{ padding-inline: 0; }
}

.mb-10 { margin-bottom: 2.5rem; }
.mt-4  { margin-top: 1rem; }
.p-8   { padding: 2rem; }
.px-3  { padding-left: .75rem; padding-right: .75rem; }
.py-2  { padding-top: .5rem; padding-bottom: .5rem; }
.w-full{ width: 100%; }
.h-full{ height: 100%; }
.flex  { display: flex; }
.flex-col { flex-direction: column; }
.text-7xl{ font-size: 4.5rem; line-height: 1; }
.font-extrabold{ font-weight: 800; }
.tracking-tighter{ letter-spacing: -.05em; }
/* Niente `content` qui: queste due regole stanno dopo il blocco fornito, e a
   parita' di specificita' vincerebbero sul `content: attr(data-content)`
   svuotando il testo di "Develop." e "Ship.". Impostano solo la posizione. */
.before\:bottom-4::before{ bottom: 1rem; }
.before\:bottom-1::before{ bottom: .25rem; }

/* mask-image arbitraria: gli underscore di Tailwind sono spazi.
   Aggiunta una zona piena fino al 55% del raggio. Senza, la sfumatura parte
   dal centro esatto: con la riga larga 1330px la prima e l'ultima parola si
   trovano al 21% del raggio orizzontale e vengono dipinte all'80-89% di
   opacita', mentre COSTANZA. al centro sta al 100%. Su METODO. si vedeva:
   il nero diventava piu' chiaro perche' lasciava passare il video sotto,
   cioe' l'opposto del nero intenso scelto al banco colori — dove la
   maschera non c'era. Con la zona piena l'intestazione e' opaca tutta,
   e la sfumatura resta per quello che dovesse uscire da li'. */
.\[mask-image\:radial-gradient\(200rem_24rem_at_center\,white\,transparent\)\]{
  -webkit-mask-image: radial-gradient(200rem 24rem at center, #fff 0 55%, transparent 100%);
          mask-image: radial-gradient(200rem 24rem at center, #fff 0 55%, transparent 100%);
}

@media (min-width: 640px){
  .sm\:text-8xl{ font-size: 6rem; line-height: 1; }
  .sm\:px-5{ padding-left: 1.25rem; padding-right: 1.25rem; }
  .sm\:before\:top-0::before{ top: 0px; }   /* niente `content`, stessa ragione di sopra */
}
@media (min-width: 768px){
  .md\:mt-6{ margin-top: 1.5rem; }
  .md\:flex-col{ flex-direction: column; }
}
@media (min-width: 1024px){
  .lg\:flex-row{ flex-direction: row; }
}

/* ---------- 25. SEZIONI IMPILATE ---------------------- */
/* Componente "motion-footer" — sorgente React fornita nel prompt e non
   salvata nel progetto, su tua richiesta.
   Di quel componente qui serve una cosa sola, il movimento: ogni sezione
   resta ferma quando l'hai finita di leggere e la successiva le sale
   sopra. E' il sipario che il componente fa una volta sola sul footer,
   ripetuto a ogni passaggio.

   Niente GSAP e niente ScrollTrigger: e' position:sticky, cioe' il
   browser che smette di far scorrere un elemento. Nessuna libreria,
   nessun listener di scroll, nessun fotogramma da dipingere a mano.

   La classe .impila la mette il JS (main.js, sezione 11) solo dopo aver
   calcolato gli agganci. Senza JS, o con "riduci animazioni" attivo,
   questo blocco non si applica affatto e la pagina scorre come prima. */
.impila main > section{
  position: sticky;
  /* L'aggancio vale 100vh meno l'altezza della sezione: un numero
     negativo, che il JS scrive su ognuna. Le due scorciatoie ovvie non
     funzionano, provate tutte e due:
       top: 0     la sezione si incolla appena tocca il soffitto, e tutto
                  quello che ha sotto la prima schermata non si raggiunge
                  piu' — meta' del Metodo sparirebbe;
       bottom: 0  peggio: sticky tira in alto anche le sezioni che stanno
                  sotto, e dopo poche centinaia di pixel sono gia'
                  agganciate tutte insieme, una sopra l'altra.
     Il ripiego e' `auto`: se il JS non arriva a scrivere il valore,
     sticky non aggancia niente e la sezione resta nel flusso. */
  top: var(--aggancio, auto);
  /* Ogni sezione deve poter coprire uno schermo intero: una piu' bassa
     lascerebbe scoperta, sopra di se', quella che sta coprendo, e se ne
     vedrebbero due insieme. Vale anche per l'eroe, che da solo si
     fermerebbe a 1040px sugli schermi alti. */
  min-height: 100vh;
  min-height: 100svh;
  /* Il bordo di quella che arriva deve staccarsi da quella che copre. */
  box-shadow: 0 -30px 60px -20px rgba(7, 9, 11, .55);
}
/* Le sezioni che crescono per forza vanno ricentrate: senza, il contenuto
   resterebbe appeso in alto con il vuoto sotto. L'eroe no, si dispone
   gia' da se'. */
.impila main > section:not(.hero){
  display: grid;
  align-content: center;
}
/* Su computer ogni sezione, finita di leggere, resta ferma un tratto prima
   che la successiva le salga sopra: con la rotellina o il trackpad si
   passava da una sezione all'altra troppo in fretta. Il margine e' strada in
   piu' che passa sotto la sezione agganciata senza vedersi, come per
   Contatti qui sotto. Non tocca lo scorrimento della pagina, che resta
   quello del browser, ne' il giro delle carte dei Percorsi. L'eroe no:
   fermo all'apertura sembrerebbe una pagina bloccata.
   Il JS somma questi margini dove calcola le posizioni delle sezioni
   (main.js, sezioni 13c e 13e). */
@media (min-width: 901px){
  .impila main > section.tl,
  .impila main > section.ruota,
  .impila main > section.risultati,
  .impila main > section.manifesto{
    margin-bottom: 35vh;
    margin-bottom: 35svh;
  }
}
/* Contatti resta fermo un po' prima che la FAQ gli salga sopra. WhatsApp e
   mail sono l'ultima cosa della sezione: appena arrivavano in fondo allo
   schermo, la FAQ li copriva. Il margine sotto e' strada in piu': la
   sezione e' gia' agganciata e copre lo schermo intero, quindi lo spazio le
   passa sotto senza vedersi, e la FAQ arriva dopo 0,6 schermate.
   Il JS dei link interni (main.js, sezione 13e) somma anche questo margine. */
.impila main > section.cta{
  margin-bottom: 60vh;
  margin-bottom: 60svh;
}
/* Senza z-index il footer finirebbe dipinto sotto le sezioni agganciate e
   resterebbe nascosto dietro l'ultima. */
.impila .footer{
  z-index: 1;
}


/* ---------- 26. BARRA DI AVANZAMENTO ------------------ */
/* Una riga verticale sul bordo destro che si riempie mentre scendi: a colpo
   d'occhio quanto sito hai fatto e quanto ne resta. Il colore e' quello delle
   parole dell'eroe, ed e' l'unico posto in cui quel rosso torna a tutta
   altezza invece che a spizzichi.
   Sta al bordo estremo, a zero: il pulsante WhatsApp e' rientrato di 32px e
   la scritta SCORRI di 72, quindi non si toccano. Passa sopra la nav perche'
   una barra che si interrompe per 72px in cima non e' piu' una barra.
   L'altezza la scrive il JS in --avanzamento, da 0 a 1. Senza JS la variabile
   non esiste, il ripiego e' 0 e la barra resta invisibile: nessun elemento
   morto sullo schermo. */
.progresso{
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: clamp(2px, .28vw, 4px);
  z-index: var(--z-progresso);
  pointer-events: none;
  /* Il binario deve leggersi sia sulle sezioni chiare sia su quelle scure, e
     nessun grigio della tavolozza fa tutt'e due: questo e' neutro e
     trasparente, quindi si scurisce sul chiaro e si schiarisce sullo scuro. */
  background: rgba(127, 137, 147, .26);
}
.progresso__pieno{
  display: block;
  width: 100%;
  height: 100%;
  transform-origin: top;
  transform: scaleY(var(--avanzamento, 0));
  /* Il rosso delle tre parole, dall'alto verso il basso. Il caldo pieno
     (#FF5A2B) qui non entra: sulle sezioni chiare scenderebbe a 2.75:1,
     sotto il 3:1 che si chiede a un elemento non testuale. Queste due
     tengono 3.43:1 e 3.86:1 sul bone, 5.14:1 e 4.61:1 sul nero. */
  background: linear-gradient(to bottom, #FF1A1A, #E5321A);
  box-shadow: 0 0 12px rgba(255, 26, 26, .5);
}
/* Niente transizione: la barra deve stare incollata al dito, non inseguirlo.
   Per lo stesso motivo non c'e' niente da spegnere con "riduci animazioni":
   non e' un'animazione, e' la posizione in cui ti trovi. */
@media print{ .progresso{ display: none; } }
