/* NAPIX Labs · effetti della home e delle transizioni (migliorie 16, 17, 18, 25 del 20/10/2026).
   Solo CSS del browser, nessuna libreria. Con moto ridotto (html.fermo o prefers-reduced-motion) niente movimento.
   16 · la foto del riquadro «vola» nell'apertura della soluzione (nome foto-volo, lo mette viaggio/navigazione.js).
   17 · il cambio chiaro/scuro si apre a cerchio dal tasto (html.vt-tema, lo mette comune.js).
   18 · il titolo d'apertura della home si compone riga per riga: il testo è nel DOM e dipinto da subito
        (opacità minima, mai 0, così la misura di Google lo conta); html.viaggiato = la
        home è arrivata con la navigazione continua → nessuna composizione (solo la prima pagina della visita).
   25 · «Cosa facciamo» come in una rivista: foto, nome, riga e «Scopri ›» sulla stessa linea in ogni riquadro.
   26 · (titolare 24/10, «più dinamico, effetto wow») il movimento legato allo SCORRIMENTO, CSS nativo
        (animation-timeline: view(), gira fuori dal thread principale): ogni blocco entra a modo suo — i riquadri si
        alzano in prospettiva uno dopo l'altro, le foto si aprono dal centro e scorrono più lente del testo
        (parallasse), il testo accanto arriva dal suo lato, i passi e i siti fatti in cascata, la foto d'apertura delle
        soluzioni si allontana appena uscendo. Senza supporto del browser, con moto ridotto o senza JS: tutto fermo e
        visibile come prima (il contenuto non dipende mai dall'animazione). Solo transform/opacità/clip-path: CLS 0. */

/* ── 18 · titolo riga per riga ── */
.riga-tit { display: block; }
@media screen and (prefers-reduced-motion: no-preference) {
  html.volo:not(.viaggiato) .apertura .riga-tit { animation: compone-riga 620ms cubic-bezier(.2, .7, .2, 1) 80ms both; }
  html.volo:not(.viaggiato) .apertura .riga-tit + .riga-tit { animation-delay: 200ms; }
  html.volo:not(.viaggiato) .apertura .frase { animation: compone-riga 620ms cubic-bezier(.2, .7, .2, 1) 320ms both; }
}
@keyframes compone-riga { from { opacity: .01; transform: translateY(.42em); } to { opacity: 1; transform: none; } }

/* ── 25 · riquadri allineati come in una rivista (sotto-griglia); senza supporto resta l'impaginazione di comune.css ── */
@supports (grid-template-rows: subgrid) {
  @media screen {
    .riquadri { row-gap: 16px; }
    .riquadri > li { display: grid; grid-row: span 4; grid-template-rows: subgrid; row-gap: 0; }
    .riquadri > li > .riquadro { display: grid; grid-row: 1 / -1; grid-template-rows: subgrid; row-gap: 0; height: auto; }
    .riquadro-riga { align-self: start; }
    .riquadro-vai { align-self: end; }
  }
  @media screen and (max-width: 699px) { .riquadri { row-gap: 0; } }
}

/* ── 16 · la foto che vola (≈260 ms, approvato dal titolare il 20/10) ── */
::view-transition-group(foto-volo) { animation-duration: 260ms; animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
::view-transition-old(foto-volo), ::view-transition-new(foto-volo) { height: 100%; object-fit: cover; overflow: clip; animation-duration: 260ms; }
::view-transition-image-pair(foto-volo) { border-radius: var(--r); overflow: hidden; }
/* giudizio R1: col volo la pagina vecchia non traspare sotto la nuova; si muove solo la foto */
html.vt-volo::view-transition-old(root) { animation: none; opacity: 0; }
html.vt-volo::view-transition-new(root) { animation: none; }
/* (titolare 27/10) il NOME della soluzione diventa il titolo: dal riquadro della home l'h3 si trasforma nell'h1 della pagina, con lo
   stesso ritmo della foto (≈260 ms). I nomi vt-<soluzione> (vt-siti-web, vt-gestionali…) li mette viaggio/navigazione.js sul SOLO h3
   cliccato e sull'h1 d'arrivo, e li toglie a transizione finita: ce n'è sempre uno per parte, mai doppioni (neppure nel viaggio 3D,
   dove il nome è lo stesso h3 del riquadro). La classe titolo-volo dà il ritmo; con moto ridotto la transizione non parte. */
::view-transition-group(*.titolo-volo) { animation-duration: 260ms; animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
::view-transition-old(*.titolo-volo), ::view-transition-new(*.titolo-volo) { animation-duration: 260ms; }

/* ── 17 · cambio tema a cerchio: niente dissolvenza, il nuovo tema si apre sopra il vecchio ── */
html.vt-tema::view-transition-old(root), html.vt-tema::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
html.vt-tema::view-transition-old(root) { z-index: 0; }
html.vt-tema::view-transition-new(root) { z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

/* ── 26 · movimento allo scorrimento (CSS nativo, miglioramento progressivo) ── */
@supports (animation-timeline: view()) {
  @media screen and (prefers-reduced-motion: no-preference) {
    /* i titoli di sezione salgono appena, entrando */
    html.js:not(.fermo) .sezione-testa > h2, html.js:not(.fermo) .alterna-testo > h2 {
      animation: sale linear both; animation-timeline: view(); animation-range: entry 10% entry 90%; }
    /* «Cosa facciamo»: i riquadri si alzano in prospettiva, uno dopo l'altro (si anima il <li>: il riquadro ha già
       il suo sollevamento al passaggio del mouse) */
    html.js:not(.fermo) .riquadri { perspective: 1400px; }
    html.js:not(.fermo) .riquadri > li { transform-origin: 50% 100%;
      animation: alza-3d linear both; animation-timeline: view(); animation-range: entry 0% cover 34%; }
    html.js:not(.fermo) .riquadri > li:nth-child(2) { animation-range: entry 6% cover 37%; }
    html.js:not(.fermo) .riquadri > li:nth-child(3) { animation-range: entry 12% cover 40%; }
    html.js:not(.fermo) .riquadri > li:nth-child(4) { animation-range: entry 18% cover 43%; }
    html.js:not(.fermo) .riquadri > li:nth-child(5) { animation-range: entry 24% cover 46%; }
    /* le foto accanto al testo: si aprono dal centro, e dentro la cornice la foto scorre più lenta (parallasse) */
    html.js:not(.fermo) .alterna-foto { animation: apre linear both; animation-timeline: view(); animation-range: entry 0% cover 40%; }
    @media (min-width: 834px) {   /* al telefono la foto è piccola: la parallasse non si vedrebbe, resta solo l'apertura */
      html.js:not(.fermo) .alterna-foto img { animation: parallasse linear both; animation-timeline: view(); animation-range: cover 0% cover 100%; }
    }
    /* il testo accanto arriva dal suo lato (da 834 px: in colonna salirebbe oltre il bordo dello schermo, lì sale) */
    html.js:not(.fermo) .alterna > .alterna-testo { animation: sale linear both; animation-timeline: view(); animation-range: entry 0% cover 30%; }
    @media (min-width: 834px) {
      html.js:not(.fermo) .alterna > .alterna-testo { animation-name: da-destra; }
      html.js:not(.fermo) .alterna--inversa > .alterna-testo { animation-name: da-sinistra; }
    }
    /* i passi e i siti fatti: in cascata */
    html.js:not(.fermo) :is(.passi, .prove) > li { animation: sale linear both; animation-timeline: view(); animation-range: entry 0% entry 100%; }
    html.js:not(.fermo) :is(.passi, .prove) > li:nth-child(2) { animation-range: entry 15% entry 100%; }
    html.js:not(.fermo) :is(.passi, .prove) > li:nth-child(3) { animation-range: entry 30% entry 100%; }
    html.js:not(.fermo) :is(.passi, .prove) > li:nth-child(4) { animation-range: entry 45% entry 100%; }
    html.js:not(.fermo) .clienti-loghi > li { animation: affiora linear both; animation-timeline: view(); animation-range: entry 20% entry 100%; }
    /* al telefono i riquadri sono una fila che scorre di lato: lì il movimento segue lo scorrimento ORIZZONTALE
       (la «slide»): il riquadro che arriva cresce e si accende, quello che esce si ritira */
    @media (max-width: 699px) {
      html.js:not(.fermo) .riquadri { perspective: none; }
      html.js:not(.fermo) .riquadri > li:nth-child(n) { transform-origin: 50% 50%; animation: scorre linear both; animation-timeline: view(inline); animation-range: normal; }
    }
    /* la foto d'apertura di una soluzione: uscendo dallo schermo si allontana appena */
    html.js:not(.fermo) .eroe-foto { animation: allontana linear both; animation-timeline: view(); animation-range: exit 0% exit 100%; }
  }
}
@keyframes sale { from { opacity: .01; transform: translateY(28px); } to { opacity: 1; transform: none; } }
@keyframes alza-3d { from { opacity: .01; transform: translateY(64px) rotateX(16deg) scale(.96); } to { opacity: 1; transform: none; } }
@keyframes apre { from { clip-path: inset(10% 8% round var(--r)); } to { clip-path: inset(0 round var(--r)); } }
@keyframes parallasse { from { transform: translateY(-6%) scale(1.14); } to { transform: translateY(6%) scale(1.14); } }
@keyframes da-destra { from { opacity: .01; transform: translateX(24px); } to { opacity: 1; transform: none; } }
@keyframes da-sinistra { from { opacity: .01; transform: translateX(-24px); } to { opacity: 1; transform: none; } }
@keyframes scorre { entry 0% { opacity: .5; transform: scale(.9); } entry 100%, exit 0% { opacity: 1; transform: none; } exit 100% { opacity: .5; transform: scale(.9); } }
@keyframes affiora { from { opacity: .01; transform: scale(.92); } to { opacity: 1; transform: none; } }
@keyframes allontana { from { transform: none; opacity: 1; } to { transform: translateY(8%) scale(.94); opacity: .55; } }

/* ── 27 · la foto d'apertura delle soluzioni s'inclina appena verso il mouse (moto/inclina.js mette --inc-x/--inc-y;
   solo mouse vero, da 834 px, mai con moto ridotto). L'inclinazione sta sull'immagine: la cornice (che ha già
   l'allontanamento allo scorrimento) resta ferma; un riflesso di luce segue il puntatore. ── */
@media screen and (hover: hover) and (pointer: fine) and (min-width: 834px) and (prefers-reduced-motion: no-preference) {
  html.js:not(.fermo) .eroe-foto[data-inclina] { perspective: 1200px; }
  html.js:not(.fermo) .eroe-foto[data-inclina] picture { transform: rotateX(calc(var(--inc-y, 0) * -3deg)) rotateY(calc(var(--inc-x, 0) * 4deg)) scale(1.04); transition: transform 600ms cubic-bezier(.23, 1, .32, 1); }
  html.js:not(.fermo) .eroe-foto[data-inclina]::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: var(--inc-luce, 0); transition: opacity 400ms ease;
    background: radial-gradient(circle at calc(50% + var(--inc-x, 0) * 50%) calc(50% + var(--inc-y, 0) * 50%), rgba(255, 255, 255, .22), transparent 55%); }
}

/* ── 28 · «Cosa facciamo» a passi sopra il viaggio 3D (html.viaggio-binario, la mette cortex-vivo/viaggio-3d.js da
   1024 px): l'alzata in prospettiva (§26), pensata per la griglia, la spegne html.viaggio-prepara un fotogramma PRIMA
   del cambio di disposizione (insieme, Chrome contava uno spostamento falso). Nel binario il riquadro NON ha animazioni
   CSS: è posato nel mondo 3D e proiettato dalla camera della scena (cortex-vivo/lastra.js, numeri in
   claude/docs/regia-viaggio.md) — un'animazione CSS vince sullo stile inline e la matrice non arriverebbe mai al browser. ── */
html.viaggio-prepara .riquadri { perspective: none; }
html.viaggio-prepara .riquadri > li:nth-child(n) { animation: none; }
