/* MeMori — animazioni (scelte dall'utente tra le prove in tools/prova-animazioni, 25/10/2026).
   Brevi e «di carta», come il resto del sito. Con «riduci movimento» attivo nel sistema
   (prefers-reduced-motion) non c'è nessuna animazione: tutto è subito al suo posto.
   Si animano solo trasparenza e le proprietà translate, rotate e scale, che si sommano alle
   trasformazioni già presenti (dorsi inclinati, avviso centrato) invece di sostituirle; a fine
   animazione non resta niente (fill-mode backwards). Le classi motion-* le mette motion.js. */

/* La parte letta della barra delle pagine (--share in style.css): registrata perché si possa
   animare come una percentuale. */
/* Ombra d'inchiostro delle copertine della Home (home.css): registrata perché possa crescere animata. */
@property --hc-shadow {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

@property --share {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 0%;
}

:root {
  --motion-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --motion-step: 40ms;
}

@media (prefers-reduced-motion: no-preference) {
  /* A1. Cambio pagina: il foglio nuovo si posa (dissolvenza e un piccolo scorrimento). Parte da
     sola quando la pagina passa da nascosta a visibile. */
  /* motion.js tiene la pagina trasparente finché il suo contenuto è disegnato (motion-wait, al
     massimo un terzo di secondo), poi la fa entrare tutta insieme (motion-in). */
  main > section.motion-wait {
    opacity: 0;
  }

  main > section.motion-in {
    animation: motion-page 380ms var(--motion-ease) backwards;
  }

  @keyframes motion-page {
    from {
      opacity: 0;
      translate: 0 10px;
    }
  }

  /* Cambio pagina: dissolvenza (pageTurn in motion.js, data-turn sulla pagina; scelta dall'utente il
     27/10/2026 tra i campioni in tools/prova-cambio-pagina, al posto dello sfoglio del giornale). Il
     menù ha un nome suo e resta fermo; il resto dello schermo (root): la pagina vecchia svanisce
     in fretta e la nuova compare, senza fondersi (il browser di suo le mescolerebbe). */
  html[data-turn] #nav {
    view-transition-name: memori-nav;
  }

  ::view-transition-group(memori-nav),
  ::view-transition-new(memori-nav) {
    animation: none;
  }

  ::view-transition-old(memori-nav) {
    display: none;
  }

  /* Anche il cerchio dell'account, che sul PC sta fermo nella riga del menù (sul telefono scorre
     con la pagina, quindi va con il foglio). */
  @media (min-width: 761px) {
    html[data-turn] #nav-me {
      view-transition-name: memori-me;
    }
  }

  ::view-transition-group(memori-me),
  ::view-transition-new(memori-me) {
    animation: none;
  }

  ::view-transition-old(memori-me) {
    display: none;
  }

  html[data-turn]::view-transition-old(root),
  html[data-turn]::view-transition-new(root) {
    mix-blend-mode: normal;
    animation-timing-function: ease-out;
    animation-fill-mode: both;
  }

  html[data-turn]::view-transition-old(root) {
    animation-name: motion-turn-out;
    animation-duration: 120ms;
  }

  html[data-turn]::view-transition-new(root) {
    animation-name: motion-turn-in;
    animation-duration: 180ms;
    animation-delay: 60ms;
  }

  @keyframes motion-turn-out {
    to {
      opacity: 0;
    }
  }

  @keyframes motion-turn-in {
    from {
      opacity: 0;
    }
  }

  /* A3. Capilettera: la lettera si imprime con un colpo d'inchiostro. Le lettere del catalogo
     sono elementi (scendono e si posano, con una macchia che si allarga); i capilettera delle
     trame sono ::first-letter, che si può solo colorare: l'inchiostro si asciuga. */
  .catalog-letter {
    position: relative;
    animation: motion-cap 450ms var(--motion-ease) backwards;
  }

  .catalog-letter::after {
    content: "";
    position: absolute;
    inset: 15% 20%;
    z-index: -1;
    border-radius: 50%;
    background: var(--mm-accent);
    opacity: 0;
    animation: motion-blot 700ms ease-out;
    pointer-events: none;
  }

  @keyframes motion-cap {
    from {
      opacity: 0;
      translate: 0 -10px;
      scale: 1.25;
    }
  }

  @keyframes motion-blot {
    from {
      opacity: 0.3;
      scale: 0.4;
    }
    to {
      opacity: 0;
      scale: 1.8;
    }
  }

  .bp-description::first-letter {
    animation: motion-ink 700ms ease-out backwards;
  }

  @keyframes motion-ink {
    from {
      color: transparent;
      text-shadow: 0 0 14px var(--mm-accent);
    }
  }

  /* B1. Scaffale aperto (dal 28/10/2026, ogni volta che si apre uno scaffale o si cambia il filtro,
     motion.js shelfOpened): le copertine atterrano una dopo l'altra come nella Libreria; all'apertura
     (sh-shelf-in) titolo e numero entrano, le pillole degli stati e gli scaffali vicini spuntano.
     B3. la pila si posa un libro alla volta. --motion-i è la posizione (al massimo 24, poi tutte insieme). */
  #shelves-view.sh-fx #shelf-books.motion-enter > * {
    animation: motion-lb-land 650ms var(--motion-ease) backwards;
    animation-delay: calc(var(--motion-i, 0) * 50ms);
  }

  #shelves-view.sh-fx #shelf-detail.sh-shelf-in :is(.sh-kicker, .sh-head h1) {
    animation: motion-lb-rise 550ms var(--motion-ease) backwards;
  }

  #shelves-view.sh-fx #shelf-detail.sh-shelf-in .sh-count {
    animation: motion-lb-pop 600ms cubic-bezier(0.3, 1.6, 0.5, 1) 200ms backwards;
  }

  #shelves-view.sh-fx #shelf-detail.sh-shelf-in :is(.sh-pill, .sh-near li) {
    animation: motion-lb-pop 400ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(250ms + var(--motion-i, 0) * 60ms);
  }

  #shelves-view.sh-fx #shelf-detail.sh-shelf-in .sh-near li {
    animation-delay: calc(500ms + var(--motion-i, 0) * 70ms);
  }

  @keyframes motion-rise {
    from {
      opacity: 0;
      translate: 0 14px;
    }
  }

  /* B3. La pila: prima il piano, poi i libri cadono uno alla volta dal basso verso la cima
     (--motion-i = 0 per quello appoggiato al piano, vedi motion.js). Ogni libro accelera
     cadendo, tocca, fa un piccolo rimbalzo e si ferma; compare subito all'inizio della caduta. */
  /* In attesa di sapere quali libri si vedono (motion.js, dropPile). */
  #pile.motion-pending > * {
    opacity: 0;
  }

  /* Fuori dallo schermo: già al loro posto. */
  #pile.motion-enter > [data-motion-skip] {
    animation: none;
  }

  #pile.motion-enter > *:not([data-motion-skip]) {
    animation:
      motion-fall 560ms backwards,
      motion-appear 120ms ease-out backwards;
    animation-delay: calc(180ms + var(--motion-i, 0) * var(--motion-pile-step, 110ms) - var(--motion-elapsed, 0ms));
  }

  @keyframes motion-fall {
    0% {
      translate: 0 -150px;
      /* Caduta: sempre più veloce, come per gravità. */
      animation-timing-function: cubic-bezier(0.55, 0, 1, 0.55);
    }
    62% {
      translate: 0 0;
      animation-timing-function: cubic-bezier(0.2, 0.8, 0.3, 1);
    }
    78% {
      translate: 0 -5px;
      animation-timing-function: cubic-bezier(0.5, 0, 0.7, 1);
    }
    100% {
      translate: 0 0;
    }
  }

  @keyframes motion-appear {
    from {
      opacity: 0;
    }
  }

  /* B2. I dorsi scivolano sulla mensola uno dopo l'altro, spinti da destra, e si fermano con un
     piccolo urto (M1, scelta dell'utente il 28/10/2026 tra i campioni in tools/prova-scaffali;
     solo sulle mensole visibili: motion.js, fillShelves). In attesa di sapere quali si vedono: nascosti. */
  .shelf-row.motion-pending > * {
    opacity: 0;
  }

  .shelf-row.motion-enter > * {
    animation: motion-slide 550ms cubic-bezier(0.25, 1.25, 0.5, 1) backwards;
    animation-delay: calc(var(--motion-row-delay, 0ms) + var(--motion-i, 0) * var(--motion-shelf-step, 40ms));
  }

  /* Copertina vera arrivata dopo, al posto di quella finta: in dissolvenza. */
  .book-cover img.motion-cover-in {
    animation: motion-appear 360ms ease-out backwards;
  }

  @keyframes motion-slide {
    from {
      opacity: 0;
      translate: 120px 0;
    }

    70% {
      opacity: 1;
      translate: -3px 0;
    }
  }

  /* D7. Scaffali (stile «Ritagli»): con sh-fx (messa da motion.js) il bollino del numero degli
     scaffali salta dentro e conta, all'apertura (sh-open) i riquadri del colpo d'occhio salgono uno
     dopo l'altro, la
     mensola si allunga sotto i dorsi che scivolano (B2). */
  #shelves-view.sh-fx .sh-count.sh-pop {
    animation: motion-lb-pop 700ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
  }

  #shelves-view.sh-fx.sh-open .sh-glance li {
    animation: motion-lb-rise 500ms var(--motion-ease) backwards;
    animation-delay: calc(150ms + var(--k, 0) * 80ms);
  }

  #shelves-view.sh-fx .shelf-row.motion-enter + .shelf-plank {
    transform-origin: left;
    animation: motion-sh-plank 600ms var(--motion-ease) backwards;
    animation-delay: var(--motion-row-delay, 0ms);
  }

  @keyframes motion-sh-plank {
    from {
      scale: 0 1;
    }
  }

  /* C1. Cambio di stato «Segnalibro» (scelto dall'utente il 27/10/2026 tra i campioni in
     tools/prova-stati, al posto del timbro): sulla copertina il segnalibro vecchio sale via
     (motion-status-old, una copia col colore di prima) e cade quello nuovo, che oscilla come un
     nastro; nella riga del catalogo il pallino si riempie con un anello che si allarga; un'etichetta
     nera (motion-word) dice lo stato per un attimo. Per ogni stato, e «Comprato» nella pagina del libro. */
  .book-item,
  .catalog-entry,
  .book-page-cover {
    position: relative;
  }

  .cover-status.motion-status::before {
    transform-origin: top center;
    animation: motion-ribbon-in 900ms cubic-bezier(0.3, 1.6, 0.5, 1) 250ms backwards;
  }

  .cover-status.motion-status-old {
    pointer-events: none;
  }

  .cover-status.motion-status-old::before {
    animation: motion-ribbon-out 350ms ease-in forwards;
  }

  .catalog-status.motion-status::before {
    animation:
      motion-dot-fill 800ms cubic-bezier(0.3, 1.6, 0.5, 1),
      motion-dot-ring 800ms ease-out;
  }

  .motion-word {
    position: absolute;
    z-index: 3;
    padding: 0.2rem 0.65rem;
    border-radius: 999px;
    background: var(--text);
    color: var(--bg);
    font: 700 0.8rem var(--rt-body);
    white-space: nowrap;
    pointer-events: none;
    animation: motion-word 1.6s ease forwards;
  }

  .book-item .motion-word {
    top: 2.2rem;
    right: 0;
  }

  .catalog-entry .motion-word {
    top: -0.6rem;
    left: 2rem;
  }

  .book-page-cover .motion-word {
    top: 0.6rem;
    right: 0.6rem;
  }

  @keyframes motion-ribbon-in {
    0% {
      opacity: 0;
      translate: 0 -50px;
    }

    50% {
      opacity: 1;
      translate: 0 6px;
      rotate: 0deg;
    }

    70% {
      rotate: 8deg;
    }

    85% {
      rotate: -5deg;
    }

    100% {
      rotate: 0deg;
    }
  }

  @keyframes motion-ribbon-out {
    to {
      opacity: 0;
      translate: 0 -40px;
    }
  }

  @keyframes motion-dot-fill {
    0% {
      scale: 0.2;
    }

    60% {
      scale: 1.5;
    }
  }

  @keyframes motion-dot-ring {
    from {
      box-shadow: 0 0 0 0 var(--status-color);
    }

    to {
      box-shadow: 0 0 0 10px transparent;
    }
  }

  @keyframes motion-word {
    0% {
      opacity: 0;
      translate: 0 8px;
    }

    15%,
    75% {
      opacity: 1;
      translate: 0 0;
    }

    100% {
      opacity: 0;
      translate: 0 -14px;
    }
  }

  @keyframes motion-fade {
    to {
      opacity: 0;
    }
  }

  /* C3. Avviso: arriva come un biglietto, un po' storto, e si posa dritto. */
  .toast:not([hidden]) {
    animation: motion-note 420ms var(--motion-ease) backwards;
  }

  @keyframes motion-note {
    from {
      opacity: 0;
      translate: 0 120%;
      rotate: -3deg;
    }
    70% {
      opacity: 1;
      translate: 0 -4px;
      rotate: 1deg;
    }
  }

  /* D1. Barra delle pagine: la parte letta si riempie fino al punto in cui sei. */
  .page-slider {
    animation: motion-fill 900ms var(--motion-ease) backwards;
  }

  @keyframes motion-fill {
    from {
      --share: 0%;
    }
  }

  /* D2. Home (stile «Ritagli»): con hc-fx (messa da motion.js) le sezioni salgono e compaiono
     quando entrano nello schermo (hc-in); le copertine «atterrano» con l'ombra d'inchiostro che
     cresce; la barra di lettura si riempie; i dorsi della pila cadono uno sopra l'altro, le
     copertine della wishlist salgono, i puntini degli autori spuntano uno dopo l'altro (--k). */
  .hc-fx .hc-reveal {
    opacity: 0;
    translate: 0 28px;
    transition:
      opacity 0.7s ease,
      translate 0.8s var(--motion-ease);
  }

  .hc-fx .hc-reveal.hc-in {
    opacity: 1;
    translate: 0 0;
  }

  .hc-fx .hc-reveal :is(.hc-day-cover, .hc-read .book-cover, .hc-tip .book-cover) {
    transition:
      --hc-shadow 0.6s ease 0.25s,
      translate 0.6s ease 0.25s;
  }

  .hc-fx .hc-reveal:not(.hc-in) :is(.hc-day-cover, .hc-read .book-cover, .hc-tip .book-cover) {
    --hc-shadow: 0px;
    translate: 3px 3px;
  }

  /* La citazione: il dorso cade al suo posto, la pagina si sfila verso destra (un libro che si apre),
     poi compaiono testo e fonte. */
  .hc-fx .hc-reveal.hc-in .hc-spine {
    animation: motion-hc-spine 450ms cubic-bezier(0.3, 1.4, 0.5, 1) 200ms backwards;
  }

  .hc-fx .hc-reveal.hc-in .hc-page {
    animation: motion-hc-unfold 900ms var(--motion-ease) 350ms backwards;
  }

  .hc-fx .hc-reveal.hc-in .hc-page > * {
    animation: motion-lb-rise 500ms ease 900ms backwards;
  }

  @keyframes motion-hc-spine {
    from {
      opacity: 0;
      translate: 0 -20px;
    }
  }

  @keyframes motion-hc-unfold {
    from {
      clip-path: inset(0 100% 0 0);
    }

    to {
      clip-path: inset(0 0 0 0);
    }
  }

  .hc-fx .hc-reveal .hc-bar i {
    transition: width 1.1s var(--motion-ease) 0.3s;
  }

  .hc-fx .hc-reveal:not(.hc-in) .hc-bar i {
    width: 0;
  }

  .hc-fx .hc-reveal .hc-pile-draw i {
    transition:
      opacity 0.3s ease,
      translate 0.45s cubic-bezier(0.3, 1.4, 0.5, 1);
    transition-delay: calc(var(--k, 0) * 70ms);
  }

  .hc-fx .hc-reveal:not(.hc-in) .hc-pile-draw i {
    opacity: 0;
    translate: var(--x, 0) -40px;
  }

  .hc-fx .hc-reveal .hc-wish-covers > * {
    transition:
      opacity 0.3s ease,
      translate 0.5s cubic-bezier(0.3, 1.4, 0.5, 1);
    transition-delay: calc(var(--k, 0) * 90ms);
  }

  .hc-fx .hc-reveal:not(.hc-in) .hc-wish-covers > * {
    opacity: 0;
    translate: 0 30px;
  }

  .hc-fx .hc-reveal .hc-faces i {
    transition:
      opacity 0.25s ease,
      scale 0.35s cubic-bezier(0.3, 1.6, 0.5, 1);
    transition-delay: calc(min(var(--k, 0), 60) * 25ms);
  }

  .hc-fx .hc-reveal:not(.hc-in) .hc-faces i {
    opacity: 0;
    scale: 0.3;
  }

  /* D4. Libreria (stile «Ritagli»): con lb-fx (messa da motion.js) il numero dei libri salta dentro
     (lb-pop) e conta; i gruppi del catalogo e le copertine entrano quando arrivano sullo schermo
     (lb-seen, in sequenza con --k): la lettera spunta, il riquadro sale, le righe scivolano dentro
     una dopo l'altra (--i); le copertine atterrano con l'ombra che cresce e poi cade il segnalibro.
     Col mouse la copertina si inclina verso il cursore (lb-tilt, angoli --lb-rx e --lb-ry). */
  #library-view.lb-fx .lb-count.lb-pop {
    animation: motion-lb-pop 700ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
  }

  #library-view.lb-fx :is(.catalog-group, .book-item):not(.lb-seen) {
    visibility: hidden;
  }

  #library-view .catalog-letter::after {
    content: none;
  }

  #library-view.lb-fx .catalog-group.lb-seen .catalog-letter {
    animation: motion-lb-pop 550ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(var(--k, 0) * 70ms);
  }

  #library-view.lb-fx .catalog-group.lb-seen :is(.catalog-list, .catalog-heading) {
    animation: motion-lb-rise 500ms var(--motion-ease) backwards;
    animation-delay: calc(var(--k, 0) * 70ms + 60ms);
  }

  #library-view.lb-fx .catalog-group.lb-seen .catalog-entry {
    animation: motion-lb-slide 450ms var(--motion-ease) backwards;
    animation-delay: calc(var(--k, 0) * 70ms + 120ms + var(--i, 0) * 45ms);
  }

  #library-view.lb-fx .book-item.lb-seen .book-cover {
    animation: motion-lb-land 650ms var(--motion-ease) backwards;
    animation-delay: calc(var(--k, 0) * 55ms);
  }

  #library-view.lb-fx .book-item.lb-seen .book-body {
    animation: motion-lb-rise 500ms ease backwards;
    animation-delay: calc(var(--k, 0) * 55ms + 150ms);
  }

  #library-view.lb-fx .book-item.lb-seen .cover-status {
    animation: motion-lb-drop 500ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(var(--k, 0) * 55ms + 300ms);
  }

  #library-view.lb-fx .book-item.lb-tilt .book-cover {
    transform: rotateX(var(--lb-rx, 0deg)) rotateY(var(--lb-ry, 0deg)) translateZ(10px);
    translate: none;
    /* L'ombra si sposta dal lato opposto all'inclinazione. */
    box-shadow: calc(6px - var(--lb-sx, 0px)) calc(6px + var(--lb-sy, 0px)) 0 var(--rt-ink);
    transition:
      transform 80ms linear,
      box-shadow 80ms linear;
  }

  @keyframes motion-lb-pop {
    from {
      opacity: 0;
      scale: 0.2;
      rotate: -50deg;
    }
  }

  @keyframes motion-lb-rise {
    from {
      opacity: 0;
      translate: 0 18px;
    }
  }

  @keyframes motion-lb-slide {
    from {
      opacity: 0;
      translate: -22px 0;
    }
  }

  @keyframes motion-lb-land {
    from {
      opacity: 0;
      translate: 0 -28px;
      scale: 1.06;
      box-shadow: 0 0 0 var(--rt-ink);
    }
  }

  @keyframes motion-lb-drop {
    from {
      opacity: 0;
      translate: 0 -24px;
    }
  }

  /* D5. Finestra Aggiungi (stile «Ritagli»): sale con un piccolo rimbalzo (dal basso sul telefono), i
     risultati arrivano uno dopo l'altro, il + appena toccato fa un salto e diventa ✓, la linea dello
     scanner scorre su e giù, la conferma salvia scende al suo posto. */
  /* D9. Autori (stile «Ritagli»): con au-fx (messa da motion.js) il bollino del numero salta dentro e
     conta (au-pop); l'elenco entra (au-in): il podio sale coi gradini che crescono e il numero del posto
     che spunta, i riquadri della galleria atterrano uno dopo l'altro (--i), le lettere del dizionario
     salgono. Aprendo un autore (au-open) il ritratto spunta girando, nome e professioni entrano, i
     bollini dei dati spuntano; le sezioni salgono arrivando sullo schermo (au-seen): i segnalibri della
     linea del tempo cadono, le opere scivolano dentro, le citazioni si srotolano. */
  #authors-view.au-fx .au-count.au-pop {
    animation: motion-lb-pop 700ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
  }

  #authors-view.au-fx #authors-list.au-in .au-pod {
    animation: motion-lb-rise 700ms cubic-bezier(0.3, 1.3, 0.5, 1) backwards;
  }

  #authors-view.au-fx #authors-list.au-in .au-pod-1 { animation-delay: 150ms; }
  #authors-view.au-fx #authors-list.au-in .au-pod-3 { animation-delay: 300ms; }

  #authors-view.au-fx #authors-list.au-in .au-step {
    transform-origin: bottom;
    animation: motion-au-grow 700ms var(--motion-ease) 200ms backwards;
  }

  #authors-view.au-fx #authors-list.au-in .au-rank {
    animation: motion-lb-pop 500ms cubic-bezier(0.3, 1.6, 0.5, 1) 800ms backwards;
  }

  #authors-view.au-fx #authors-list.au-in :is(.au-gallery > li, .au-group) {
    animation: motion-lb-land 550ms cubic-bezier(0.3, 1.3, 0.5, 1) backwards;
    animation-delay: calc(400ms + var(--i, 0) * 50ms);
  }

  #authors-view.au-fx #author-detail.au-open .author-portrait-image {
    animation: motion-au-spin 800ms cubic-bezier(0.3, 1.4, 0.5, 1) 100ms backwards;
  }

  #authors-view.au-fx #author-detail.au-open h1 {
    animation: motion-lb-rise 600ms var(--motion-ease) 150ms backwards;
  }

  #authors-view.au-fx #author-detail.au-open :is(.au-occ li, .au-fact) {
    animation: motion-lb-pop 450ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(350ms + var(--i, 0) * 60ms);
  }

  #authors-view.au-fx #author-detail .au-sec:not(.au-seen) {
    visibility: hidden;
  }

  #authors-view.au-fx #author-detail .au-sec.au-seen {
    animation: motion-lb-rise 600ms var(--motion-ease) backwards;
    animation-delay: calc(var(--k, 0) * 90ms);
  }

  #authors-view.au-fx .au-seen .au-line::before {
    transform-origin: left;
    animation: motion-au-grow-x 900ms var(--motion-ease) 200ms backwards;
  }

  #authors-view.au-fx .au-seen .au-tick {
    animation: motion-au-drop 700ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(600ms + var(--i, 0) * 110ms);
  }

  #authors-view.au-fx .au-seen .au-work {
    animation: motion-lb-slide 450ms var(--motion-ease) backwards;
  }

  #authors-view.au-fx .au-seen .au-quote {
    animation: motion-bk-unfold 800ms var(--motion-ease) backwards;
    animation-delay: calc(200ms + var(--i, 0) * 150ms);
  }

  @keyframes motion-au-grow {
    from {
      scale: 1 0;
    }
  }

  @keyframes motion-au-grow-x {
    from {
      scale: 0 1;
    }
  }

  @keyframes motion-au-spin {
    from {
      opacity: 0;
      scale: 0.4;
      rotate: -28deg;
    }
  }

  @keyframes motion-au-drop {
    0% {
      opacity: 0;
      translate: -50% -40px;
    }

    60% {
      opacity: 1;
      translate: -50% 4px;
    }

    100% {
      translate: -50% 0;
    }
  }

  /* D10. Pila (stile «Ritagli»): con pi-fx (messa da motion.js) il bollino del numero salta dentro e
     conta; aprendo la pagina (pi-open) i gradini della scala spuntano, il piano si allarga, «Leggilo per
     primo!» sale con la copertina che atterra e il cartellino che spunta, le cifre spuntano, le righe
     dell'elenco scivolano dentro. I libri cadono sulla pila (B3). Il dorso pescato a caso oscilla. */
  #pile-view.pi-fx .pi-count.pi-pop {
    animation: motion-lb-pop 700ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
  }

  #pile-view.pi-fx.pi-open .pi-scale span {
    animation: motion-lb-pop 400ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(200ms + var(--i, 0) * 60ms);
  }

  #pile-view.pi-fx.pi-open .pile-floor {
    animation: motion-au-grow-x 600ms var(--motion-ease) 150ms backwards;
    transform-origin: center;
  }

  #pile-view.pi-fx.pi-open .pi-first {
    animation: motion-lb-rise 700ms var(--motion-ease) 400ms backwards;
  }

  #pile-view.pi-fx.pi-open .pi-cover {
    animation: motion-lb-land 700ms cubic-bezier(0.3, 1.3, 0.5, 1) 700ms backwards;
  }

  #pile-view.pi-fx.pi-open .pi-flag {
    animation: motion-lb-pop 500ms cubic-bezier(0.3, 1.6, 0.5, 1) 1100ms backwards;
  }

  #pile-view.pi-fx.pi-open .pi-fun-card {
    animation: motion-lb-rise 600ms var(--motion-ease) backwards;
    animation-delay: calc(500ms + var(--i, 0) * 120ms);
  }

  #pile-view.pi-fx.pi-open .pi-emo {
    animation: motion-lb-pop 500ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(900ms + var(--i, 0) * 120ms);
  }

  #pile-view.pi-fx.pi-open .pi-nums div {
    animation: motion-lb-pop 450ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(900ms + var(--i, 0) * 70ms);
  }

  #pile-view.pi-fx.pi-open .pi-rows li {
    animation: motion-lb-slide 450ms var(--motion-ease) backwards;
    animation-delay: calc(1000ms + var(--i, 0) * 40ms);
  }

  #pile-view.pi-fx .spine.is-picked {
    animation: motion-pi-wiggle 500ms ease;
  }

  @keyframes motion-pi-wiggle {
    25% {
      rotate: 3deg;
    }

    50% {
      rotate: -3deg;
    }

    75% {
      rotate: 2deg;
    }
  }

  /* D11. Wishlist (stile «Ritagli»): con wi-fx (messa da motion.js) il cuore del numero batte e conta;
     aprendo la pagina (wi-open) i gradini della scala spuntano, «Lo desideri da più tempo» sale col
     cartellino che spunta, le copertine atterrano una dopo l'altra e i cuoricini spuntano, le iniziali
     dell'elenco spuntano e le righe scivolano dentro, gli autori spuntano. Cambiando vista o filtro la
     lista rientra (wi-in). «Comprato»: il timbro si posa e il libro vola via. */
  #wishlist-view.wi-fx .wi-count.wi-pop {
    animation: motion-wi-beat 900ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
  }

  #wishlist-view.wi-fx.wi-open .wi-scale span {
    animation: motion-lb-pop 400ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(200ms + var(--i, 0) * 60ms);
  }

  #wishlist-view.wi-fx.wi-open :is(.wi-add, .wi-tip) {
    animation: motion-lb-rise 600ms var(--motion-ease) 300ms backwards;
  }

  #wishlist-view.wi-fx.wi-open .wi-oldest {
    animation: motion-lb-rise 700ms var(--motion-ease) 400ms backwards;
  }

  #wishlist-view.wi-fx.wi-open .wi-flag {
    animation: motion-lb-pop 500ms cubic-bezier(0.3, 1.6, 0.5, 1) 1000ms backwards;
  }

  #wishlist-view.wi-fx:is(.wi-open, .wi-in) .wi-item {
    animation: motion-lb-land 600ms cubic-bezier(0.3, 1.3, 0.5, 1) backwards;
    animation-delay: calc(300ms + var(--i, 0) * 60ms);
  }

  #wishlist-view.wi-fx:is(.wi-open, .wi-in) .wi-heart {
    animation: motion-lb-pop 500ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(700ms + var(--i, 0) * 60ms);
  }

  #wishlist-view.wi-fx:is(.wi-open, .wi-in) .wi-letter {
    animation: motion-lb-pop 500ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(300ms + var(--i, 0) * 80ms);
  }

  #wishlist-view.wi-fx:is(.wi-open, .wi-in) .wi-row {
    animation: motion-lb-slide 450ms var(--motion-ease) backwards;
    animation-delay: calc(450ms + var(--j, 0) * 40ms);
  }

  #wishlist-view.wi-fx.wi-open .wi-chips li {
    animation: motion-lb-pop 400ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(900ms + var(--i, 0) * 60ms);
  }

  #wishlist-view.wi-fx .is-bought .wi-stamp {
    animation: motion-wi-stamp 400ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
  }

  #wishlist-view.wi-fx .is-bought {
    animation: motion-wi-away 600ms cubic-bezier(0.5, 0, 0.75, 0) 700ms forwards;
  }

  @keyframes motion-wi-beat {
    0% {
      opacity: 0;
      scale: 0.3;
    }

    60% {
      scale: 1.15;
    }

    75% {
      scale: 0.95;
    }
  }

  @keyframes motion-wi-stamp {
    from {
      opacity: 0;
      scale: 2.2;
    }
  }

  @keyframes motion-wi-away {
    to {
      opacity: 0;
      translate: 0 -40px;
      scale: 0.7;
    }
  }

  /* D12. Letture (stile «Ritagli»): con le-fx (messa da motion.js) il bollino del numero salta dentro e
     conta; aprendo la pagina (le-open) i riquadri dei libri salgono, le copertine atterrano, i bollini
     dei numeri spuntano, le barrette del ritmo crescono, le citazioni si srotolano; «Una a caso» fa
     oscillare quella scelta. La barra si riempie (D1), il segnalibro scende quando segni (D3). */
  #reading-view.le-fx .le-count.le-pop {
    animation: motion-lb-pop 700ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
  }

  #reading-view.le-fx.le-open .le-book {
    animation: motion-lb-rise 700ms var(--motion-ease) backwards;
    animation-delay: calc(200ms + var(--i, 0) * 150ms);
  }

  #reading-view.le-fx.le-open .le-cv {
    animation: motion-lb-land 700ms cubic-bezier(0.3, 1.3, 0.5, 1) backwards;
    animation-delay: calc(400ms + var(--i, 0) * 150ms);
  }

  #reading-view.le-fx.le-open .le-facts div {
    animation: motion-lb-pop 450ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(800ms + var(--j, 0) * 70ms);
  }

  #reading-view.le-fx.le-open .le-bars i {
    transform-origin: bottom;
    animation: motion-au-grow 500ms cubic-bezier(0.3, 1.4, 0.5, 1) backwards;
    animation-delay: calc(900ms + var(--k, 0) * 30ms);
  }

  #reading-view.le-fx.le-open .le-q {
    transform-origin: left;
    animation: motion-le-unfold 600ms var(--motion-ease) backwards;
    animation-delay: calc(1000ms + var(--k, 0) * 80ms);
  }

  #reading-view.le-fx .le-q.is-lucky {
    animation: motion-le-wiggle 500ms ease;
  }

  @keyframes motion-le-unfold {
    from {
      opacity: 0;
      scale: 0.2 1;
    }
  }

  @keyframes motion-le-wiggle {
    25% {
      rotate: 1.5deg;
    }

    50% {
      rotate: -1.5deg;
    }

    75% {
      rotate: 1deg;
    }
  }

  /* D13. Consigli e Lettori (stile «Ritagli»): con sc-fx (messa da motion.js) aprendo la pagina (sc-open)
     le quattro strade spuntano; ogni consiglio che arriva atterra (in fila, --i), con Shuffle entra
     mescolato come un mazzo di carte; «✕ Non fa per me» lo fa uscire. In Lettori i gradini del podio
     crescono, le copertine atterrano, le righe e i profili scivolano dentro. */
  #recommend-view.sc-fx.sc-open .sc-way {
    animation: motion-lb-pop 500ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
  }

  #recommend-view.sc-fx.sc-open .sc-way-2 { animation-delay: 80ms; }
  #recommend-view.sc-fx.sc-open .sc-way-3 { animation-delay: 160ms; }
  #recommend-view.sc-fx.sc-open .sc-way-4 { animation-delay: 240ms; }

  #recommend-view.sc-fx .rc-card {
    animation: motion-lb-land 550ms cubic-bezier(0.3, 1.3, 0.5, 1) backwards;
    animation-delay: calc(var(--i, 0) * 60ms);
  }

  #recommend-view.sc-fx [data-mode="shuffle"] .rc-card {
    animation: motion-sc-riffle 700ms cubic-bezier(0.3, 1.3, 0.5, 1) backwards;
    animation-delay: calc(var(--i, 0) * 45ms);
  }

  #recommend-view.sc-fx .rc-card.is-gone {
    animation: motion-sc-gone 400ms ease forwards;
  }

  #readers-view.sc-fx.sc-open .rd-step {
    transform-origin: bottom;
    animation: motion-au-grow 700ms var(--motion-ease) 200ms backwards;
  }

  #readers-view.sc-fx.sc-open .rd-pod .book-cover {
    animation: motion-lb-land 700ms cubic-bezier(0.3, 1.3, 0.5, 1) backwards;
    animation-delay: calc(500ms + var(--i, 0) * 120ms);
  }

  #readers-view.sc-fx.sc-open :is(.rd-poplist li, .rd-readers li) {
    animation: motion-lb-slide 450ms var(--motion-ease) backwards;
    animation-delay: calc(700ms + var(--i, 0) * 50ms);
  }

  @keyframes motion-sc-riffle {
    0% {
      opacity: 0;
      translate: -60px -20px;
    }

    50% {
      opacity: 1;
      translate: 20px 0;
    }
  }

  @keyframes motion-sc-gone {
    to {
      opacity: 0;
      scale: 0.8;
      translate: 0 10px;
    }
  }

  /* D14. Account (stile «Ritagli»): con ac-fx (messa da motion.js) aprendo la pagina (ac-open) l'iniziale
     spunta girando, nome e dati salgono, le cifre spuntano e contano, i riquadri salgono uno dopo l'altro. */
  #account-view.ac-fx.ac-open .ac-ini {
    animation: motion-au-spin 800ms cubic-bezier(0.3, 1.4, 0.5, 1) 100ms backwards;
  }

  #account-view.ac-fx.ac-open .ac-who {
    animation: motion-lb-rise 600ms var(--motion-ease) 200ms backwards;
  }

  #account-view.ac-fx.ac-open .ac-nums div {
    animation: motion-lb-pop 450ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: calc(400ms + var(--i, 0) * 70ms);
  }

  #account-view.ac-fx.ac-open .ac-box {
    animation: motion-lb-rise 600ms var(--motion-ease) backwards;
    animation-delay: 500ms;
  }

  #account-view.ac-fx.ac-open .ac-col:last-child .ac-box {
    animation-delay: 620ms;
  }

  /* D8. Le finestre del libro, della copertina e delle citazioni (finestre.css) entrano come Aggiungi;
     i grandi ritagli da toccare spuntano uno dopo l'altro, il bollino della pagina si posa. */
  :is(#add-dialog, dialog.fw)[open] {
    animation: motion-ad-rise 550ms cubic-bezier(0.3, 1.3, 0.5, 1);
  }

  :is(#add-dialog, dialog.fw)[open]::backdrop {
    animation: motion-ad-fade 300ms ease;
  }

  dialog.fw[open] .fw-tile {
    animation: motion-lb-pop 450ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
    animation-delay: 200ms;
  }

  dialog.fw[open] .fw-tile + .fw-tile {
    animation-delay: 270ms;
  }

  dialog.fw[open] .qd-page {
    animation: motion-lb-pop 500ms cubic-bezier(0.3, 1.6, 0.5, 1) 300ms backwards;
  }

  #add-results > li {
    animation: motion-lb-rise 500ms var(--motion-ease) backwards;
  }

  #add-results > li:nth-child(2) { animation-delay: 70ms; }
  #add-results > li:nth-child(3) { animation-delay: 140ms; }
  #add-results > li:nth-child(4) { animation-delay: 210ms; }
  #add-results > li:nth-child(5) { animation-delay: 280ms; }
  #add-results > li:nth-child(n + 6) { animation-delay: 350ms; }

  #add-dialog .lookup-add.is-added {
    animation: motion-ad-pop 450ms cubic-bezier(0.3, 1.6, 0.5, 1);
  }

  /* Libro aggiunto: l'etichetta entra con un rimbalzo, la ✓ si stampa nel cerchio, la copertina
     scivola dentro storta e dalla ✓ escono i coriandoli di carta (--dx, --dy, --r, --c: app.js). */
  #add-dialog .ad-done.is-new {
    animation: motion-ad-done 600ms cubic-bezier(0.3, 1.5, 0.5, 1);
  }

  #add-dialog .ad-done.is-new .ad-ok {
    animation: motion-ad-stamp 500ms cubic-bezier(0.3, 1.6, 0.5, 1) 150ms backwards;
  }

  #add-dialog .ad-done.is-new .ad-done-cover {
    animation: motion-ad-cover 600ms cubic-bezier(0.3, 1.4, 0.5, 1) 250ms backwards;
  }

  #add-dialog .ad-done.is-new .ad-confetti {
    position: absolute;
    left: 50%;
    top: 50%;
    display: block;
    width: 8px;
    height: 12px;
    margin: -6px 0 0 -4px;
    border-radius: 2px;
    background: var(--c);
    opacity: 0;
    pointer-events: none;
    animation: motion-ad-confetti 900ms cubic-bezier(0.2, 0.8, 0.3, 1) 200ms forwards;
  }

  #add-dialog .ad-done.is-new .ad-confetti:nth-child(3n) {
    width: 9px;
    height: 9px;
    border-radius: 50%;
  }

  #add-dialog .ad-done.is-new .ad-confetti:nth-child(4n) {
    width: 12px;
    height: 6px;
    border-radius: 60% 40% 70% 30% / 50% 60% 40% 50%;
  }

  @keyframes motion-ad-done {
    from {
      opacity: 0;
      translate: 0 -14px;
      scale: 0.9;
      rotate: -2deg;
    }
  }

  @keyframes motion-ad-stamp {
    from {
      opacity: 0;
      scale: 2.2;
      rotate: -30deg;
    }
  }

  @keyframes motion-ad-cover {
    from {
      opacity: 0;
      translate: 30px -10px;
      rotate: 25deg;
    }
  }

  @keyframes motion-ad-confetti {
    0% {
      opacity: 1;
      translate: 0 0;
      rotate: 0deg;
    }

    100% {
      opacity: 0;
      translate: var(--dx) var(--dy);
      rotate: var(--r);
    }
  }

  .ad-laser {
    animation: motion-ad-scan 1.6s ease-in-out infinite alternate;
  }

  @keyframes motion-ad-rise {
    from {
      opacity: 0;
      translate: 0 40px;
      scale: 0.96;
    }
  }

  @keyframes motion-ad-fade {
    from {
      opacity: 0;
    }
  }

  @keyframes motion-ad-pop {
    40% {
      scale: 1.25;
      rotate: -12deg;
    }
  }

  /* Uno spostamento (translate, in altezza del riquadro: cqh), non la posizione: il telefono lo fa
     scorrere senza ricalcolare la pagina mentre decodifica il video. */
  @keyframes motion-ad-scan {
    from {
      translate: 0 0;
    }

    to {
      translate: 0 28cqh;
    }
  }

  @media (max-width: 760px) {
    :is(#add-dialog, dialog.fw)[open] {
      animation: motion-ad-up 450ms var(--motion-ease);
    }

    @keyframes motion-ad-up {
      from {
        translate: 0 100%;
      }
    }
  }

  /* D3. Segnalibro che scende sul libro in lettura quando segni dove sei arrivato. */
  .reading-cover {
    position: relative;
  }

  .reading-book.motion-mark .reading-cover::after {
    content: "";
    position: absolute;
    top: -3px;
    right: 14%;
    width: 14px;
    height: 46%;
    background: var(--fill);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 82%, 0 100%);
    transform-origin: top;
    animation:
      motion-ribbon 700ms cubic-bezier(0.3, 1.3, 0.5, 1) backwards,
      motion-fade 500ms ease-in 2.5s forwards;
  }

  @keyframes motion-ribbon {
    from {
      scale: 1 0;
    }
  }

  /* D6. Pagina del libro (stile «Ritagli», prova in tools/prova-libro): con bk-fx (messa da motion.js)
     all'apertura di un libro (bk-open) la copertina atterra e poi galleggia piano, il cuore della
     wishlist spunta, le pillole dei generi saltano dentro, titolo e resto salgono, i bollini dei
     dati spuntano uno dopo l'altro (--k). Le sezioni salgono quando arrivano sullo schermo (bk-in,
     in sequenza con --k); dentro, la barra della lettura si riempie, le citazioni si srotolano, le
     pillole degli scaffali spuntano e le copertine dei consigli atterrano. Col mouse la copertina si
     inclina verso il cursore (--bk-rx, --bk-ry: la regola è in libro.css). */
  #book-view.bk-fx .book-page-cover {
    animation: motion-bk-float 6s ease-in-out 1.2s infinite;
  }

  #book-view.bk-fx.bk-open .book-page-cover {
    animation:
      motion-lb-land 800ms cubic-bezier(0.3, 1.3, 0.5, 1) 100ms backwards,
      motion-bk-float 6s ease-in-out 1.2s infinite;
  }

  #book-view.bk-fx.bk-open .bk-wishmark {
    animation: motion-lb-pop 600ms cubic-bezier(0.3, 1.6, 0.5, 1) 700ms backwards;
  }

  #book-view.bk-fx.bk-open .bk-tags li {
    animation: motion-lb-pop 450ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
  }

  #book-view.bk-fx.bk-open .bk-tags li:nth-child(1) { animation-delay: 250ms; }
  #book-view.bk-fx.bk-open .bk-tags li:nth-child(2) { animation-delay: 320ms; }
  #book-view.bk-fx.bk-open .bk-tags li:nth-child(n + 3) { animation-delay: 390ms; }

  #book-view.bk-fx.bk-open h1 {
    animation: motion-lb-rise 700ms var(--motion-ease) 200ms backwards;
  }

  #book-view.bk-fx.bk-open :is(.bp-author, .bp-status, .bp-wish, .bk-verdict-part) {
    animation: motion-lb-rise 600ms var(--motion-ease) 350ms backwards;
  }

  #book-view.bk-fx.bk-open .bk-fact {
    animation: motion-bk-pop 500ms cubic-bezier(0.3, 1.5, 0.5, 1) backwards;
    animation-delay: calc(500ms + var(--k, 0) * 60ms);
  }

  #book-view.bk-fx .bk-sec:not(.bk-in) {
    visibility: hidden;
  }

  #book-view.bk-fx .bk-sec.bk-in {
    animation: motion-lb-rise 600ms var(--motion-ease) backwards;
    animation-delay: calc(var(--k, 0) * 90ms);
  }

  #book-view.bk-fx .bk-sec.bk-in .page-slider {
    animation: motion-bk-fill 1100ms var(--motion-ease) 300ms backwards;
  }

  #book-view.bk-fx .bk-sec.bk-in .quote {
    animation: motion-bk-unfold 800ms var(--motion-ease) backwards;
    animation-delay: 200ms;
  }

  #book-view.bk-fx .bk-sec.bk-in .quote:nth-child(2) {
    animation-delay: 350ms;
  }

  #book-view.bk-fx .bk-sec.bk-in .quote:nth-child(n + 3) {
    animation-delay: 500ms;
  }

  #book-view.bk-fx .bk-sec.bk-in .bk-shelf {
    animation: motion-lb-pop 450ms cubic-bezier(0.3, 1.6, 0.5, 1) backwards;
  }

  #book-view.bk-fx .bk-sec.bk-in .bk-shelf:nth-child(2) { animation-delay: 70ms; }
  #book-view.bk-fx .bk-sec.bk-in .bk-shelf:nth-child(3) { animation-delay: 140ms; }
  #book-view.bk-fx .bk-sec.bk-in .bk-shelf:nth-child(n + 4) { animation-delay: 210ms; }

  /* I consigli arrivano dopo la sezione (chiesti quando entra): atterrano appena disegnati. */
  #book-view.bk-fx .bk-rec {
    animation: motion-lb-land 600ms cubic-bezier(0.3, 1.3, 0.5, 1) backwards;
    animation-delay: calc(var(--k, 0) * 80ms);
  }

  @keyframes motion-bk-float {
    50% {
      translate: 0 -6px;
    }
  }

  @keyframes motion-bk-pop {
    from {
      opacity: 0;
      scale: 0.3;
    }
  }

  /* La parte letta del cursore (--share, vedi pageControl) cresce da zero. */
  @keyframes motion-bk-fill {
    from {
      --share: 0%;
    }
  }

  @keyframes motion-bk-unfold {
    from {
      clip-path: inset(0 100% 0 0);
    }

    to {
      clip-path: inset(0 0 0 0);
    }
  }
}
