/* ===========================================
   AVVISI — la risposta del prodotto dopo un'azione

   Due cose, un foglio solo, perché sono lo stesso mestiere: dire all'utente
   com'è andata (.avviso) e chiedergli conferma prima di fare un danno
   (.dialogo).

   Perché esiste: prima di questo file il prodotto non rispondeva. I flash di
   Symfony venivano scritti da 14 controller e renderizzati da nessun layout —
   solo i template master/* li stampavano — quindi i redirect che spiegano
   perché sei stato rimbalzato ("Nessuna sede ancora", "Questa azienda è
   disattivata") ti riportavano alla lista in silenzio. Il resto del feedback
   erano 94 alert() nativi e 38 confirm() nativi: non si vestono, bloccano il
   thread e su mobile sembrano un errore del browser, non una risposta del
   gestionale.

   Dove stanno sullo schermo: in alto a destra. Gli angoli in basso sono
   occupati — a sinistra la card del Cloud offline (cloud-health-check.js,
   z-index 1040), a destra le notifiche push (push-notifications.js, 1040) e il
   widget della chat. In alto a destra non c'è niente.
   =========================================== */

/* ===== AVVISI (toast) ===== */

.avvisi {
  position: fixed;
  top: 76px;              /* sotto la top bar */
  right: 16px;
  z-index: var(--z-avvisi);
  display: flex;
  flex-direction: column;
  gap: var(--k-space-3);
  width: min(380px, calc(100vw - 32px));
  /* Il contenitore è sempre lì e coprirebbe l'angolo anche da vuoto: i click
     passano attraverso, li riprendono i singoli avvisi. */
  pointer-events: none;
}

.avviso {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: var(--k-space-3);
  padding: var(--k-space-3) 14px;
  border-radius: var(--k-radius);                              /* raggio card del sistema */
  background: var(--color-bg-primary, var(--color-white));
  border: 1px solid var(--color-border-light, var(--color-gray-200));
  box-shadow: var(--k-shadow);       /* ombra card del sistema */
  font-size: var(--k-text-md);
  line-height: 1.45;
  color: var(--color-text-primary, var(--color-gray-900));
}

/* Lo stato lo dice l'icona, non un bordo colorato a sinistra: il side-stripe è
   fra gli anti-pattern dichiarati del prodotto (v. .claude/docs/product-design.md). */
.avviso-icona {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  display: grid;
  place-items: center;
  border-radius: var(--k-circle);
  font-size: var(--k-text-2xs);
}

.avviso-testo {
  flex: 1 1 auto;
  min-width: 0;
  /* I messaggi dei controller sono frasi intere, non etichette: vanno a capo. */
  overflow-wrap: anywhere;
}

/* Stessa regola per tinta che vale per i ruoli (v. colors.css): i colori freddi
   scuriscono e tengono il glifo bianco, l'ambra resta viva e prende il glifo
   scuro — scurita diventa marrone, e un pallino marrone non dice "attenzione". */
.avviso--success .avviso-icona { background: var(--color-success-solid); color: var(--color-white); }
.avviso--danger  .avviso-icona { background: var(--color-danger-solid);  color: var(--color-white); }
.avviso--info    .avviso-icona { background: var(--color-info-solid);    color: var(--color-white); }
.avviso--warning .avviso-icona { background: var(--color-warning);       color: var(--color-gray-900); }

/* ----- Vestito da notifica (avvisi.js vesti) -----
   Lo stesso della notifica con la mascotte (chat-widget.css, .communication-alert):
   card chiara, mascotte dell'area a sinistra con l'icona del tipo sopra la testa,
   titolo nel colore del tipo. Qui in piccolo, perché gli avvisi si impilano. */
.avviso--success { --ca: var(--color-success-solid); }
.avviso--danger  { --ca: var(--color-danger-solid); }
.avviso--info    { --ca: var(--color-info-solid); }
.avviso--warning { --ca: var(--color-warning); }

.avvisi:has(.avviso--mascotte) {
  width: min(420px, calc(100vw - 32px));
}

.avviso--mascotte {
  align-items: center;
  padding: var(--k-space-3) var(--k-space-4) var(--k-space-3) var(--k-space-3);
  box-shadow: var(--k-shadow-lg);
}

.avviso-mascotte {
  position: relative;
  flex: 0 0 auto;
  --mascotte-w: 64px;
  margin: -12px 0 -8px;
  animation: avviso-mascotte-pop 0.55s cubic-bezier(0.2, 0.9, 0.3, 1.3) both;
}

.avviso-mascotte .mascotte {
  position: relative;
  cursor: pointer;
}

/* Icona del tipo sopra la testa: dentro .mascotte, così fluttua con lei; sopra il
   respiro della mascotte verrebbe tagliata a metà (v. mascotte.css) */
.avviso-testa {
  position: absolute;
  top: max(0px, calc(var(--respiro-y) - 9px));
  left: 60%;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: var(--k-circle);
  border: 2px solid var(--color-white);
  background: var(--ca);
  color: var(--color-white);
  font-size: var(--k-text-xs);
  line-height: 1;
  box-shadow: var(--k-shadow);
  animation: avviso-testa-pop 0.5s cubic-bezier(0.2, 0.9, 0.3, 1.4) 0.15s both;
}

/* l'ambra resta viva col glifo scuro, come il pallino */
.avviso--warning .avviso-testa { color: var(--color-gray-900); }

.avviso-corpo {
  flex: 1 1 auto;
  min-width: 0;
}

.avviso-titolo {
  display: block;
  margin-bottom: 2px;
  font-size: var(--k-text-lg);
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--ca);
}

.avviso--warning .avviso-titolo { color: var(--color-warning-solid); }

.avviso--mascotte .avviso-testo {
  margin: 0;
  color: var(--color-text-secondary, var(--color-gray-600));
}

@keyframes avviso-mascotte-pop {
  from { opacity: 0; transform: scale(0.5) translateY(10px); }
  to   { opacity: 1; transform: none; }
}

@keyframes avviso-testa-pop {
  from { opacity: 0; transform: scale(0) translateY(8px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .avviso-mascotte, .avviso-testa { animation: none; }
}

.avviso-chiudi {
  flex: 0 0 auto;
  /* 14px di padding attorno a un glifo da 16px: il bersaglio arriva a 44px
     senza che il bottone si veda grande. */
  margin: -14px -14px -14px 0;
  padding: 14px;
  border: 0;
  background: none;
  color: var(--color-text-muted, var(--color-gray-500));
  font-size: var(--k-text-xl);
  line-height: 1;
  cursor: pointer;
  border-radius: var(--k-radius);
}

.avviso-chiudi:hover { color: var(--color-text-primary, var(--color-gray-900)); }

.avviso-chiudi:focus-visible {
  outline: 2px solid var(--color-primary-solid);
  outline-offset: -2px;
}

/* Entrata e uscita: arriva da destra, esce verso destra. L'uscita è più rapida
   dell'entrata — una cosa che se ne va non deve farsi aspettare. */
.avviso {
  animation: avviso-entra 0.22s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.avviso.is-uscita {
  animation: avviso-esce 0.16s ease-in both;
}

@keyframes avviso-entra {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: none; }
}

@keyframes avviso-esce {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateX(16px); }
}

/* ===== DIALOGO DI CONFERMA ===== */

.dialogo-velo {
  position: fixed;
  inset: 0;
  z-index: var(--z-dialogo);
  display: grid;
  place-items: center;
  padding: var(--k-space-4);
  background: color-mix(in srgb, var(--color-gray-900) 45%, transparent);
  animation: dialogo-velo-entra 0.15s ease both;
}

.dialogo {
  width: min(440px, 100%);
  background: var(--color-bg-primary, var(--color-white));
  border-radius: var(--k-radius);
  /* Più profonda dell'ombra card: qui serve staccare dal velo, non posare su
     una pagina. */
  box-shadow: var(--k-shadow-xl);
  padding: var(--k-space-5);
  animation: dialogo-entra 0.18s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Mascotte a sinistra, domanda a destra. Sopra, come fa shared/_vuoto,
   occuperebbe un'altezza che un dialogo non si può permettere: qui la domanda
   deve restare la prima cosa che leggi. */
.dialogo-testa {
  display: flex;
  align-items: flex-start;
  gap: var(--k-space-4);
}

.dialogo-mascotte {
  flex: 0 0 auto;
  margin-top: 2px;
  /* Il <template> dell'area la stampa a 60px: qui scende a 48, perché accanto
     a due righe di testo 60 pesa troppo. Si scavalca con --mascotte-w e basta
     — è la leva prevista da mascotte.css (`--mw: var(--mascotte-w, var(--size)`),
     e la proprietà eredita fino alla .mascotte dentro. Nessuna width sul
     guscio: la mascotte non è quadrata e se la calcola da sé. */
  --mascotte-w: 48px;
}

.dialogo-testi {
  flex: 1 1 auto;
  min-width: 0;
}

.dialogo-titolo {
  margin: 0;
  font-size: var(--k-text-xl);
  font-weight: 600;
  color: var(--color-text-primary, var(--color-gray-900));
  /* La domanda nomina l'oggetto, quindi può essere lunga: niente ellissi. */
  line-height: 1.4;
}

.dialogo-dettaglio {
  margin: var(--k-space-2) 0 0;
  font-size: var(--k-text-md);
  line-height: 1.55;
  color: var(--color-text-secondary, var(--color-gray-600));
  /* I messaggi ereditati dai confirm() vanno a capo di loro: pre-line tiene
     gli a capo veri e continua a mandare a capo il resto da solo. */
  white-space: pre-line;
}

.dialogo-azioni {
  display: flex;
  justify-content: flex-end;
  gap: var(--k-space-2);
  margin-top: var(--k-space-5);
}

/* I bottoni sono quelli del sistema (.btn di Bootstrap, ricolorati in
   colors.css): un dialogo non è il posto dove inventare un bottone nuovo. */
.dialogo-azioni .btn {
  min-height: 44px;
  padding-inline: var(--k-space-5);
}

.dialogo-azioni .btn:focus-visible {
  outline: 2px solid var(--color-primary-solid);
  outline-offset: 2px;
}

@keyframes dialogo-velo-entra {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes dialogo-entra {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}

/* Sul telefono i due bottoni vanno a tutta larghezza e si impilano, con la
   conferma sotto: sul pollice la posizione più comoda è quella bassa, e la
   conferma è l'azione che l'utente è venuto a fare. */
@media (max-width: 480px) {
  .avvisi {
    top: 68px;
    right: 12px;
    left: 12px;
    width: auto;
  }

  .dialogo-azioni {
    flex-direction: column-reverse;
  }

  .dialogo-azioni .btn {
    width: 100%;
  }
}

/* Chi ha chiesto meno movimento non lo riceve. Vale per tutto quello che si
   muove qui dentro: gli avvisi compaiono e spariscono, il dialogo appare. */
@media (prefers-reduced-motion: reduce) {
  .avviso,
  .avviso.is-uscita,
  .dialogo,
  .dialogo-velo {
    animation-duration: 0.01ms;
    animation-iteration-count: 1;
  }
}
