/* ==========================================================================
   Purpure Punch - foglio di stile del sito
   ==========================================================================

   Rifatto da zero il 27/07/2026. La versione precedente e' nella storia
   git, ultimo commit prima di questo.

   Direzione: "il proiettore e lo specchio".
   Il marchio dice "It holds up a mirror" e non l'aveva mai detto con la
   grafica. Il sito e' una sala buia: un fascio di luce che gira piano,
   bollicine che salgono, grana di pellicola, vignettatura ai bordi.

   Cosa NON e' cambiato rispetto a prima: palette, caratteri, logo, tutti i
   testi e le 143 chiavi di traduzione. E' cambiata l'impaginazione e il
   movimento.

   ⚠ DUE REGOLE DA NON VIOLARE, tutte e due nate da guasti veri:

   1. Ogni animazione ARRIVA allo stato leggibile, non ci parte. Scritta al
      rovescio, con "meno movimento" attivo o con le animazioni spente, non
      diventa brutta: lascia il testo INVISIBILE. E' successo col menu su
      telefono, che si apriva vuoto.

   2. Il soggetto di un'animazione da scorrimento non puo' essere la cosa di
      cui stai cambiando posizione o misura: diventa insieme causa ed
      effetto, si assesta su un punto fisso e non si muove piu'. Quando
      serve, si da' un nome alla view-timeline sul CONTENITORE. E' successo
      due volte, sulla barra della roadmap e sul titolo della home.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. VARIABILI
   -------------------------------------------------------------------------- */

:root {
  /* Colori del marchio: identici a quelli del sito vero. */
  --pp-violet: #460196;
  --pp-violet-light: #6a01e0;
  --pp-violet-dark: #2d0060;
  --pp-pink: #f065a5;
  --pp-pink-light: #ff8ec4;

  --bg-primary: #0d0020;
  --bg-secondary: #130030;
  --bg-card: #1a0038;

  --text-primary: #f0e8ff;
  --text-sec: #c4a8e8;
  --text-muted: #a992c4;

  /* Tono aggiunto, non un colore nuovo del marchio: serve solo a dare
     profondita' di sala. E' lo stesso viola, portato quasi al nero. */
  --bg-deep: #070012;

  --line: rgba(160, 80, 255, 0.16);
  --line-soft: rgba(160, 80, 255, 0.08);
  --glass: rgba(26, 0, 56, 0.55);

  --ok: #00c853;
  --ok-light: #69f0ae;
  --amazon: #ff9900;
  --err: #f06565;

  --wrap: 1180px;
  --gutter: clamp(20px, 5vw, 56px);
  --nav-h: 76px;

  --ease: cubic-bezier(.2, .7, .2, 1);

  --sans: 'DM Sans', system-ui, sans-serif;
  --serif: 'Playfair Display', Georgia, serif;
}

/* --------------------------------------------------------------------------
   1. BASE
   -------------------------------------------------------------------------- */

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

html {
  scroll-behavior: smooth;
  /* La barra fissa copriva i titoli di sezione a ogni click sul menu: e' un
     difetto che il sito vero ha ancora. Qui e' corretto. */
  scroll-padding-top: calc(var(--nav-h) + 32px);
  background: var(--bg-deep);
}

body {
  margin: 0;
  font-family: var(--sans);
  font-weight: 400;
  color: var(--text-primary);
  background: var(--bg-deep);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--pp-pink);
  outline-offset: 3px;
  border-radius: 3px;
}

::selection { background: var(--pp-pink); color: #12002a; }

/* Barra di scorrimento in tinta: dettaglio piccolo, si nota subito. */
::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: var(--bg-deep); }
::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, var(--pp-violet), var(--pp-violet-dark));
  border-radius: 10px;
  border: 2px solid var(--bg-deep);
}
::-webkit-scrollbar-thumb:hover { background: var(--pp-violet-light); }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--pp-violet);
  color: #fff;
  padding: 12px 20px;
  border-radius: 0 0 10px 0;
  z-index: 2000;
  font-size: .9rem;
}
.skip-link:focus { left: 0; }

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* --------------------------------------------------------------------------
   2. LA SALA: grana, vignettatura, barra di lettura
   --------------------------------------------------------------------------
   Tre veli fissi, tutti pointer-events:none e tutti sotto la navbar.
   La grana e' FERMA: animare la posizione di uno sfondo a schermo intero
   vuol dire ridisegnare tutto lo schermo a ogni fotogramma, per sempre.
   -------------------------------------------------------------------------- */

/* Il pulviscolo nel fascio. Sta sopra gli sfondi ma sotto ogni contenuto. */
#particleCanvas {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .55;
}

.film-grain,
.film-vignette {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 900;
}

.film-grain {
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.film-vignette {
  background:
    radial-gradient(120% 90% at 50% 45%, transparent 42%, rgba(0, 0, 0, .55) 100%);
}

/* Il fascio di luce del proiettore: un cono che gira molto piano dietro
   tutto. Un solo elemento, solo transform, quindi gira sul compositore. */
.film-beam {
  position: fixed;
  top: -40vh;
  left: 50%;
  width: 150vmax;
  height: 150vmax;
  margin-left: -75vmax;
  pointer-events: none;
  z-index: 0;
  opacity: .5;
  background: conic-gradient(from 0deg at 50% 50%,
    transparent 0deg,
    rgba(106, 1, 224, .16) 18deg,
    transparent 42deg,
    transparent 190deg,
    rgba(240, 101, 165, .10) 210deg,
    transparent 240deg);
  filter: blur(38px);
  animation: beam-turn 64s linear infinite;
}
@keyframes beam-turn { to { rotate: 360deg; } }

/* Barra di avanzamento della lettura. Pura CSS, guidata dallo scorrimento.
   Se il browser non ha animation-timeline non si mostra affatto: una barra
   ferma a zero e' peggio di nessuna barra. */
.read-bar { display: none; }

@supports (animation-timeline: scroll()) {
  .read-bar {
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    z-index: 1100;
    transform-origin: 0 50%;
    background: linear-gradient(90deg, var(--pp-violet-light), var(--pp-pink), var(--pp-pink-light));
    animation: read-grow linear both;
    animation-timeline: scroll(root block);
  }
  @keyframes read-grow { from { scale: 0 1; } to { scale: 1 1; } }
}

/* --------------------------------------------------------------------------
   3. NAVBAR
   --------------------------------------------------------------------------
   Trasparente in cima, si compatta e si opacizza scendendo. Lo stato e'
   guidato dallo scorrimento in CSS: nessun listener, nessun ricalcolo.
   -------------------------------------------------------------------------- */

#navbar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 1000;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  background: transparent;
  border-bottom: 1px solid transparent;
}

.nav-inner {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  gap: 28px;
}

.nav-logo {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  transition: opacity .25s var(--ease);
}
.nav-logo:hover { opacity: .75; }
.nav-logo svg { display: block; }

.nav-links {
  list-style: none;
  display: flex;
  gap: 26px;
  margin: 0 0 0 auto;
  padding: 0;
}

.nav-links a {
  position: relative;
  text-decoration: none;
  font-size: .76rem;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-sec);
  padding-block: 6px;
  transition: color .25s var(--ease);
}
.nav-links a::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  height: 1px;
  width: 100%;
  background: var(--pp-pink);
  scale: 0 1;
  transform-origin: 0 50%;
  transition: scale .35s var(--ease);
}
.nav-links a:hover { color: var(--text-primary); }
.nav-links a:hover::after { scale: 1 1; }

.nav-controls { display: flex; align-items: center; gap: 14px; }

.lang-toggle {
  display: flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(13, 0, 32, .5);
}

.lang-btn {
  font-family: var(--sans);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .06em;
  padding: 5px 11px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: color .2s, background .2s;
}
.lang-btn:hover { color: var(--text-primary); }
.lang-btn.active {
  background: var(--pp-violet);
  color: #fff;
}

.hamburger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  padding: 0 9px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(13, 0, 32, .5);
  cursor: pointer;
}
.hamburger span {
  display: block;
  height: 1.5px;
  width: 100%;
  border-radius: 2px;
  background: var(--text-primary);
  transition: transform .3s var(--ease), opacity .2s;
}
.hamburger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.hamburger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.hamburger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

@supports (animation-timeline: scroll()) {
  #navbar {
    animation: nav-solid linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 140px;
  }
  @keyframes nav-solid {
    to {
      background: rgba(9, 0, 24, .82);
      border-bottom-color: var(--line-soft);
      backdrop-filter: blur(18px) saturate(1.2);
      -webkit-backdrop-filter: blur(18px) saturate(1.2);
    }
  }
}
/* Ripiego per i browser senza scroll-timeline: barra sempre opaca. Meno
   bella, ma il menu resta leggibile su qualsiasi sfondo. */
@supports not (animation-timeline: scroll()) {
  #navbar {
    background: rgba(9, 0, 24, .9);
    border-bottom-color: var(--line-soft);
    backdrop-filter: blur(18px);
  }
}

/* Menu mobile: entra in scala con le voci sfalsate. E' l'unico effetto del
   sito che vive SOLO sotto i 960px, dove tutto il resto si semplifica. */
.mobile-nav {
  position: fixed;
  inset: var(--nav-h) 0 auto 0;
  z-index: 999;
  display: none;
  flex-direction: column;
  padding: 20px var(--gutter) 30px;
  background: rgba(9, 0, 24, .96);
  backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--line);
}
.mobile-nav.open { display: flex; }

/* Le voci erano in Playfair a 1,6rem: su uno schermo da telefono sei titoli
   di quella misura sono un muro, e il menu diventava piu' importante della
   pagina che ci sta sotto. Un menu si legge di colpo, non si contempla. */
.mobile-nav a {
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: .02em;
  text-decoration: none;
  color: var(--text-primary);
  padding: 13px 0;
  border-bottom: 1px solid var(--line-soft);
}
.mobile-nav a:last-child { border-bottom: 0; }

/* ⚠ Lo stato di riposo e' VISIBILE, e l'entrata sfalsata sta tutta dentro
   i fotogrammi chiave.
   Prima le voci partivano da opacita' zero e le riportava su l'animazione:
   bastava che l'animazione non girasse e il menu si apriva VUOTO. E'
   successo davvero, in modalita' fotografia, che le animazioni le spegne.
   E' la stessa regola seguita ovunque nel resto del foglio, qui era
   l'unica eccezione ed era anche l'unico posto dove faceva danno. */
.mobile-nav.open a { animation: mob-in .45s var(--ease) both; }
.mobile-nav.open a:nth-child(1) { animation-delay: .04s; }
.mobile-nav.open a:nth-child(2) { animation-delay: .08s; }
.mobile-nav.open a:nth-child(3) { animation-delay: .12s; }
.mobile-nav.open a:nth-child(4) { animation-delay: .16s; }
.mobile-nav.open a:nth-child(5) { animation-delay: .2s; }
.mobile-nav.open a:nth-child(6) { animation-delay: .24s; }
@keyframes mob-in {
  from { opacity: 0; translate: 0 -14px; }
  to { opacity: 1; translate: 0 0; }
}

/* --------------------------------------------------------------------------
   4. TIPOGRAFIA
   -------------------------------------------------------------------------- */

h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -.02em;
  margin: 0;
  /* Su un sito trilingue conta doppio: le stringhe IT e ES sono piu' lunghe
     del 15-30% e sono proprio quelle che producono le righe orfane. */
  text-wrap: balance;
}
p { margin: 0; text-wrap: pretty; }

.section {
  position: relative;
  z-index: 1;
  padding-block: clamp(90px, 13vh, 160px);
}

/* Filo sottile fra una sezione e l'altra, con un punto di luce al centro. */
.section + .section::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  translate: -50% 0;
  width: min(100% - var(--gutter) * 2, var(--wrap));
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line), transparent);
}

.section-head { margin-bottom: clamp(44px, 6vw, 76px); }

.section-label {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--pp-pink);
  margin-bottom: 18px;
}
.section-label::before {
  content: '';
  width: 26px;
  height: 1px;
  background: var(--pp-pink);
  flex-shrink: 0;
}

.section-title {
  font-size: clamp(2.1rem, 5vw, 3.6rem);
  max-width: 17ch;
}

.section-note {
  margin-top: 20px;
  max-width: 56ch;
  color: var(--text-sec);
  font-size: 1rem;
}

/* --------------------------------------------------------------------------
   5. BOTTONI
   -------------------------------------------------------------------------- */

.btn-primary, .btn-secondary, .progetto-cta, .ms-cta {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  font-family: var(--sans);
  font-size: .84rem;
  font-weight: 600;
  letter-spacing: .02em;
  text-decoration: none;
  padding: 14px 28px;
  border-radius: 999px;
  border: 1px solid transparent;
  cursor: pointer;
  overflow: hidden;
  transition: color .3s var(--ease), border-color .3s var(--ease), translate .3s var(--ease);
}

.btn-primary {
  background: linear-gradient(120deg, var(--pp-violet), var(--pp-violet-light));
  color: #fff;
}
/* Il bagliore in hover e' uno pseudo-elemento in opacita', non una
   transizione su box-shadow: una sfocatura da 60px rifatta a ogni
   fotogramma e' la cosa piu' cara che si possa mettere su una scheda. */
.btn-primary::after {
  content: '';
  position: absolute;
  inset: -40%;
  background: radial-gradient(closest-side, rgba(255, 142, 196, .55), transparent);
  opacity: 0;
  transition: opacity .35s var(--ease);
}
.btn-primary:hover { translate: 0 -2px; }
.btn-primary:hover::after { opacity: 1; }
.btn-primary > * { position: relative; z-index: 1; }

.btn-secondary {
  background: transparent;
  border-color: var(--line);
  color: var(--text-primary);
}
.btn-secondary:hover {
  border-color: var(--pp-pink);
  color: var(--pp-pink-light);
  translate: 0 -2px;
}

.progetto-cta {
  padding: 12px 22px;
  font-size: .8rem;
  background: transparent;
  border-color: var(--line);
  color: var(--text-primary);
}
.progetto-cta:hover { border-color: var(--pp-pink); translate: 0 -2px; }

.cta-amazon {
  border-color: rgba(255, 153, 0, .45);
  color: var(--amazon);
}
.cta-amazon:hover {
  border-color: var(--amazon);
  background: rgba(255, 153, 0, .1);
  color: var(--amazon);
}
.amazon-mark { width: 17px; height: 17px; flex-shrink: 0; }

/* Spinto in fondo alla scheda: le schede senza prezzo lasciavano il
   pulsante a meta' altezza e le tre non finivano sulla stessa riga. */
.progetto-card .cta-disabled { margin-top: auto; align-self: flex-start; }

.cta-disabled {
  border-style: dashed;
  border-color: var(--line);
  color: var(--text-muted);
  cursor: default;
}
.cta-disabled:hover { translate: 0; border-color: var(--line); }

/* --------------------------------------------------------------------------
   6. MOTORE DI RIVELAZIONE
   --------------------------------------------------------------------------
   Tre livelli, in quest'ordine:
     1. senza JS e senza CSS moderno -> tutto visibile (stato di riposo)
     2. con JS (classe x-js) -> IntersectionObserver, come il sito vero
     3. con animation-timeline -> guidato dallo scorrimento, niente JS
   Il livello 3 non e' solo piu' fluido: e' anche l'unico che sopravvive al
   cambio lingua senza far ripartire niente sotto gli occhi, perche' e' una
   funzione della posizione e non di un evento gia' successo.
   -------------------------------------------------------------------------- */

.reveal { opacity: 1; }

.x-js .reveal {
  opacity: 0;
  translate: 0 40px;
  transition: opacity .85s var(--ease), translate .85s var(--ease);
}
.x-js .reveal.visible { opacity: 1; translate: 0 0; }
.x-js .reveal-delay-1 { transition-delay: .09s; }
.x-js .reveal-delay-2 { transition-delay: .18s; }
.x-js .reveal-delay-3 { transition-delay: .27s; }

@supports (animation-timeline: view()) {
  .x-js .reveal {
    opacity: 1;
    translate: 0 0;
    transition: none;
    animation: rise linear both;
    animation-timeline: view();
    animation-range: entry 6% cover 32%;
  }
  @keyframes rise {
    from { opacity: 0; translate: 0 44px; }
    to { opacity: 1; translate: 0 0; }
  }
}

/* --------------------------------------------------------------------------
   7. HERO
   -------------------------------------------------------------------------- */

#hero {
  position: relative;
  z-index: 1;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: calc(var(--nav-h) + 40px);
  /* Spazio in fondo per l'indicatore "scroll": con 40px finiva addosso alla
     terza statistica, e la scritta si leggeva sopra l'etichetta. */
  padding-bottom: 92px;
  overflow: hidden;
}

/* Qui c'era il marchio gigante di fondo, tagliato dal bordo destro. Tolto:
   ridotto a una filigrana al 5% e mozzato a meta', non leggeva come un
   marchio, leggeva come sporco dietro al testo. Un logo o si vede o non
   c'e': quello nella barra e quello nel footer bastano. */

.hero-glow {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  border-radius: 50%;
  filter: blur(90px);
}
.hero-glow.g1 {
  width: 46vw; height: 46vw;
  left: -12vw; top: 6vh;
  background: radial-gradient(circle, rgba(70, 1, 150, .55), transparent 68%);
}
.hero-glow.g2 {
  width: 38vw; height: 38vw;
  right: -8vw; bottom: -6vh;
  background: radial-gradient(circle, rgba(240, 101, 165, .3), transparent 68%);
}

.hero-content {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--pp-pink);
  margin-bottom: 26px;
}
.hero-eyebrow::before {
  content: '';
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--pp-pink);
  box-shadow: 0 0 12px var(--pp-pink);
  animation: blink 2.4s ease-in-out infinite;
}
@keyframes blink {
  0%, 100% { opacity: 1; scale: 1; }
  50% { opacity: .35; scale: .6; }
}

.hero-title {
  font-size: clamp(2.6rem, 8vw, 6.4rem);
  font-weight: 900;
  line-height: 1.02;
  letter-spacing: -.035em;
  margin: 0;
  max-width: 15ch;
  /* ⚠ Qui c'era il riflesso sul pavimento, ed e' stato tolto.
     Disegnava sotto l'ultima riga una copia rovesciata e sfumata a meta':
     un troncone di testo, appeso sotto al titolo. Misurando, il titolo non
     era tagliato da nessuna parte (provato a sei larghezze, dalle 480 alle
     1920, in tutte e tre le lingue, sui quattro lati); quel troncone pero'
     si legge come una riga tagliata, ed e' la stessa obiezione fatta alla
     citazione del manifesto mezza accesa.
     La regola che ne esce: su un testo da leggere, un effetto che ne mostra
     un pezzo a meta' perde sempre contro la leggibilita'. */
}

/* Ogni riga sta in una finestrella che taglia: il testo entra da sotto,
   come una didascalia di testa. Il figlio con data-i18n resta un elemento
   a se', quindi il cambio lingua ne riscrive il testo senza toccare
   l'impalcatura dell'effetto. */
/* ⚠ La finestrella che taglia serve alla comparsa, ma tagliava anche le
   lettere: con line-height 1.02 su Playfair, che ha le code lunghe, la
   "g" di "gia'" e la "q" di "qualcuno" venivano troncate di netto, e lo
   svolazzo della N corsiva di "Non" spariva a sinistra.

   Si allarga la zona visibile col padding e la si riprende col margine
   negativo: il testo resta dov'era, l'interlinea resta quella, e le code
   hanno il loro spazio. Serve su tutti e quattro i lati perche' il corsivo
   esce anche di fianco. */
.hl {
  display: block;
  overflow: hidden;
  /* .35em di lato, non .22em: quel valore bastava nelle prove locali ma
     online, col vero Playfair da Google Fonts, lo svolazzo della N e la
     coda della e finale restavano tagliati lo stesso. Il margine grande
     costa niente (la riga resta dov'era) e mette al riparo dalle
     differenze reali fra un font caricato e uno di prova. */
  padding: .04em .35em .22em;
  margin: 0 -.35em -.22em;
}
/* Anche con questo margine, un font vero puo' sempre sforare quanto un
   margine indovinato non prevede: e' successo di nuovo online col vero
   Playfair, con lo svolazzo della N che restava tagliato a meta'. Il
   ritaglio serve SOLO per la durata della tendina che fa entrare la riga;
   finita quella, il testo e' gia' fermo al suo posto e non c'e' piu' nessun
   motivo per tagliare nulla. pp.js aggiunge questa classe quando
   l'animazione line-up finisce davvero (initHeroSettle). */
.hl.hl-set { overflow: visible; }
.hl > * {
  display: inline-block;
  font-style: inherit;
}
/* 145% e non 104%: la finestrella adesso e' piu' alta della riga, e con il
   vecchio valore in partenza si vedeva spuntare la cima delle lettere. */
.x-js .hl > * {
  translate: 0 145%;
  animation: line-up .7s var(--ease) forwards;
}
/* Scaletta stretta apposta: finche' l'animazione gira, le righe si vedono
   per forza a meta', ed e' l'unico momento in cui il titolo sembra tagliato.
   Prima l'ultima riga partiva a mezzo secondo, e con la sua durata si
   arrivava a un secondo e mezzo di righe mozze a ogni ricarica. */
.x-js .hl:nth-of-type(1) > * { animation-delay: .05s; }
.x-js .hl:nth-of-type(2) > * { animation-delay: .12s; }
.x-js .hl:nth-of-type(3) > * { animation-delay: .19s; }
.x-js .hl:nth-of-type(4) > * { animation-delay: .26s; }
@keyframes line-up { to { translate: 0 0; } }

/* ⚠ Il gradiente NON finisce su --pp-violet-light (#6a01e0): e' un viola
   scuro, e su un fondo quasi nero l'ultima parola spariva. Finisce sul suo
   chiaro (#c084fc), che e' lo stesso colore gia' usato altrove nel sito.
   Su fondo scuro un gradiente va verso il chiaro, non verso il cupo. */
.hero-title em {
  font-style: italic;
  font-weight: 700;
  background: linear-gradient(100deg,
    var(--pp-pink-light) 0%,
    var(--pp-pink) 34%,
    #c084fc 100%) no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* ⚠ Il taglio della N e della e finale veniva da QUI, non dalla
     finestrella .hl: background-clip:text dipinge solo dentro la scatola
     dell'elemento, e lo svolazzo del corsivo di Playfair sporge fuori
     dalla scatola. La lettera c'e' tutta, e' il colore che si ferma al
     bordo: per questo allargare .hl non cambiava niente. Il padding
     allarga la zona dipinta fin sopra gli svolazzi, i margini negativi
     la ricompensano e la riga resta esattamente dov'era. */
  padding-inline: .3em;
  margin-inline: -.3em;
}
/* Era .46, cioe' grigio: la riga si leggeva a fatica. Resta piu' spenta
   delle altre, perche' e' li' per dare respiro fra due righe forti, ma
   adesso si legge. */
.hero-title .accent { color: rgba(240, 232, 255, .82); }
.hero-title .pink { color: var(--pp-pink); }

.hero-sub {
  margin-top: 34px;
  max-width: 48ch;
  font-size: 1.05rem;
  line-height: 1.75;
  color: var(--text-sec);
}

.hero-ctas {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 38px;
}

/* La striscia dei numeri in fondo all'hero: come i titoli di coda di un
   film, tutta su una riga, separata da fili sottili. Prima erano quattro
   riquadri dentro una scheda che galleggiava, e su telefono sparivano. */
.hero-strip {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--wrap);
  margin: clamp(50px, 8vh, 96px) auto 0;
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--line-soft);
}

.hero-stat {
  padding: 26px 18px 0 0;
  border-right: 1px solid var(--line-soft);
}
.hero-stat:last-child { border-right: 0; }

.hero-stat-num {
  font-family: var(--serif);
  font-size: clamp(1.9rem, 3.6vw, 3rem);
  font-weight: 900;
  line-height: 1;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.hero-stat:last-child .hero-stat-num {
  /* Lo zero sotto "Moralismo" e' la battuta dell'identita': si vede. */
  color: var(--pp-pink);
}
.hero-stat-label {
  margin-top: 9px;
  font-size: .68rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.scroll-indicator {
  position: absolute;
  left: 50%;
  bottom: 20px;
  translate: -50% 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  font-size: .62rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--text-muted);
  animation: nudge 2.6s ease-in-out infinite;
}
@keyframes nudge {
  0%, 100% { translate: -50% 0; opacity: .45; }
  50% { translate: -50% 9px; opacity: 1; }
}

/* L'hero sprofonda invece di scorrere via: gli sfondi corrono, il testo
   quasi no. Il testo che si muove tanto da' la nausea, ed e' l'errore
   piu' comune del parallasse. */
@supports (animation-timeline: view()) {
  /* ⚠ Il conteggio si aggancia a #hero, con un nome, e NON a `view()` sui
     singoli pezzi.

     Con `view()` ogni pezzo era il soggetto di se' stesso, e siccome li
     stiamo spostando la loro posizione era insieme causa ed effetto: si
     assestava su un punto fisso e non si muoveva piu'. Misurato: il blocco
     del titolo restava a opacita' 0,59 e spostato di 18px **a qualsiasi
     altezza di scorrimento**, cioe' il titolo si vedeva slavato gia'
     all'apertura della pagina.

     E' lo stesso identico errore della barra della roadmap. La regola vale
     una volta per tutte: il soggetto di un'animazione da scorrimento non
     puo' essere la cosa che stai spostando. */
  #hero {
    view-timeline-name: --palco;
    view-timeline-axis: block;
  }

  .x-js .hero-content,
  .x-js .hero-glow {
    animation: sink linear both;
    animation-timeline: --palco;
    /* "exit" e non "cover": exit comincia quando l'hero inizia a uscire dal
       bordo alto, cioe' allo scorrimento zero. Con "cover" l'animazione era
       gia' a meta' strada appena aperta la pagina. */
    animation-range: exit 0% exit 90%;
  }
  @keyframes sink { to { translate: 0 0; } }

  .x-js .hero-content { animation-name: sink-text; }
  @keyframes sink-text { to { translate: 0 -34px; opacity: .3; } }

  .x-js .hero-glow.g1 { animation-name: sink-g1; }
  @keyframes sink-g1 { to { translate: 0 90px; } }

  .x-js .hero-glow.g2 { animation-name: sink-g2; }
  @keyframes sink-g2 { to { translate: 0 -70px; } }
}

/* --------------------------------------------------------------------------
   8. MANIFESTO
   --------------------------------------------------------------------------
   L'effetto bandiera del sito. Le parole della citazione si accendono da
   sinistra a destra mentre la sezione attraversa la finestra.

   Fatto con background-clip:text e una percentuale animata: NON tocca mai i
   figli dell'elemento, quindi il cambio lingua non ha niente da distruggere.
   Spezzare il testo in span sarebbe stato l'altro modo, e sarebbe stato il
   pezzo piu' fragile del sito.
   -------------------------------------------------------------------------- */

#manifesto {
  position: relative;
  z-index: 1;
  padding-block: clamp(110px, 18vh, 210px);
  background: var(--bg-deep);
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   8bis. LE FOTO IN MOVIMENTO
   --------------------------------------------------------------------------
   Due sole, e sono due immagini del marchio che oggi stanno nella cartella
   senza essere usate da nessuna pagina: il volto a puzzle dietro il
   manifesto, i mocktail dietro la newsletter.

   Due elementi annidati apposta, e non uno:
     .scena  taglia, e fa la parallasse allo scorrimento (proprieta' translate)
     .scena img  fa il carrello lento, avanti e indietro (proprieta' scale)
   Se stessero sullo stesso elemento si contenderebbero la stessa proprieta'
   e una delle due si spegnerebbe.

   Le foto sono in WebP: quella dei mocktail pesava 1,5 MB in PNG e adesso
   pesa 89 KB. Un'immagine che si muove viene ridisegnata di continuo,
   tenerla pesante si paga due volte. Gli originali restano in immagini/.
   -------------------------------------------------------------------------- */

.scena {
  position: absolute;
  inset: -8% 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.scena img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Spenta e desaturata prima ancora del velo: cosi' la foto entra nella
     tavolozza del sito invece di litigarci. Una foto di cocktail lasciata
     brillare, su un sito che parla di alcol, direbbe anche la cosa
     sbagliata. */
  filter: brightness(.46) saturate(.72);
  /* Il carrello: si avvicina e torna indietro, senza mai fare uno scatto
     perche' va avanti e indietro invece di riavvolgersi. */
  animation: carrello 34s ease-in-out infinite alternate;
}
@keyframes carrello {
  from { scale: 1.04; translate: -1% 0; }
  to { scale: 1.2; translate: 1.5% -1.5%; }
}

/* Il velo, in due strati. Il primo sfuma i bordi nella pagina, cosi' la foto
   non ha un attacco netto in alto e in basso; il secondo scurisce il centro,
   che e' dove sta il testo.

   Sembra tanto, ed e' tanto apposta: il modo piu' rapido di rovinare una
   pagina e' mettere del testo bianco sopra una foto chiara e convincersi
   che si legga lo stesso perche' si sa gia' cosa c'e' scritto. */
.scena::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, var(--bg-deep), transparent 24%, transparent 76%, var(--bg-deep)),
    radial-gradient(92% 130% at 50% 48%, rgba(45, 0, 96, .66), rgba(7, 0, 18, .93) 74%);
}

@supports (animation-timeline: view()) {
  /* La foto scorre piu' piano della pagina: e' quello che le da' profondita'.
     Ottanta pixel in tutto, non trecento: una foto che vola dietro al testo
     e' un effetto che si guarda, non uno sfondo. */
  .x-js .scena {
    animation: scena-lenta linear both;
    animation-timeline: view();
    animation-range: cover 0% cover 100%;
  }
  @keyframes scena-lenta {
    from { translate: 0 -42px; }
    to { translate: 0 42px; }
  }
}

.manifesto-inner {
  position: relative;
  max-width: 1000px;
  margin-inline: auto;
  padding-inline: var(--gutter);
  text-align: center;
}

.manifesto-open-quote {
  display: block;
  font-family: var(--serif);
  font-size: clamp(6rem, 16vw, 13rem);
  line-height: .55;
  color: rgba(240, 101, 165, .16);
  margin-bottom: .12em;
  user-select: none;
}

.manifesto-quote {
  margin: 0;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.6rem, 4.4vw, 3.1rem);
  line-height: 1.45;
  letter-spacing: -.015em;
  /* ⚠ Tutta bianca, punto.
     Qui c'era la spazzolata: le parole si accendevano da sinistra a destra
     mentre la sezione attraversava lo schermo, e la parte non ancora accesa
     stava al 16% di bianco. Sulla carta e' un bell'effetto, dal vivo no:
     fermandosi a leggere, mezza citazione resta spenta e sembra un guasto,
     non una scelta. Su una frase da leggere, l'effetto perde contro la
     leggibilita' e va tolto. */
  color: #fff;
}

.manifesto-author {
  margin-top: 40px;
  font-size: .74rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.manifesto-author span { color: var(--pp-pink); }

/* --------------------------------------------------------------------------
   9. PROGETTI
   -------------------------------------------------------------------------- */

#progetti { background: var(--bg-primary); }

.progetti-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px;
}

.progetto-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 34px 30px 32px;
  border: 1px solid var(--line);
  border-radius: 22px;
  background:
    linear-gradient(180deg, rgba(26, 0, 56, .85), rgba(13, 0, 32, .85));
  overflow: hidden;
  transition: border-color .4s var(--ease), translate .4s var(--ease);
}
.progetto-card:hover { border-color: rgba(160, 80, 255, .38); translate: 0 -6px; }

/* Il riflettore che segue il puntatore. Le coordinate le scrive un solo
   ascoltatore sul contenitore della griglia, strozzato a un fotogramma. */
.progetto-card::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(360px circle at var(--mx, 50%) var(--my, 0%),
    rgba(106, 1, 224, .22), transparent 62%);
  opacity: 0;
  transition: opacity .4s var(--ease);
  pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
  .progetto-card:hover::before { opacity: 1; }
}

/* Il numero della scheda, in grande e in trasparenza. Da' ritmo a tre
   riquadri che altrimenti si somigliano tutti. */
.progetto-card::after {
  content: attr(data-num);
  position: absolute;
  right: 22px;
  top: 20px;
  font-family: var(--serif);
  font-size: 3.4rem;
  font-weight: 900;
  line-height: 1;
  color: rgba(160, 80, 255, .13);
  pointer-events: none;
}

.progetto-card > * { position: relative; z-index: 1; }

.progetto-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  align-self: flex-start;
  font-size: .64rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 5px 12px;
  border-radius: 999px;
  margin-bottom: 22px;
}
.status-live {
  color: var(--ok-light);
  background: rgba(0, 200, 83, .1);
  border: 1px solid rgba(0, 200, 83, .28);
}
.status-live::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--ok);
  box-shadow: 0 0 8px var(--ok);
  animation: blink 1.6s ease-in-out infinite;
}
.status-soon {
  color: rgba(190, 145, 255, .95);
  background: rgba(70, 1, 150, .22);
  border: 1px solid rgba(160, 80, 255, .25);
}

.progetto-type {
  font-size: .66rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 8px;
}

.progetto-title {
  font-size: 1.6rem;
  margin-bottom: 4px;
}

.progetto-subtitle {
  font-family: var(--serif);
  font-style: italic;
  font-size: .92rem;
  color: var(--pp-pink);
  margin-bottom: 16px;
}

.progetto-desc {
  font-size: .88rem;
  line-height: 1.72;
  color: var(--text-sec);
  margin-bottom: 22px;
}

.progetto-price {
  font-family: var(--serif);
  font-size: 1.7rem;
  font-weight: 700;
  color: var(--pp-pink-light);
  margin-top: auto;
  margin-bottom: 18px;
}
.progetto-price small {
  font-family: var(--sans);
  font-size: .68rem;
  font-weight: 400;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.lang-editions {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--line-soft);
}
.lang-editions-label {
  display: block;
  font-size: .64rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 10px;
}
.lang-editions-links { display: flex; gap: 8px; }
.lang-edition {
  font-family: var(--sans);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .06em;
  padding: 6px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: all .25s var(--ease);
}
.lang-edition:hover { color: var(--text-primary); border-color: var(--pp-pink); }
.lang-edition.current {
  background: rgba(240, 101, 165, .14);
  border-color: var(--pp-pink);
  color: var(--pp-pink-light);
}

/* --------------------------------------------------------------------------
   10. NEWSLETTER
   -------------------------------------------------------------------------- */

#newsletter {
  position: relative;
  background: var(--bg-deep);
  overflow: hidden;
}

/* La filigrana gigante: c'era anche prima ed e' una buona idea, qui e'
   solo dosata meglio e tagliata dal bordo. Sopra la foto, sotto al testo. */
#newsletter::before {
  z-index: 0;
  content: 'PP';
  position: absolute;
  right: -4vw;
  top: 50%;
  translate: 0 -50%;
  font-family: var(--serif);
  font-size: clamp(16rem, 34vw, 34rem);
  font-weight: 900;
  line-height: .8;
  color: rgba(70, 1, 150, .13);
  pointer-events: none;
  user-select: none;
}

.newsletter-inner {
  position: relative;
  z-index: 1;
  max-width: 640px;
  margin-inline: auto;
  padding-inline: var(--gutter);
  text-align: center;
}

.newsletter-icon {
  width: 58px; height: 58px;
  margin: 0 auto 28px;
  display: grid;
  place-items: center;
  border-radius: 18px;
  background: linear-gradient(135deg, var(--pp-violet), var(--pp-pink));
}

.newsletter-title {
  font-size: clamp(1.9rem, 4.4vw, 2.9rem);
  margin-bottom: 16px;
}

.newsletter-sub {
  font-size: 1rem;
  line-height: 1.7;
  color: var(--text-sec);
  margin-bottom: 32px;
}

/* Campo e pulsante dentro una pillola sola: un oggetto, non due. */
.newsletter-form {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(26, 0, 56, .6);
  transition: border-color .3s var(--ease), background .3s var(--ease);
}
.newsletter-form:focus-within {
  border-color: var(--pp-pink);
  background: rgba(26, 0, 56, .9);
}

.newsletter-input {
  flex: 1;
  min-width: 0;
  font-family: var(--sans);
  font-size: .92rem;
  padding: 13px 20px;
  border: 0;
  background: transparent;
  color: var(--text-primary);
}
.newsletter-input:focus { outline: none; }
.newsletter-input::placeholder { color: var(--text-muted); }

.newsletter-btn {
  flex-shrink: 0;
  font-family: var(--sans);
  font-size: .84rem;
  font-weight: 600;
  padding: 13px 28px;
  border: 0;
  border-radius: 999px;
  background: linear-gradient(120deg, var(--pp-violet), var(--pp-violet-light));
  color: #fff;
  cursor: pointer;
  transition: filter .25s var(--ease);
}
.newsletter-btn:hover { filter: brightness(1.18); }
.newsletter-btn:disabled { opacity: .55; cursor: wait; }

.newsletter-consent {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 9px;
  margin-top: 18px;
  text-align: left;
}
.newsletter-consent input {
  margin-top: 3px;
  width: 15px; height: 15px;
  accent-color: var(--pp-pink);
  flex-shrink: 0;
}
.newsletter-consent label {
  font-size: .76rem;
  line-height: 1.55;
  color: var(--text-muted);
}
.newsletter-consent a { color: var(--pp-pink); }

.newsletter-privacy {
  margin-top: 14px;
  font-size: .72rem;
  color: var(--text-muted);
}

.newsletter-message, .ebook-message {
  margin-top: 14px;
  font-size: .84rem;
  min-height: 1.3em;
}
.newsletter-message.success, .ebook-message.success { color: var(--ok-light); }
.newsletter-message.error, .ebook-message.error { color: var(--err); }

/* --------------------------------------------------------------------------
   11. RUBRICHE
   --------------------------------------------------------------------------
   Due nastri che scorrono piano in versi opposti. NON una sezione bloccata
   che scorre in orizzontale: sono sei riquadri da 200px, su un desktop ci
   stanno gia' tutti, e bloccare la pagina per mostrare cose che si vedevano
   gia' e' attrito e basta. Il nastro da' lo stesso senso di flusso senza
   rubare il controllo dello scorrimento.
   -------------------------------------------------------------------------- */

#rubriche {
  background: var(--bg-secondary);
  overflow: hidden;
}
#rubriche .section-head { padding-inline: var(--gutter); max-width: var(--wrap); margin-inline: auto; }

.rub-lane {
  display: flex;
  width: 100%;
  overflow: hidden;
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.rub-lane + .rub-lane { margin-top: 18px; }

.rub-track {
  display: flex;
  align-items: center;
  gap: clamp(40px, 5vw, 76px);
  padding-right: clamp(40px, 5vw, 76px);
  width: max-content;
  /* Piano. Piu' di un minuto per un giro: si deve poter leggere un nome
     senza inseguirlo. */
  animation: slide 78s linear infinite;
}
.rub-lane.back .rub-track { animation-direction: reverse; animation-duration: 94s; }
@keyframes slide { to { translate: -50% 0; } }

.rub-lane:hover .rub-track,
.rub-lane:focus-within .rub-track { animation-play-state: paused; }

/* Solo i loghi, senza riquadro.
   Erano dentro una scheda quadrata con fondo e bordo, ma sono marchi con lo
   sfondo trasparente: la scheda faceva da cornice a una cornice, e sei
   quadrati in fila pesavano piu' dei sei nomi che dovevano far leggere. */
.rubrica-item {
  flex-shrink: 0;
  display: block;
  opacity: .88;
  transition: opacity .4s var(--ease), scale .4s var(--ease);
}
.rubrica-item:hover { opacity: 1; scale: 1.06; }
/* ⚠ L'altezza va messa QUI, sull'immagine, non sul contenitore con un
   height:100% sopra: con il contenitore ad altezza automatica quel 100% non
   si risolve, l'immagine torna alla sua misura naturale e viene tagliata
   dalla corsia. */
.rubrica-item img {
  display: block;
  height: clamp(62px, 6.2vw, 92px);
  width: auto;
}

.rubriche-cta {
  margin-top: 44px;
  text-align: center;
}

/* --------------------------------------------------------------------------
   12. ABOUT
   -------------------------------------------------------------------------- */

#about { background: var(--bg-primary); }

.about-inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(34px, 6vw, 78px);
  align-items: center;
}

.about-box {
  position: relative;
  padding: clamp(34px, 4vw, 52px);
  border: 1px solid var(--line);
  border-radius: 24px;
  background:
    linear-gradient(150deg, rgba(70, 1, 150, .35), rgba(13, 0, 32, .7));
  overflow: hidden;
}
.about-box::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(80% 60% at 20% 0%, rgba(240, 101, 165, .16), transparent 70%);
  pointer-events: none;
}
.about-box > * { position: relative; z-index: 1; }

.about-big-quote {
  display: block;
  font-family: var(--serif);
  font-size: 5rem;
  line-height: .5;
  color: rgba(240, 101, 165, .3);
  margin-bottom: .18em;
  user-select: none;
}

.about-quote-text {
  margin: 0;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.1rem, 1.7vw, 1.35rem);
  line-height: 1.62;
  color: var(--text-primary);
}

.about-quote-author {
  margin-top: 24px;
  font-size: .7rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.about-text-col h2 {
  font-size: clamp(1.8rem, 3.2vw, 2.5rem);
  margin-bottom: 22px;
}
.about-text-col p {
  font-size: .95rem;
  line-height: 1.8;
  color: var(--text-sec);
  margin-bottom: 16px;
}

.about-pills { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 26px; }
.pill {
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .05em;
  padding: 7px 16px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--pp-pink-light);
  background: rgba(240, 101, 165, .07);
}

/* --------------------------------------------------------------------------
   13. FOOTER
   -------------------------------------------------------------------------- */

#footer {
  position: relative;
  z-index: 1;
  background: var(--bg-deep);
  border-top: 1px solid var(--line-soft);
  padding-top: 76px;
  overflow: hidden;
}

.footer-inner {
  position: relative;
  z-index: 1;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.footer-top {
  display: grid;
  grid-template-columns: 2fr 1fr 1.2fr;
  gap: clamp(30px, 5vw, 64px);
  padding-bottom: 54px;
}

.footer-brand p {
  font-size: .86rem;
  line-height: 1.7;
  color: var(--text-muted);
  max-width: 40ch;
}

.footer-social { display: flex; gap: 10px; margin-top: 22px; }
.social-btn {
  width: 38px; height: 38px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 12px;
  transition: border-color .25s var(--ease), background .25s var(--ease), translate .25s var(--ease);
}
.social-btn:hover {
  border-color: var(--pp-pink);
  background: rgba(240, 101, 165, .12);
  translate: 0 -2px;
}

.footer-col h4 {
  font-family: var(--sans);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-primary);
  margin-bottom: 18px;
}
.footer-col ul { list-style: none; margin: 0; padding: 0; }
.footer-col li { margin-bottom: 11px; }
.footer-col a {
  font-size: .85rem;
  text-decoration: none;
  color: var(--text-muted);
  transition: color .2s;
}
.footer-col a:hover { color: var(--pp-pink); }

.footer-disclaimer {
  margin-top: 22px;
  font-size: .72rem;
  line-height: 1.6;
  color: rgba(169, 146, 196, .7);
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px;
  padding-block: 26px;
  border-top: 1px solid var(--line-soft);
  font-size: .75rem;
  color: var(--text-muted);
}

/* Qui c'era il logo enorme in fondo, tagliato a meta' dal bordo della
   pagina. Tolto per lo stesso motivo di quello dell'hero: mozzato a meta' e
   al 5% di opacita' non era un marchio, era una macchia di lettere in fondo
   a tutte e cinque le pagine. Il logo del footer, quello vero e per intero,
   resta dov'e'. */

/* --------------------------------------------------------------------------
   14. PAGINE INTERNE: intestazione comune
   -------------------------------------------------------------------------- */

/* ⚠ Anche .legal-main: privacy.html e cookie.html usano quella classe e NON
   .page-main. Senza questa riga il titolo finisce sotto la barra fissa e il
   testo parte incollato al bordo sinistro dello schermo. */
.page-main,
.legal-main {
  position: relative;
  z-index: 1;
  max-width: var(--wrap);
  margin-inline: auto;
  padding: calc(var(--nav-h) + clamp(58px, 9vh, 110px)) var(--gutter) clamp(80px, 12vh, 140px);
}

.page-header {
  position: relative;
  margin-bottom: clamp(50px, 8vh, 90px);
  padding-bottom: clamp(34px, 5vh, 54px);
  border-bottom: 1px solid var(--line-soft);
}
.page-header h1 {
  font-size: clamp(2.3rem, 6vw, 4.2rem);
  font-weight: 900;
  letter-spacing: -.035em;
  max-width: 16ch;
  margin-bottom: 22px;
}
.page-header > p:last-child {
  max-width: 58ch;
  font-size: 1.02rem;
  line-height: 1.75;
  color: var(--text-sec);
}

/* --------------------------------------------------------------------------
   15. PAGINA PRODOTTI
   -------------------------------------------------------------------------- */

/* Una scheda per riga, non due. Con due colonne al testo restavano circa
   200px di larghezza: i titoli lunghi uscivano dalla scheda e il modulo
   dell'ebook veniva tagliato a meta'. In fascia larga il libro ha anche lo
   spazio per sembrare un libro. */
.prod-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}

.prod-card {
  position: relative;
  display: grid;
  grid-template-columns: 340px minmax(0, 1fr);
  border: 1px solid var(--line);
  border-radius: 24px;
  background: linear-gradient(180deg, rgba(26, 0, 56, .8), rgba(13, 0, 32, .85));
  overflow: hidden;
  transition: border-color .4s var(--ease), translate .4s var(--ease);
}
.prod-card:hover { border-color: rgba(160, 80, 255, .38); translate: 0 -5px; }

/* La copertina come oggetto fisico: prospettiva, dorso e riflesso.
   Il palcoscenico ha la prospettiva, il libro ci sta dentro. */
.prod-stage {
  position: relative;
  min-width: 0;
  display: grid;
  place-items: center;
  padding: 52px 30px;
  background:
    radial-gradient(70% 60% at 50% 25%, rgba(106, 1, 224, .3), transparent 70%),
    #0b0018;
  perspective: 1400px;
  overflow: hidden;
}

/* ⚠ NIENTE aspect-ratio qui, e niente object-fit sull'immagine.
   Prima c'era 3/4 con object-fit:cover, e le copertine vere non sono 3/4:
   sono 0,691 e 0,705. Il ritaglio mangiava l'8% e il 6% dell'altezza, meta'
   sopra e meta' sotto, cioe' proprio dove sta scritto il titolo del libro.
   Il sito vero questa trappola la conosceva gia': nel suo CSS c'e' un
   object-fit:contain con accanto il commento che spiega perche'.
   Qui l'altezza la decide l'immagine, e cosi' vale per qualsiasi copertina
   futura senza doverne misurare il rapporto. */
.prod-book {
  position: relative;
  width: 194px;
  transform-style: preserve-3d;
  rotate: y -19deg;
  transition: rotate .7s var(--ease), translate .7s var(--ease);
}
/* Solo la rotazione: la proprieta' translate qui e' occupata dal dondolio
   continuo, e un'animazione batte sempre una dichiarazione normale. */
.prod-card:hover .prod-book { rotate: y -9deg; }

.prod-book img,
.prod-book .prod-cover-placeholder {
  width: 100%;
  border-radius: 2px 5px 5px 2px;
  box-shadow: 14px 18px 40px rgba(0, 0, 0, .6);
}
/* L'altezza viene dall'immagine: la copertina si vede tutta, sempre. */
.prod-book img { height: auto; display: block; }
/* Il segnaposto invece un rapporto ce l'ha bisogno, non avendo dentro
   nessuna immagine che glielo detti. */
.prod-book .prod-cover-placeholder { aspect-ratio: 1 / 1.42; }
/* Due prodotti su quattro non hanno ancora una copertina. Il segnaposto e'
   fatto come una copertina cieca del marchio, non come un riquadro vuoto:
   un trattamento in rilievo applicato a meta' delle schede sembrerebbe un
   guasto invece di una scelta. */
.prod-book .prod-cover-placeholder {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 30px;
  padding: 26px;
  background: linear-gradient(140deg, rgba(70, 1, 150, .62), rgba(20, 0, 44, .95) 78%);
  border: 1px solid var(--line);
}
.prod-book .prod-cover-placeholder::after {
  content: '';
  position: absolute;
  inset: 13px;
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: 2px;
}
.ph-logo { width: 72%; height: auto; }

/* Il dorso: una lastra sottile ruotata sul bordo sinistro. Senza questo il
   libro resta una figurina, con questo diventa un oggetto. */
.prod-book::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  width: 15px;
  height: 100%;
  background: linear-gradient(90deg, #1c0033, #40007a 40%, #14002a);
  transform-origin: left center;
  rotate: y -90deg;
  border-radius: 2px 0 0 2px;
}
/* Il riflesso che passa sulla copertina. */
.prod-book::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 2px 5px 5px 2px;
  background: linear-gradient(105deg,
    transparent 32%, rgba(255, 255, 255, .16) 46%, transparent 60%);
  pointer-events: none;
  translate: -18% 0;
  transition: translate .8s var(--ease);
}
.prod-card:hover .prod-book::after { translate: 22% 0; }

/* --- Il telefono di AlcoolCheck ------------------------------------------
   AlcoolCheck e' un'app, non un libro: sulle altre tre schede il segnaposto
   e' una copertina, qui e' un telefono. Stessa prospettiva e stesso
   dondolio dei libri, cosi' le quattro schede restano una famiglia.
   Lo schermo e' uno SCHEMA, non una finta schermata: l'app non esiste
   ancora, e una schermata finta qualcuno la scambia per il prodotto vero. */

.prod-phone {
  position: relative;
  width: 128px;
  aspect-ratio: 9 / 19;
  padding: 5px;
  border-radius: 22px;
  background: linear-gradient(150deg, #4a1a78, #14002c 62%);
  border: 1px solid rgba(200, 140, 255, .38);
  box-shadow: 14px 18px 40px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .14);
  rotate: y -19deg;
  transition: rotate .7s var(--ease);
  animation: dondolo 7.5s ease-in-out infinite;
}
.prod-card:hover .prod-phone { rotate: y -9deg; }

.phone-schermo {
  position: relative;
  height: 100%;
  padding: 22px 13px 16px;
  border-radius: 17px;
  background: radial-gradient(130% 70% at 50% 0%, rgba(106, 1, 224, .55), #0b0018 72%);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 9px;
}
/* Il riflesso che scorre sul vetro, come sulle copertine. */
.phone-schermo::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 34%, rgba(255, 255, 255, .14) 48%, transparent 62%);
  translate: -18% 0;
  transition: translate .8s var(--ease);
}
.prod-card:hover .phone-schermo::after { translate: 22% 0; }

.phone-tacca {
  position: absolute;
  top: 8px;
  left: 50%;
  translate: -50% 0;
  width: 32px;
  height: 4px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .22);
}
.phone-marchio {
  width: 34px;
  height: 3px;
  border-radius: 3px;
  background: rgba(240, 101, 165, .55);
  margin-bottom: 2px;
}
/* Il quadrante: al posto del numero che l'app calcolera'. */
.phone-quadrante {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 2px solid rgba(240, 101, 165, .5);
  box-shadow: inset 0 0 14px rgba(240, 101, 165, .3), 0 0 12px rgba(240, 101, 165, .18);
  margin-bottom: 4px;
}
.phone-riga {
  width: 74%;
  height: 5px;
  border-radius: 5px;
  background: rgba(200, 140, 255, .26);
}
.phone-riga.media { width: 52%; }
.phone-tasto {
  margin-top: 8px;
  width: 78%;
  height: 15px;
  border-radius: 15px;
  background: linear-gradient(120deg, var(--pp-violet), var(--pp-violet-light));
  opacity: .8;
}

/* min-width:0 e' obbligatorio: un elemento di griglia parte da
   min-width:auto, cioe' non scende mai sotto la larghezza minima del suo
   contenuto, e un titolo lungo o un modulo largo sfondano la scheda invece
   di andare a capo. Con overflow:hidden sopra, il testo veniva tagliato. */
.prod-body {
  min-width: 0;
  padding: 40px 42px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.prod-body > * { max-width: 62ch; }

.prod-type {
  font-size: .66rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 8px;
}
.prod-title { font-size: 1.55rem; margin-bottom: 4px; }
.prod-sub {
  font-family: var(--serif);
  font-style: italic;
  font-size: .92rem;
  color: var(--pp-pink);
  margin-bottom: 16px;
}
.prod-desc {
  font-size: .88rem;
  line-height: 1.72;
  color: var(--text-sec);
  margin-bottom: 20px;
}
.prod-price {
  font-family: var(--serif);
  font-size: 1.7rem;
  font-weight: 700;
  color: var(--pp-pink-light);
  margin-top: auto;
  margin-bottom: 18px;
}
.prod-price small {
  font-family: var(--sans);
  font-size: .68rem;
  font-weight: 400;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.prod-free { color: var(--ok-light); }

.prod-card .progetto-cta { align-self: flex-start; }

.ebook-form {
  width: min(100%, 430px);
  display: flex;
  gap: 6px;
  padding: 5px;
  margin-top: 6px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(13, 0, 32, .6);
  transition: border-color .3s var(--ease);
}
.ebook-form:focus-within { border-color: var(--pp-pink); }
.ebook-form input {
  flex: 1;
  min-width: 0;
  font-family: var(--sans);
  font-size: .86rem;
  padding: 11px 16px;
  border: 0;
  background: transparent;
  color: var(--text-primary);
}
.ebook-form input:focus { outline: none; }
.ebook-form input::placeholder { color: var(--text-muted); }
.ebook-form button {
  flex-shrink: 0;
  font-family: var(--sans);
  font-size: .8rem;
  font-weight: 600;
  padding: 11px 22px;
  border: 0;
  border-radius: 999px;
  background: linear-gradient(120deg, var(--pp-violet), var(--pp-violet-light));
  color: #fff;
  cursor: pointer;
  transition: filter .25s;
}
.ebook-form button:hover { filter: brightness(1.18); }
.ebook-form button:disabled { opacity: .55; cursor: wait; }

.prod-card .newsletter-consent { justify-content: flex-start; margin-top: 12px; }

/* --------------------------------------------------------------------------
   16. PAGINA ROADMAP
   -------------------------------------------------------------------------- */

.rm-section-title {
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  margin-bottom: 12px;
}
.rm-section-note {
  max-width: 58ch;
  font-size: .95rem;
  line-height: 1.75;
  color: var(--text-sec);
  margin-bottom: 34px;
}

.rm-next { margin-bottom: clamp(70px, 10vh, 120px); }

.rm-next-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}

.rm-next-card {
  padding: 30px 28px;
  border: 1px dashed var(--line);
  border-radius: 20px;
  background: rgba(26, 0, 56, .45);
  transition: border-color .35s var(--ease);
}
.rm-next-card:hover { border-color: rgba(160, 80, 255, .4); }

.ms-badge {
  display: inline-block;
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 4px 11px;
  border-radius: 999px;
  margin-bottom: 14px;
}
.badge-soon {
  color: rgba(190, 145, 255, .95);
  background: rgba(70, 1, 150, .25);
  border: 1px solid rgba(160, 80, 255, .25);
}
.badge-done {
  color: var(--ok-light);
  background: rgba(0, 200, 83, .1);
  border: 1px solid rgba(0, 200, 83, .26);
}

.ms-title { font-size: 1.22rem; margin-bottom: 10px; }
.ms-desc {
  font-size: .88rem;
  line-height: 1.75;
  color: var(--text-sec);
}

.rm-year {
  font-family: var(--serif);
  font-size: 2.6rem;
  font-weight: 900;
  color: rgba(240, 101, 165, .42);
  margin: 54px 0 22px;
  padding-left: 76px;
  letter-spacing: -.02em;
}
.rm-year:first-child { margin-top: 0; }

/* La linea del tempo si riempie mentre si scorre. E' l'unico effetto del
   sito che vuol dire qualcosa invece di decorare: scendere e' andare
   indietro nel tempo, e la barra che avanza lo dice.

   Due pezzi, e servono tutti e due:
     ::before  la GUIDA, ferma e tenue, dice dove arrivera'
     ::after   il RIEMPIMENTO, che cresce dall'alto
   Prima c'era solo il secondo, e con un gradiente che diventava viola scuro
   a meta' e poi svaniva: su fondo scuro la meta' inferiore era invisibile,
   quindi non si vedeva ne' la barra ne' il fatto che si stesse muovendo. */
.rm-timeline {
  position: relative;
  padding-left: 76px;
}

.rm-timeline::before,
.rm-timeline::after {
  content: '';
  position: absolute;
  left: 26px;
  top: 6px;
  bottom: 6px;
  width: 3px;
  border-radius: 3px;
}

/* La linea, sempre tutta visibile. */
.rm-timeline::before {
  z-index: 0;
  background: linear-gradient(180deg,
    var(--pp-pink),
    var(--pp-violet-light) 42%,
    rgba(160, 80, 255, .38));
}

/* La cometa: un lampo che scende lungo la linea, in continuo e senza
   agganci allo scorrimento. Non e' un riempimento: la linea sotto c'e'
   sempre tutta, questo ci passa sopra e basta.

   E' fatta muovendo la POSIZIONE DELLO SFONDO, non l'elemento: l'elemento
   resta alto quanto la linea e fermo dov'e', quindi non c'e' nessuna
   geometria che cambia e niente che possa mordersi la coda. */
.rm-timeline::after {
  z-index: 1;
  background-image: linear-gradient(180deg,
    transparent 0,
    rgba(240, 101, 165, .85) 34%,
    #fff 50%,
    rgba(240, 101, 165, .85) 66%,
    transparent 100%);
  background-size: 100% 240px;
  background-repeat: no-repeat;
  filter: drop-shadow(0 0 7px rgba(240, 101, 165, .85));
  animation: cometa 5.2s linear infinite;
}
@keyframes cometa {
  from { background-position-y: -240px; }
  to { background-position-y: calc(100% + 240px); }
}

/* ⚠ I pallini verdi e le tacche dei mesi vanno SOPRA la linea.
   Senza questo non e' una questione di gusto ma di ordine di disegno: lo
   pseudo-elemento ::after di un contenitore viene disegnato DOPO i suoi
   figli, quindi la cometa passava davanti ai pallini e li copriva. */
.rm-row { z-index: 2; }

.rm-row { position: relative; margin-bottom: 22px; }
.rm-row::before {
  content: '';
  position: absolute;
  left: -56px;
  top: 26px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--pp-violet-light);
  box-shadow: 0 0 0 4px rgba(106, 1, 224, .18);
}
.rm-row.is-done::before {
  background: var(--ok);
  box-shadow: 0 0 0 4px rgba(0, 200, 83, .18);
}

.rm-month {
  position: absolute;
  left: -76px;
  top: 18px;
  width: 0;
  font-size: .68rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-muted);
  transform-origin: right center;
  rotate: -90deg;
  translate: -14px 0;
  white-space: nowrap;
  text-align: right;
}

.ms-card {
  padding: 26px 28px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: rgba(26, 0, 56, .5);
  transition: border-color .35s var(--ease), translate .35s var(--ease);
}
.ms-card:hover { border-color: rgba(160, 80, 255, .38); translate: 5px 0; }

.ms-cta {
  margin-top: 16px;
  padding: 9px 18px;
  font-size: .76rem;
  border-color: var(--line);
  color: var(--text-primary);
}

/* --------------------------------------------------------------------------
   17. PAGINE LEGALI
   -------------------------------------------------------------------------- */

.legal-main { max-width: 880px; }

.legal-main h1 {
  font-size: clamp(2rem, 4.4vw, 3.2rem);
  font-weight: 900;
  letter-spacing: -.03em;
  margin-bottom: 10px;
}
/* "Last updated: ..." e' il primo paragrafo dopo il titolo. */
.legal-main h1 + p {
  font-size: .78rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 34px;
}
.legal-box {
  padding: clamp(26px, 4vw, 44px);
  border: 1px solid var(--line);
  border-radius: 22px;
  background: rgba(26, 0, 56, .42);
}
.legal-main h2 {
  font-size: 1.32rem;
  color: var(--pp-pink-light);
  margin: 40px 0 14px;
  padding-top: 22px;
  border-top: 1px solid var(--line-soft);
}
.legal-main h2:first-of-type { margin-top: 0; padding-top: 0; border-top: 0; }
.legal-main h3 {
  font-family: var(--sans);
  font-size: .95rem;
  font-weight: 600;
  margin: 22px 0 8px;
}
.legal-main p, .legal-main li {
  font-size: .93rem;
  line-height: 1.85;
  color: var(--text-sec);
}
.legal-main p { margin-bottom: 14px; }
.legal-main ul { padding-left: 20px; margin-bottom: 16px; }
.legal-main li { margin-bottom: 7px; }
.legal-main a { color: var(--pp-pink); }

.legal-main table {
  width: 100%;
  border-collapse: collapse;
  margin: 18px 0 24px;
  font-size: .86rem;
}
.legal-main th, .legal-main td {
  padding: 11px 13px;
  border: 1px solid var(--line-soft);
  text-align: left;
  color: var(--text-sec);
}
.legal-main th {
  font-size: .72rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-primary);
  background: rgba(70, 1, 150, .2);
}

/* --------------------------------------------------------------------------
   18. TRANSIZIONI FRA PAGINE
   --------------------------------------------------------------------------
   Tenute CORTE apposta. L'inglese sta nell'HTML e la traduzione arriva col
   JS: una transizione lunga tiene fermo il fotogramma inglese e fa vedere
   lo scatto in italiano. Tre decimi sono gia' troppi, qui sono due.
   -------------------------------------------------------------------------- */

@view-transition { navigation: auto; }

::view-transition-old(root) { animation: vt-out .18s ease both; }
::view-transition-new(root) { animation: vt-in .22s ease both; }
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-in { from { opacity: 0; } }

/* --------------------------------------------------------------------------
   19. LARGHEZZE
   -------------------------------------------------------------------------- */

@media (max-width: 1080px) {
  .progetti-grid { grid-template-columns: 1fr; }
  .prod-card { grid-template-columns: 260px minmax(0, 1fr); }
  .prod-book { width: 160px; }
  .prod-phone { width: 112px; }
  .prod-body { padding: 32px 30px; }
}

@media (max-width: 960px) {
  .nav-links { display: none; }
  .hamburger { display: flex; }
  .nav-inner { justify-content: space-between; }
  .nav-controls { margin-left: auto; }

  .hero-title { margin-bottom: 10px; }

  .hero-strip { grid-template-columns: repeat(2, 1fr); }
  .hero-stat:nth-child(2) { border-right: 0; }
  .hero-stat:nth-child(3), .hero-stat:nth-child(4) {
    border-top: 1px solid var(--line-soft);
    margin-top: 18px;
    padding-top: 22px;
  }

  /* Il sito vero qui nasconde la citazione "chi siamo" con display:none.
     E' un pezzo di testo vero, la frase piu' forte del marchio, e chi
     arriva da telefono non la legge mai. Qui va sopra, non via. */
  .about-inner { grid-template-columns: 1fr; }
  .rm-next-grid { grid-template-columns: 1fr; }
  .footer-top { grid-template-columns: 1fr 1fr; }
  .footer-brand { grid-column: 1 / -1; }
}

@media (max-width: 720px) {
  :root { --nav-h: 66px; }
  .prod-card { grid-template-columns: 1fr; }
  .prod-stage { padding: 44px 20px 34px; }
  .prod-book { width: 132px; }
  .prod-phone { width: 104px; }
  .prod-body { padding: 28px 24px; }

  .newsletter-form { flex-direction: column; border-radius: 20px; padding: 8px; }
  .newsletter-input { width: 100%; text-align: center; }
  .newsletter-btn { width: 100%; }

  .rm-timeline { padding-left: 34px; }
  .rm-year { padding-left: 34px; font-size: 2rem; }
  .rm-timeline::before { left: 5px; }
  .rm-row::before { left: -34px; }
  /* Il mese torna orizzontale: ruotato di 90 gradi, su schermo stretto,
     finiva addosso alla linea. */
  .rm-month {
    position: static;
    width: auto;
    rotate: none;
    translate: 0;
    text-align: left;
    margin-bottom: 8px;
  }
  .ms-card:hover { translate: 0; }

  .footer-top { grid-template-columns: 1fr; }
  .footer-bottom { flex-direction: column; gap: 6px; }
}

@media (max-width: 560px) {
  .hero-strip { grid-template-columns: 1fr 1fr; }
  #newsletter::before { font-size: 13rem; }
  .about-box { padding: 28px 24px; }
}

/* Sotto i 420px (la maggior parte dei telefoni Android, e gli iPhone piu'
   vecchi) logo, selettore lingua e hamburger insieme non ci stanno: la riga
   sfora a destra e l'hamburger finisce mezzo fuori schermo, invisibile in
   qualsiasi test fatto a 1440px. Qui si stringe, non si toglie nulla. */
@media (max-width: 420px) {
  .nav-logo svg { width: 128px; height: 23px; }
  .nav-inner { gap: 16px; }
  .nav-controls { gap: 8px; }
  .lang-btn { padding: 4px 8px; }
  .hamburger { width: 36px; height: 36px; padding: 0 7px; }
}

/* --------------------------------------------------------------------------
   19bis. PIU' MOVIMENTO
   --------------------------------------------------------------------------
   Tutto quello che e' stato aggiunto nel secondo giro. Sta in fondo apposta:
   cosi' si vede a colpo d'occhio cosa costa in piu' rispetto alla prima
   versione, e togliendo questo blocco si torna indietro.
   -------------------------------------------------------------------------- */

/* --- La torcia -----------------------------------------------------------
   Una luce morbida che segue il puntatore su tutta la pagina, come una
   pila in una stanza buia. Un elemento solo, due variabili, nessun
   ridisegno di layout: si muove sul compositore. */

.torcia {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(340px circle at var(--tx, -999px) var(--ty, -999px),
    rgba(160, 80, 255, .13), rgba(240, 101, 165, .05) 45%, transparent 72%);
}

/* --- I titoli, parola per parola ----------------------------------------
   La frase intera resta nel DOM invisibile (.x-sr) per gli screen reader e
   per il trova-nella-pagina; le parole visibili sono aria-hidden, cosi'
   nessuno si sente leggere dodici frammenti staccati. */

.x-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.x-split-on { position: relative; }
.x-w { display: inline-block; }

@supports (animation-timeline: view()) {
  .x-js .x-split-on .x-w {
    opacity: 0;
    animation: word-in linear both;
    animation-timeline: view();
    /* La scaletta e' nel RANGE, non nel delay: cosi' resta agganciata alla
       posizione invece che al tempo, e non riparte al cambio lingua. */
    animation-range: entry calc(6% + var(--i) * 4%) entry calc(50% + var(--i) * 4%);
  }
  @keyframes word-in {
    from { opacity: 0; translate: 0 .42em; filter: blur(7px); }
    to { opacity: 1; translate: 0 0; filter: blur(0); }
  }
}

/* --- I numeri dell'hero -------------------------------------------------- */

/* La ricaduta a zero sotto "Moralismo": il contatore sale, ci ripensa e
   torna secco. Questa e' la scrollata di spalle finale. */
.hero-stat-num.zero-fatto { animation: nope .5s var(--ease); }
@keyframes nope {
  0%, 100% { translate: 0 0; }
  28% { translate: -4px 0; }
  62% { translate: 4px 0; }
}

/* --- Schede: profondita' vera -------------------------------------------- */

.progetti-grid, .prod-grid { perspective: 1400px; }

.progetto-card, .prod-card {
  /* La transizione fa da ammortizzatore: senza, l'inclinazione insegue il
     puntatore un fotogramma alla volta e sembra incollata. */
  transition: border-color .4s var(--ease), translate .4s var(--ease), transform .3s var(--ease);
}

/* --- Il manifesto entra come una scena nuova -----------------------------
   La sezione arriva rimpicciolita e con gli angoli tondi, e si apre a tutta
   larghezza mentre entra: sembra che una scena scivoli sopra la precedente
   invece di scorrere via insieme a lei. */

@supports (animation-timeline: view()) {
  .x-js #manifesto {
    animation: scena linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 92%;
  }
  @keyframes scena {
    from { scale: .9; border-radius: 34px; }
    to { scale: 1; border-radius: 0; }
  }

  /* I pallini della roadmap scattano quando la loro tappa entra. */
  .x-js .rm-row::before {
    animation: pallino var(--ease) both;
    animation-timeline: view();
    animation-range: entry 16% entry 54%;
  }
  @keyframes pallino {
    from { scale: 0; }
    to { scale: 1; }
  }
}

/* --- Il lampo sui bottoni ------------------------------------------------ */

.btn-primary::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 36%, rgba(255, 255, 255, .3) 50%, transparent 64%);
  translate: -130% 0;
  transition: translate .75s var(--ease);
  pointer-events: none;
}
.btn-primary:hover::before { translate: 130% 0; }

/* --- L'onda della busta -------------------------------------------------- */

.newsletter-icon { position: relative; }
.newsletter-icon::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 1px solid var(--pp-pink);
  animation: onda 3s ease-out infinite;
  pointer-events: none;
}
@keyframes onda {
  from { scale: 1; opacity: .65; }
  to { scale: 1.8; opacity: 0; }
}

/* --- I libri respirano --------------------------------------------------- */

.prod-book { animation: dondolo 7.5s ease-in-out infinite; }
@keyframes dondolo {
  0%, 100% { translate: 0 0; }
  50% { translate: 0 -10px; }
}

/* --------------------------------------------------------------------------
   20. MENO MOVIMENTO
   --------------------------------------------------------------------------
   Chi lo chiede vede il sito fermo, non il sito vuoto: ogni animazione qui
   sopra arriva allo stato leggibile, quindi saltare alla fine e' sicuro.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    animation-timeline: none !important;
  }

  .x-js .reveal { opacity: 1 !important; translate: 0 0 !important; }
  .x-js .hl > * { translate: 0 0 !important; }
  .x-js .hl { overflow: visible !important; }
  .rm-timeline::after { display: none !important; }
  .x-js .hero-content { opacity: 1 !important; translate: 0 0 !important; }

  #particleCanvas, .film-beam, .film-grain, .read-bar, .torcia { display: none !important; }
  .rub-track { animation: none !important; }
  .newsletter-icon::after { display: none !important; }
  .prod-book, .prod-phone { animation: none !important; translate: 0 0 !important; }
  .scena img { animation: none !important; scale: 1.06 !important; translate: 0 0 !important; }
  .x-js .scena { translate: 0 0 !important; }
  .x-js .x-split-on .x-w { opacity: 1 !important; translate: 0 0 !important; filter: none !important; }
  .x-js #manifesto { scale: 1 !important; border-radius: 0 !important; }
  .x-js .rm-row::before { scale: 1 !important; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) {
    animation: none !important;
  }
}

/* --------------------------------------------------------------------------
   21. MODALITA' FOTOGRAFIA
   --------------------------------------------------------------------------
   Si accende con ?stills=1 nell'indirizzo, e la usa lo script che fa gli
   screenshot a pagina intera.

   Serve perche' le animazioni guidate dallo scorrimento sono una funzione
   della posizione: lo script scorre fino in fondo, TORNA IN CIMA e poi
   scatta, quindi tutto si riazzererebbe e la foto uscirebbe mezza vuota.
   Non e' un guasto della pagina, e' come funziona la cattura.
   -------------------------------------------------------------------------- */

[data-x-shots] *, [data-x-shots] *::before, [data-x-shots] *::after {
  animation-timeline: none !important;
  animation: none !important;
  transition: none !important;
}
[data-x-shots] .reveal { opacity: 1 !important; translate: 0 0 !important; }
[data-x-shots] .hl > * { translate: 0 0 !important; }
[data-x-shots] .hl { overflow: visible !important; }
[data-x-shots] .hero-content { opacity: 1 !important; translate: 0 0 !important; }
[data-x-shots] .rm-timeline::after { animation: none !important; background-position-y: 34% !important; }
[data-x-shots] #navbar {
  background: rgba(9, 0, 24, .88) !important;
  border-bottom-color: var(--line-soft) !important;
}
[data-x-shots] .x-w { opacity: 1 !important; translate: 0 0 !important; filter: none !important; }
[data-x-shots] #manifesto { scale: 1 !important; border-radius: 0 !important; }
[data-x-shots] .rm-row::before { scale: 1 !important; }
[data-x-shots] .prod-book, [data-x-shots] .prod-phone { translate: 0 0 !important; }
[data-x-shots] .scena img { scale: 1.06 !important; translate: 0 0 !important; }
[data-x-shots] .scena { translate: 0 0 !important; }
[data-x-shots] .torcia { display: none !important; }
