/* "STA PENSANDO": l'indicatore di attesa quando l'app sta calcolando qualcosa di pesante —
   una proposta d'ordine, i dettagli di una riga, una pagina che si costruisce.

   Fatto in CSS puro, senza librerie: e' un'animazione, non vale una dipendenza da mantenere
   (ne' una licenza da verificare). Tre anelli concentrici che ruotano a velocita' diverse piu'
   un nucleo che pulsa: la sensazione e' quella di qualcosa che elabora, non di una rotella che
   gira a vuoto.

   Rispetta prefers-reduced-motion: a chi ha chiesto meno movimento resta il nucleo che pulsa
   piano, senza rotazioni — un indicatore che fa venire il mal di testa non e' un indicatore. */

.thinking {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  font-size: 0.88rem;
  color: var(--gray-text);
}

.thinking-core {
  position: relative;
  width: 2.2rem;
  height: 2.2rem;
  flex-shrink: 0;
}

/* Gli anelli: archi aperti, non cerchi chiusi — un cerchio pieno che ruota non si vede
   ruotare. Ognuno gira a velocita' e verso diversi: e' il movimento discorde a dare l'idea
   del calcolo invece dell'attesa. */
.thinking-core::before,
.thinking-core::after,
.thinking-ring {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid transparent;
}

.thinking-core::before {
  border-top-color: var(--navy);
  border-right-color: var(--navy);
  animation: thinking-spin 1.1s cubic-bezier(0.5, 0.1, 0.4, 0.9) infinite;
}

.thinking-core::after {
  inset: 0.35rem;
  border-bottom-color: var(--navy-bright);
  border-left-color: var(--navy-bright);
  opacity: 0.8;
  animation: thinking-spin 1.7s cubic-bezier(0.4, 0.2, 0.5, 0.8) infinite reverse;
}

.thinking-ring {
  inset: 0.7rem;
  border-top-color: var(--azure);
  animation: thinking-spin 0.8s linear infinite;
}

/* Il nucleo: il punto che pulsa al centro, quello che fa sembrare che ci sia qualcuno
   dentro a pensare. */
.thinking-dot {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0.3rem;
  height: 0.3rem;
  margin: -0.15rem 0 0 -0.15rem;
  border-radius: 50%;
  background: var(--navy);
  animation: thinking-pulse 1.4s ease-in-out infinite;
}

.thinking-label {
  font-weight: 500;
}

/* I tre puntini dopo il testo: si accendono a turno, come chi sta scrivendo. */
.thinking-dots::after {
  content: "";
  animation: thinking-ellipsis 1.5s steps(4, end) infinite;
}

@keyframes thinking-spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes thinking-pulse {
  0%, 100% {
    transform: scale(1);
    opacity: 0.4;
  }

  50% {
    transform: scale(2.2);
    opacity: 1;
  }
}

@keyframes thinking-ellipsis {
  0% {
    content: "";
  }

  25% {
    content: "·";
  }

  50% {
    content: "··";
  }

  75% {
    content: "···";
  }
}

@media (prefers-reduced-motion: reduce) {
  .thinking-core::before,
  .thinking-core::after,
  .thinking-ring {
    animation: none;
    border-color: var(--border);
    border-top-color: var(--navy);
  }

  .thinking-dot {
    animation: thinking-pulse 2.4s ease-in-out infinite;
  }

  .thinking-dots::after {
    content: "···";
    animation: none;
  }
}

/* L'ATTESA GRANDE (`shared/_attesa`): TRE ZONE UNA SOTTO L'ALTRA, non tre strati sovrapposti.

   La prima versione impilava rete, icona, etichetta e passi nello stesso punto: la scritta
   finiva sopra le sinapsi, la rete usciva da tutte le parti e i passi la tagliavano in mezzo
   (Mattias 2026-08-06: "hai fatto una roba orribile", e aveva ragione).

   Adesso: la mente nel suo riquadro, sotto cosa sta facendo, sotto i passi. Il testo sta su
   fondo pulito e non ha bisogno di nessun trucco per essere leggibile. */

.attesa {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.2rem;
  padding: 2.5rem 1.5rem;
}

/* Nei blocchi grossi — i dettagli del calcolo, la tabella del gruppo — lo spazio si prenota
   prima: se no si apre alto due dita e un istante dopo ci compare dentro mezzo metro di
   tabelle, e la pagina scatta sotto le mani. */
.attesa.is-piena {
  min-height: 22rem;
  justify-content: center;
}

/* LA MENTE: il riquadro che contiene tutto quello che si muove. Ha una misura sua e niente ne
   esce — e' questo che tiene il disegno pulito. */
.attesa-mente {
  position: relative;
  width: 11rem;
  height: 11rem;
  flex: 0 0 auto;
}

.attesa-icona {
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -1.6rem 0 0 -1.6rem;
}

.attesa-icona .thinking-core {
  width: 3.2rem;
  height: 3.2rem;
}

.attesa-icona .thinking-core::before,
.attesa-icona .thinking-core::after,
.attesa-icona .thinking-ring {
  border-width: 3px;
}

.attesa-icona .thinking-ring {
  inset: 1rem;
}

.attesa-etichetta {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  color: var(--navy);
  text-align: center;
  animation: attesa-fiato 3.4s ease-in-out infinite;
}

/* LA RETE CHE PENSA (`shared/_sinapsi`): due lobi di nodi, e impulsi che corrono lungo le
   sinapsi. Riempie la mente e ci sta dentro; l'icona degli anelli sta sopra, al centro.

   Gli impulsi sono un trattino che scorre: la linea e' tratteggiata con un segmento corto e un
   vuoto lunghissimo, e animando lo scorrimento del tratteggio quell'unico segmento percorre
   tutta la sinapsi. Sfasando i ritardi, i segnali non partono mai tutti insieme — e' quello
   che lo fa sembrare pensiero e non una decorazione che lampeggia a tempo. */

.sinapsi {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  /* LA RETE SI MUOVE, non solo i segnali che ci corrono dentro: si inclina come un ologramma
     che gira su se stesso, e i nodi vicini e lontani si spostano di diverso. Ondeggia avanti e
     indietro invece di girare tutta — un giro completo la farebbe sparire di taglio a meta'. */
  animation: sinapsi-ologramma 16s ease-in-out infinite;
}

@keyframes sinapsi-ologramma {
  0%, 100% {
    transform: perspective(700px) rotateY(-19deg) rotateZ(-3deg) scale(0.95);
  }

  50% {
    transform: perspective(700px) rotateY(19deg) rotateZ(3deg) scale(1.05);
  }
}

/* Il tracciato spento, sotto: si intravede appena e serve a far capire dove passeranno gli
   impulsi — senza, i segnali sembrerebbero comparire dal nulla. */
.sinapsi-tracciato line {
  stroke: rgba(53, 71, 171, 0.12);
  stroke-width: 1;
}

/* Le stesse linee sopra, ma tratteggiate con un segmento corto e un vuoto lunghissimo: e'
   quell'unico segmento che percorre tutta la sinapsi quando si anima lo scorrimento. */
.sinapsi-rete line {
  stroke-dasharray: 10 300;
  stroke-dashoffset: 310;
  stroke-linecap: round;
  animation: sinapsi-impulso 2.1s cubic-bezier(0.45, 0, 0.35, 1) infinite;
}

.sinapsi-rete line:nth-child(6n + 1) {
  animation-delay: 0s;
}

.sinapsi-rete line:nth-child(6n + 2) {
  animation-delay: 0.45s;
}

.sinapsi-rete line:nth-child(6n + 3) {
  animation-delay: 0.9s;
}

.sinapsi-rete line:nth-child(6n + 4) {
  animation-delay: 1.35s;
}

.sinapsi-rete line:nth-child(6n + 5) {
  animation-delay: 1.8s;
}

.sinapsi-rete line:nth-child(6n) {
  animation-delay: 2.25s;
}

.sinapsi-nodi circle {
  fill: var(--navy-bright);
  transform-box: fill-box;
  transform-origin: center;
  animation: sinapsi-nodo 2.8s ease-in-out infinite;
}

.sinapsi-nodi circle:nth-child(5n + 1) {
  animation-delay: 0.2s;
}

.sinapsi-nodi circle:nth-child(5n + 2) {
  animation-delay: 0.75s;
}

.sinapsi-nodi circle:nth-child(5n + 3) {
  animation-delay: 1.3s;
}

.sinapsi-nodi circle:nth-child(5n + 4) {
  animation-delay: 1.85s;
}

.sinapsi-nodi circle:nth-child(5n) {
  animation-delay: 2.4s;
}

/* L'impulso parte spento, si accende mentre corre e si spegne arrivando: un segnale che
   viaggia, non un trattino che scivola. */
@keyframes sinapsi-impulso {
  0% {
    stroke: rgba(53, 71, 171, 0);
    stroke-width: 1;
    stroke-dashoffset: 310;
  }

  12% {
    stroke: rgba(120, 200, 255, 1);
    stroke-width: 3.2;
  }

  40% {
    stroke: rgba(42, 120, 214, 0.9);
    stroke-width: 2;
  }

  85% {
    stroke: rgba(42, 120, 214, 0.35);
    stroke-width: 1.2;
  }

  100% {
    stroke: rgba(53, 71, 171, 0);
    stroke-width: 1;
    stroke-dashoffset: 0;
  }
}

@keyframes sinapsi-nodo {
  0%, 100% {
    opacity: 0.18;
    transform: scale(0.8);
  }

  40% {
    opacity: 1;
    transform: scale(1.6);
  }

  60% {
    opacity: 0.75;
    transform: scale(1.15);
  }
}

/* IL RAGIONAMENTO SCRITTO: i passi compaiono uno dopo l'altro mentre il server lavora. Quello
   in corso e' scuro e col suo puntino che pulsa, i fatti restano grigi col segno di spunta,
   quelli che devono ancora venire tengono il posto senza mostrarsi — cosi' il blocco non
   cambia altezza a ogni riga e non fa saltare quello che c'e' intorno.

   Niente fondo, niente riquadro: sotto non passa piu' niente, perche' la rete sta nel suo
   spazio la' sopra. */
.attesa-passi {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: left;
}

.attesa-passo {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.92rem;
  color: var(--gray-text);
  white-space: nowrap;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.35s ease, transform 0.35s ease, color 0.35s ease;
}

.attesa-passo::before {
  content: "";
  flex: 0 0 auto;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--border);
  transition: background 0.3s ease, transform 0.3s ease;
}

.attesa-passo.is-visibile {
  opacity: 1;
  transform: none;
}

.attesa-passo.is-corrente {
  color: var(--navy);
  font-weight: 600;
}

.attesa-passo.is-corrente::before {
  background: var(--navy-bright);
  animation: attesa-passo-pulsa 1.2s ease-in-out infinite;
}

.attesa-passo.is-fatto::before {
  content: "✓";
  width: auto;
  height: auto;
  background: none;
  color: var(--semaforo-verde);
  font-size: 0.8rem;
  font-weight: 700;
  line-height: 1;
}

@keyframes attesa-passo-pulsa {
  0%, 100% {
    transform: scale(1);
    opacity: 0.55;
  }

  50% {
    transform: scale(1.6);
    opacity: 1;
  }
}

/* L'ALONE che respira dietro la rete: tiene il centro caldo e l'occhio sul punto dove
   comparira' il contenuto. Sta dentro la mente, non ne esce.

   L'aurora conica che c'era prima e' stata tolta: sommata alla rete faceva una macchia sola e
   nessuna delle due si distingueva piu'. Uno strato che si muove basta. */
.attesa-alone {
  position: absolute;
  inset: -12%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(42, 120, 214, 0.16) 0%, rgba(42, 120, 214, 0) 70%);
  pointer-events: none;
  animation: attesa-respiro 3.4s ease-in-out infinite;
}

@keyframes attesa-respiro {
  0%, 100% {
    transform: scale(0.82);
    opacity: 0.5;
  }

  50% {
    transform: scale(1.08);
    opacity: 0.95;
  }
}

@keyframes attesa-fiato {
  0%, 100% {
    opacity: 0.65;
  }

  50% {
    opacity: 1;
  }
}

/* A chi ha chiesto meno movimento resta la stessa immagine, ferma: i colori ci sono, non si
   muove niente. Un caricamento che fa venire il mal di testa non e' un caricamento. */
@media (prefers-reduced-motion: reduce) {
  .attesa-alone,
  .attesa-etichetta,
  .attesa-passo.is-corrente::before,
  .sinapsi,
  .sinapsi-rete line,
  .sinapsi-nodi circle {
    animation: none;
  }

  /* Ferma, ma non di taglio: senza l'animazione servirebbe comunque l'inclinazione, se no
     resterebbe l'ultima posizione calcolata dal browser. */
  .sinapsi {
    transform: none;
  }

  /* La rete resta, ferma e accesa: si vede il disegno, non si muove niente. */
  .sinapsi-rete line {
    stroke: rgba(42, 120, 214, 0.5);
    stroke-dasharray: none;
    stroke-dashoffset: 0;
  }

  .sinapsi-nodi circle {
    opacity: 0.6;
  }

  .attesa-alone {
    opacity: 0.7;
  }

  /* I passi restano, ma senza scivolare dentro: compaiono e basta. */
  .attesa-passo {
    transition: none;
    transform: none;
  }
}

/* LA BARRA DI TURBO, in tinta col resto: la pagina che si carica si vede da sopra, sottile,
   senza coprire niente. Turbo la mette da solo su ogni navigazione lenta. */
.turbo-progress-bar {
  height: 3px;
  background: linear-gradient(90deg, var(--navy) 0%, var(--navy-bright) 50%, var(--azure) 100%);
}

/* Il messaggio dentro un frame che non si e' potuto servire. */
.frame-message {
  margin: 0.5rem 0;
  padding: 0.6rem 0.8rem;
  background: #fef7e0;
  border-left: 4px solid #d9b23c;
  border-radius: var(--radius-small);
  font-size: 0.85rem;
  color: #7a5d00;
}
