/* === [hidden] VINCE SEMPRE ===
   Il browser da' agli elementi con l'attributo `hidden` un `display:none` a
   specificita' minima: basta una regola di classe con `display:flex` per
   annullarlo, e da quel momento nascondere un elemento dal codice non lo
   nasconde piu'. E' successo davvero — un pannello che non si chiudeva, col
   codice che faceva la cosa giusta e nessun errore da nessuna parte: il
   difetto piu' difficile da vedere. Con questa riga non puo' piu' capitare. */
[hidden] { display: none !important; }

* { margin: 0; padding: 0; box-sizing: border-box; }

/* ============================================================
   FONDAMENTA VISIVE — palette WhatsApp
   ============================================================
   Scelta dell'utente: il pannello deve somigliare a WhatsApp,
   perche' e' li' che il personale del negozio passera' la
   giornata e la somiglianza vale piu' della nostra identita'.

   I valori sono quelli veri di WhatsApp Web, con UNA correzione
   che va spiegata: il verde #00A884 col testo bianco sopra fa
   3,03:1 di contrasto, sotto il minimo leggibile (4,5). WhatsApp
   lo usa su bottoni che contengono solo icone, dove la regola non
   si applica. Qui invece i bottoni hanno delle parole dentro, quindi:

     --accent       #008069  verde scuro, dove c'e' del TESTO (4,89:1)
     --accent-vivo  #00A884  verde WhatsApp, per icone, barre e stati
     --nonletti     #25D366  il verde acceso del pallino dei non letti

   Il rosso Tatech (#CF1224) non sparisce: resta nel logo, e da qui
   in avanti fa il colore delle azioni distruttive — ruolo in cui,
   con l'accento diventato verde, non da' piu' nessuna ambiguita'.
   ============================================================ */

:root, [data-theme="light"] {
  /* --- Verdi WhatsApp --- */
  --wa-50:  #e7fcf4;
  --wa-100: #d9fdd3;   /* bolla dei messaggi inviati */
  --wa-200: #a5e8c8;
  --wa-300: #6ed6a8;
  --wa-400: #25d366;   /* verde acceso: pallini, notifiche */
  --wa-500: #00a884;   /* verde WhatsApp */
  --wa-600: #008069;   /* verde per il testo */
  --wa-700: #006c58;
  --wa-800: #005c4b;   /* bolla inviati, tema scuro */
  --wa-900: #075e54;   /* teal storico */

  /* --- Grigi WhatsApp --- */
  --grigio-0:   #ffffff;
  --grigio-25:  #fbfbfb;
  --grigio-50:  #f7f8fa;
  --grigio-100: #f0f2f5;   /* fondo dell'applicazione */
  --grigio-200: #e9edef;   /* bordi */
  --grigio-300: #d1d7db;   /* bordi marcati */
  /* I due grigi del testo tenue, con il contrasto MISURATO e non a occhio.
     Prima erano #8696a0 e #667781: il primo dava 3,05:1 sul bianco, sotto il
     minimo leggibile di 4,5 — ed e' il grigio con cui sono scritte date, note
     e sottotitoli, cioe' testo piccolo, dove servirebbe anche di piu'. Su uno
     schermo buono in una stanza buia si legge; su un portatile di fronte a una
     finestra sparisce. */
  --grigio-400: #5d6b73;   /* testo tenue — 5,5:1 sul bianco */
  --grigio-500: #4a5860;   /* testo secondario — 7,1:1 sul bianco */
  --grigio-600: #4a5860;
  --grigio-700: #33434d;
  --grigio-800: #202c33;
  --grigio-900: #111b21;   /* testo e pannelli scuri */

  /* --- Ruoli --- */
  --bg: var(--grigio-100);
  --bg-alt: var(--grigio-50);
  --bg-2: var(--grigio-50);
  --surface: var(--grigio-0);
  --surface-alt: var(--grigio-50);
  --surface-hover: var(--grigio-100);
  --text: var(--grigio-900);
  --text-2: var(--grigio-500);
  --text-secondary: var(--grigio-500);
  --text-3: var(--grigio-400);
  --text-light: var(--grigio-0);
  --border: var(--grigio-200);
  --border-forte: var(--grigio-300);
  --code-bg: var(--grigio-100);

  --accent: var(--wa-600);
  --accent-2: var(--wa-700);
  --accent-vivo: var(--wa-500);
  --accent-debole: var(--wa-50);
  --su-accento: #ffffff;
  --nonletti: var(--wa-400);
  --su-nonletti: var(--grigio-900);

  /* --- Conversazione --- */
  --chat-sfondo: #efeae2;
  --bolla-entrata: #ffffff;
  --su-bolla-entrata: var(--grigio-900);
  --bolla-uscita: var(--wa-100);
  --su-bolla-uscita: var(--grigio-900);

  --green: var(--wa-600);
  --success: var(--wa-600);
  --success-debole: var(--wa-50);
  /* Il rosso del marchio Tatech, qui nel ruolo di "attenzione, e' definitivo". */
  --red: #cf1224;
  --danger: #cf1224;
  --danger-debole: #fdecee;
  --yellow: #8a5a00;
  --warning: #8a5a00;
  --warning-debole: #fdf3e2;
  --info: #027eb5;
  --info-debole: #e7f4fb;

  --sidebar-bg: var(--grigio-900);
  --sidebar-text: var(--grigio-400);
  --sidebar-active: #ffffff;
  --sidebar-attivo-bg: var(--wa-600);

  /* --- Tipografia --- */
  --font: 'SF Mono', 'Consolas', 'Liberation Mono', Menlo, monospace;
  --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Roboto, Arial, sans-serif;
  --t-xs: 11px;
  --t-sm: 12px;
  --t-base: 13px;
  --t-md: 15px;
  --t-lg: 18px;
  --t-xl: 22px;
  --t-2xl: 28px;

  /* --- Spaziature --- */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 20px; --s-6: 24px; --s-8: 32px; --s-10: 40px;
  /* Il margine della pagina, in un posto solo: l'intestazione del cliente ci
     esce fuori con un margine negativo, e quando i due numeri non erano lo
     stesso (20 nel contenuto, 12 sul telefono) la pagina scorreva in
     orizzontale di 8 pixel senza che si capisse perche'. */
  --pad-pagina: 20px;
  /* Altezza della barra che compare solo sul telefono. */
  --h-barra: 52px;

  /* --- Forma --- */
  --r-sm: 4px; --r: 8px; --r-lg: 12px; --r-xl: 16px; --r-tonda: 999px;

  --shadow-sm: 0 1px 2px rgba(11,20,26,0.06);
  --shadow: 0 1px 3px rgba(11,20,26,0.08), 0 1px 2px rgba(11,20,26,0.04);
  --shadow-md: 0 4px 12px rgba(11,20,26,0.10), 0 2px 4px rgba(11,20,26,0.05);
  --shadow-lg: 0 12px 32px rgba(11,20,26,0.14), 0 4px 8px rgba(11,20,26,0.07);
  --anello: 0 0 0 3px rgba(0,168,132,0.22);

  --modal-bg: rgba(11,20,26,0.5);

  --tr-veloce: 120ms cubic-bezier(0.4, 0, 0.2, 1);
  --tr: 180ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* === SCURO — i colori del tema scuro di WhatsApp Web === */
[data-theme="dark"] {
  --grigio-0:   #0b141a;   /* fondo della conversazione */
  --grigio-25:  #0d1a21;
  --grigio-50:  #111b21;   /* fondo dell'applicazione */
  --grigio-100: #182229;
  --grigio-200: #202c33;   /* pannelli */
  --grigio-300: #2a3942;   /* bordi */
  /* Stessa correzione al contrario: #667781 sul pannello scuro dava 3,08:1.
     Adesso il testo tenue sta a 5,9:1 e il secondario a 7,2:1. */
  --grigio-400: #9aa8b1;
  --grigio-500: #aebac1;
  --grigio-600: #ccd0d5;
  --grigio-700: #ccd0d5;
  --grigio-800: #dfe3e7;
  --grigio-900: #e9edef;   /* testo */

  --bg: var(--grigio-50);
  --bg-alt: var(--grigio-100);
  --bg-2: var(--grigio-100);
  --surface: var(--grigio-200);
  --surface-alt: var(--grigio-100);
  --surface-hover: var(--grigio-300);
  --text: var(--grigio-900);
  --text-2: var(--grigio-500);
  --text-secondary: var(--grigio-500);
  --text-3: var(--grigio-400);
  --text-light: #ffffff;
  --border: var(--grigio-300);
  --border-forte: #313d45;
  --code-bg: var(--grigio-100);

  /* Sul fondo scuro il verde puo' tornare quello vivo: contro #202C33 il
     contrasto c'e', ed e' esattamente quello che fa WhatsApp. */
  --accent: var(--wa-500);
  --accent-2: var(--wa-300);
  --accent-vivo: var(--wa-500);
  --accent-debole: rgba(0,168,132,0.16);
  --su-accento: #04231c;
  --nonletti: var(--wa-500);
  --su-nonletti: #04231c;

  --chat-sfondo: #0b141a;
  --bolla-entrata: #202c33;
  --su-bolla-entrata: var(--grigio-900);
  --bolla-uscita: var(--wa-800);
  --su-bolla-uscita: var(--grigio-900);

  --green: var(--wa-500);
  --success: var(--wa-500);
  --success-debole: rgba(0,168,132,0.16);
  --red: #f2637a;
  --danger: #f2637a;
  --danger-debole: rgba(242,99,122,0.15);
  --yellow: #e0a33c;
  --warning: #e0a33c;
  --warning-debole: rgba(224,163,60,0.15);
  --info: #53bdeb;
  --info-debole: rgba(83,189,235,0.15);

  --sidebar-bg: #0b141a;
  --sidebar-text: var(--grigio-500);
  --sidebar-active: #ffffff;
  --sidebar-attivo-bg: var(--wa-800);

  --shadow-sm: 0 1px 2px rgba(0,0,0,0.4);
  --shadow: 0 1px 3px rgba(0,0,0,0.5), 0 1px 2px rgba(0,0,0,0.3);
  --shadow-md: 0 4px 12px rgba(0,0,0,0.5), 0 2px 4px rgba(0,0,0,0.3);
  --shadow-lg: 0 12px 32px rgba(0,0,0,0.6), 0 4px 8px rgba(0,0,0,0.4);
  --anello: 0 0 0 3px rgba(0,168,132,0.35);

  --modal-bg: rgba(0,0,0,0.7);
}

/* Chi ha chiesto meno animazioni non deve subirle: non e' una preferenza
   estetica, per qualcuno il movimento sullo schermo da' nausea. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Il contorno di messa a fuoco serve a chi naviga da tastiera: prima
   non c'era su nulla tranne le schede del cliente. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

body {
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--text);
  font-size: var(--t-base);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* La barra di scorrimento: quella di sistema su fondo scuro e' bianca e
   spacca il tema. */
* { scrollbar-width: thin; scrollbar-color: var(--grigio-300) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: var(--grigio-300); border-radius: var(--r-tonda); border: 3px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: var(--grigio-400); background-clip: content-box; }
*::-webkit-scrollbar-track { background: transparent; }

/* === TEMA === */
.theme-toggle {
  background: transparent; border: 1px solid rgba(255,255,255,0.15); border-radius: var(--r-sm);
  width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  cursor: pointer; font-size: var(--t-base); margin-left: auto; flex-shrink: 0;
  transition: border-color var(--tr), background var(--tr);
}
.theme-toggle:hover { border-color: var(--accent); background: rgba(255,255,255,0.06); }
.login-theme-toggle {
  position: fixed; top: var(--s-4); right: var(--s-4);
  border-color: var(--border); color: var(--text-2); background: var(--surface);
}

/* === ACCESSO === */
.login-wrapper {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: var(--bg); padding: var(--s-4);
}
.login-box {
  width: 100%; max-width: 380px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-xl); padding: var(--s-8);
  box-shadow: var(--shadow-lg);
}
.login-box h1 { text-align: center; font-size: var(--t-lg); font-weight: 650; margin-bottom: var(--s-1); letter-spacing: -0.2px; }
.login-box .subtitle { text-align: center; color: var(--text-2); margin-bottom: var(--s-6); font-size: var(--t-sm); }
.login-box .error-msg {
  background: var(--danger-debole); color: var(--danger);
  padding: var(--s-3); font-size: var(--t-sm); margin-bottom: var(--s-3);
  display: none; border-radius: var(--r); border: 1px solid var(--danger);
}
.logo-login { display: block; margin: 0 auto var(--s-5); height: 44px; width: auto; }

/* === IMPIANTO === */
.app-layout { display: flex; min-height: 100vh; }

.sidebar {
  position: fixed; top: 0; left: 0; bottom: 0; width: 200px;
  background: var(--sidebar-bg); color: var(--sidebar-text);
  display: flex; flex-direction: column; z-index: 100;
}
.sidebar-header { padding: var(--s-4) var(--s-4) var(--s-3); border-bottom: 1px solid rgba(255,255,255,0.07); }
.logo { display: flex; align-items: center; gap: var(--s-2); }
.logo img { height: 26px; width: auto; }
.sidebar-header h2 { font-size: var(--t-base); font-weight: 700; color: #fff; letter-spacing: 0.2px; }
.sidebar-header small { color: var(--grigio-500); font-size: var(--t-xs); }

.sidebar-nav { flex: 1; padding: var(--s-3) var(--s-2); display: flex; flex-direction: column; gap: 2px; }
.sidebar-nav a {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-2) var(--s-3); border-radius: var(--r);
  color: var(--sidebar-text); text-decoration: none;
  font-size: var(--t-base); font-weight: 500;
  transition: background var(--tr-veloce), color var(--tr-veloce);
}
.sidebar-nav a:hover { color: #fff; background: rgba(255,255,255,0.05); }
/* La voce attiva ha il fondo pieno del marchio: era una linguetta di 2px sul
   bordo sinistro, che a colpo d'occhio non si vedeva. */
.sidebar-nav a.active { color: var(--sidebar-active); background: var(--sidebar-attivo-bg); font-weight: 600; }
.sidebar-nav a .icon { width: 18px; text-align: center; font-size: var(--t-md); flex-shrink: 0; }
.nav-divider { height: 1px; background: rgba(255,255,255,0.07); margin: var(--s-2) var(--s-3); }

.sidebar-footer { padding: var(--s-3) var(--s-4); border-top: 1px solid rgba(255,255,255,0.07); font-size: var(--t-xs); }
.sidebar-footer .user-info { color: var(--grigio-500); margin-bottom: var(--s-2); }
.sidebar-footer .user-info strong { color: var(--sidebar-active); font-weight: 600; }
.btn-logout {
  background: none; border: 1px solid rgba(255,255,255,0.12); border-radius: var(--r-sm);
  color: var(--sidebar-text); padding: var(--s-2) var(--s-3); cursor: pointer;
  font-size: var(--t-xs); width: 100%; font-family: var(--font-sans);
  transition: background var(--tr-veloce), color var(--tr-veloce);
}
.btn-logout:hover { background: rgba(255,255,255,0.08); color: #fff; }

.main-content { margin-left: 200px; flex: 1; padding: var(--pad-pagina); min-height: 100vh; min-width: 0; }

/* === COMPONENTI === */
.page-header { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); margin-bottom: var(--s-5); flex-wrap: wrap; }
.page-header h1 { font-size: var(--t-xl); font-weight: 650; letter-spacing: -0.3px; }

.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: var(--s-5);
  margin-bottom: var(--s-4);
  box-shadow: var(--shadow-sm);
}
.card-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-3); margin-bottom: var(--s-4); flex-wrap: wrap;
}
.card-header h3 {
  font-size: var(--t-xs); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.6px; color: var(--text-3);
}

.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: var(--s-3); margin-bottom: var(--s-5); }
.stat-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: var(--s-4) var(--s-5);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--tr), transform var(--tr);
}
.stat-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.stat-card .stat-value { font-size: var(--t-2xl); font-weight: 700; letter-spacing: -0.5px; line-height: 1.1; }
.stat-card .stat-label { font-size: var(--t-sm); color: var(--text-2); margin-top: var(--s-1); }
.stat-card.accent .stat-value { color: var(--accent); }
.stat-card.success .stat-value { color: var(--success); }
.stat-card.warning .stat-value { color: var(--warning); }

/* --- Moduli --- */
.form-group { margin-bottom: var(--s-4); }
.form-group label {
  display: block; font-size: var(--t-xs); font-weight: 600;
  color: var(--text-2); margin-bottom: var(--s-1);
  text-transform: uppercase; letter-spacing: 0.4px;
}
.form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--s-3); }
.form-control {
  width: 100%; padding: var(--s-2) var(--s-3);
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface); color: var(--text);
  font-size: var(--t-base); font-family: var(--font-sans);
  transition: border-color var(--tr-veloce), box-shadow var(--tr-veloce);
}
.form-control::placeholder { color: var(--text-3); }
.form-control:hover:not(:disabled) { border-color: var(--border-forte); }
.form-control:focus { outline: none; border-color: var(--accent); box-shadow: var(--anello); }
.form-control:disabled { background: var(--surface-alt); color: var(--text-3); cursor: not-allowed; }
textarea.form-control { resize: vertical; min-height: 72px; line-height: 1.55; }
select.form-control { cursor: pointer; }

/* --- Pulsanti --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-4);
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface); color: var(--text);
  font-size: var(--t-base); font-weight: 600; font-family: var(--font-sans);
  cursor: pointer; white-space: nowrap;
  transition: background var(--tr-veloce), border-color var(--tr-veloce), color var(--tr-veloce), box-shadow var(--tr-veloce);
}
.btn:hover:not(:disabled) { background: var(--surface-hover); border-color: var(--border-forte); }
.btn:active:not(:disabled) { transform: translateY(0.5px); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.btn-primary { background: var(--accent); color: var(--su-accento); border-color: var(--accent); }
.btn-primary:hover:not(:disabled) { background: var(--accent-2); border-color: var(--accent-2); }
.btn-success { background: var(--success); color: #fff; border-color: var(--success); }
.btn-success:hover:not(:disabled) { filter: brightness(1.08); background: var(--success); }
/* Distruttivo: contorno e non pieno. Il pieno rosso e' del marchio, e due
   bottoni rossi affiancati — "Salva" e "Elimina" — si distinguerebbero solo
   dalla parola sopra. Qui il pieno arriva solo passandoci sopra, cioe' quando
   si sta gia' prendendo la mira. */
.btn-danger { background: transparent; color: var(--danger); border-color: var(--danger); }
.btn-danger:hover:not(:disabled) { background: var(--danger); color: #fff; border-color: var(--danger); }
.btn-secondary { background: var(--surface-alt); color: var(--text); border-color: var(--border); }
.btn-secondary:hover:not(:disabled) { background: var(--surface-hover); }
.btn-outline { background: transparent; }
.btn-sm { padding: var(--s-1) var(--s-3); font-size: var(--t-sm); }
.btn-lg { padding: var(--s-3) var(--s-5); font-size: var(--t-md); }

/* --- Tabelle --- */
.table-wrapper {
  overflow-x: auto; border: 1px solid var(--border);
  border-radius: var(--r-lg); background: var(--surface);
}
table { width: 100%; border-collapse: collapse; }
th, td { padding: var(--s-3) var(--s-4); text-align: left; border-bottom: 1px solid var(--border); font-size: var(--t-base); }
th {
  font-weight: 600; color: var(--text-2); font-size: var(--t-xs);
  text-transform: uppercase; letter-spacing: 0.5px;
  background: var(--surface-alt); position: sticky; top: 0; z-index: 1;
  white-space: nowrap;
}
tbody tr { transition: background var(--tr-veloce); }
tbody tr:hover { background: var(--surface-hover); }
tbody tr:last-child td { border-bottom: none; }
td .agent-id {
  font-family: var(--font); background: var(--code-bg);
  padding: 2px var(--s-2); border-radius: var(--r-sm);
  font-size: var(--t-xs); color: var(--text-2);
}

/* --- Etichette di stato --- */
.badge {
  display: inline-flex; align-items: center; gap: var(--s-1);
  padding: 3px var(--s-2); border-radius: var(--r-tonda);
  font-size: var(--t-xs); font-weight: 650;
  text-transform: uppercase; letter-spacing: 0.3px;
  background: var(--surface-alt); color: var(--text-2);
}
.badge::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.badge-connected { color: var(--success); background: var(--success-debole); }
.badge-disconnected { color: var(--danger); background: var(--danger-debole); }
.badge-connecting, .badge-qr_pending { color: var(--warning); background: var(--warning-debole); }
/* Un'etichetta che non e' ne' buona ne' cattiva: dice dove gira una cosa, non
   se e' rotta. Senza questa, "Server" si sarebbe letto come un allarme. */
.badge-neutro { color: var(--text-2); background: var(--surface-alt); }
.badge-connecting::before, .badge-qr_pending::before { animation: pulse 1.5s infinite; }

/* --- Finestre --- */
.modal-overlay {
  position: fixed; inset: 0; background: var(--modal-bg);
  display: flex; align-items: center; justify-content: center;
  z-index: 9500; opacity: 0; visibility: hidden;
  transition: opacity var(--tr), visibility var(--tr);
  padding: var(--s-4);
  backdrop-filter: blur(2px);
}
.modal-overlay.active { opacity: 1; visibility: visible; }
.modal {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-xl); padding: var(--s-6);
  width: 100%; max-width: 560px; max-height: 88vh; overflow-y: auto;
  box-shadow: var(--shadow-lg);
  transform: translateY(8px) scale(0.99);
  transition: transform var(--tr);
}
.modal-overlay.active .modal { transform: none; }

/* Il ripristino non e' una finestrella: e' una procedura in quattro passi, e
   ognuno vuole spazio — la tabella delle copie, l'esplora dentro la copia,
   l'esplora delle cartelle del computer. Stretta com'era, si vedevano tre
   righe per volta e si perdeva il filo di dove si era arrivati. */
.modal.larga { max-width: 860px; max-height: 92vh; }

/* La barra dei passi: dice sempre a che punto si e' e quanto manca. I passi
   gia' fatti sono cliccabili per tornare indietro senza perdere quello che si
   e' scelto; quelli davanti no — non si sceglie dove mettere qualcosa prima di
   aver detto cosa. */
.passi { display: flex; gap: var(--s-2); flex-wrap: wrap; margin-bottom: var(--s-4); }
.passo {
  display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px;
  border: 1px solid var(--border); border-radius: 999px; background: var(--surface-2);
  color: var(--text-2); font-size: var(--t-xs); white-space: nowrap;
}
.passo .n {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--border); color: var(--text-2); font-size: 11px; font-weight: 700;
}
.passo.fatto { cursor: pointer; border-color: var(--success); color: var(--text); }
.passo.fatto .n { background: var(--success); color: #fff; }
.passo.fatto:hover { background: var(--surface-hover); }
.passo.attuale { border-color: var(--accent); background: var(--surface); color: var(--text); font-weight: 600; }
.passo.attuale .n { background: var(--accent); color: #fff; }
.modal-header {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
  margin-bottom: var(--s-5); border-bottom: 1px solid var(--border); padding-bottom: var(--s-4);
}
.modal-header h3 { font-size: var(--t-lg); font-weight: 650; letter-spacing: -0.2px; }
.modal-close {
  background: none; border: none; font-size: var(--t-lg); cursor: pointer;
  color: var(--text-3); line-height: 1; padding: var(--s-1);
  border-radius: var(--r-sm); transition: color var(--tr-veloce), background var(--tr-veloce);
}
.modal-close:hover { color: var(--text); background: var(--surface-hover); }
.modal-footer { display: flex; gap: var(--s-2); justify-content: flex-end; margin-top: var(--s-5); padding-top: var(--s-4); border-top: 1px solid var(--border); }

/* --- QR --- */
.qr-container { background: #fff; padding: var(--s-4); border-radius: var(--r-lg); display: flex; align-items: center; justify-content: center; margin: var(--s-3) 0; }
.qr-image { border-radius: var(--r); }
.qr-placeholder {
  background: var(--surface-alt); border: 1px dashed var(--border-forte);
  border-radius: var(--r-lg); padding: var(--s-8) var(--s-6); text-align: center;
  color: var(--text-2); margin: var(--s-3) 0; font-size: var(--t-sm);
}

/* --- Chat con l'AI --- */
.chat-layout { display: flex; height: calc(100vh - var(--s-10) - var(--s-4)); gap: var(--s-4); }
.chat-sidebar { width: 260px; display: flex; flex-direction: column; }
.chat-sidebar .sessions-list { flex: 1; overflow-y: auto; }
.chat-session-item { padding: var(--s-3); border-radius: var(--r); cursor: pointer; transition: background var(--tr-veloce); }
.chat-session-item:hover { background: var(--surface-hover); }
.chat-session-item.active { background: var(--accent-debole); box-shadow: inset 3px 0 0 var(--accent); }
.chat-session-item .session-title { font-size: var(--t-base); font-weight: 600; }
.chat-session-item .session-meta { font-size: var(--t-xs); color: var(--text-3); margin-top: 2px; }

.chat-main { flex: 1; display: flex; flex-direction: column; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; }
.chat-messages { flex: 1; overflow-y: auto; padding: var(--s-5); display: flex; flex-direction: column; gap: var(--s-2); }
.chat-message { max-width: min(80%, 640px); padding: var(--s-3) var(--s-4); font-size: var(--t-base); line-height: 1.55; border-radius: var(--r-lg); white-space: pre-wrap; word-break: break-word; }
.chat-message.user { background: var(--accent); color: var(--su-accento); align-self: flex-end; border-bottom-right-radius: var(--r-sm); }
.chat-message.assistant { background: var(--surface-alt); color: var(--text); align-self: flex-start; border: 1px solid var(--border); border-bottom-left-radius: var(--r-sm); }
.chat-message pre { background: var(--code-bg); padding: var(--s-3); border-radius: var(--r); overflow-x: auto; margin: var(--s-2) 0; font-size: var(--t-sm); font-family: var(--font); }
.chat-message code { font-size: var(--t-sm); font-family: var(--font); }
.chat-message.user pre, .chat-message.user code { background: rgba(255,255,255,0.18); }

.chat-input-area { display: flex; gap: var(--s-2); padding: var(--s-3); border-top: 1px solid var(--border); }
.chat-input {
  flex: 1; padding: var(--s-2) var(--s-3);
  border: 1px solid var(--border); border-radius: var(--r);
  font-size: var(--t-base); font-family: var(--font-sans); resize: none;
  background: var(--bg); color: var(--text);
}
.chat-input:focus { outline: none; border-color: var(--accent); box-shadow: var(--anello); }
.chat-send {
  padding: var(--s-2) var(--s-5); background: var(--accent); color: var(--su-accento);
  border: none; border-radius: var(--r); cursor: pointer; font-weight: 600; font-size: var(--t-sm);
  transition: background var(--tr-veloce);
}
.chat-send:hover:not(:disabled) { background: var(--accent-2); }
.chat-send:disabled { opacity: 0.4; cursor: not-allowed; }
.chat-empty { display: flex; align-items: center; justify-content: center; flex: 1; color: var(--text-3); font-size: var(--t-sm); text-align: center; padding: var(--s-6); }

/* --- Schede ---
   Ce n'erano due sistemi con aspetto diverso, `.tab` e `.ctab`: qui hanno la
   stessa forma, cosi' passando da una pagina all'altra non sembra un altro
   programma. I nomi restano due perche' li usa il JS. */
.tabs, .tab-nav { display: flex; gap: var(--s-1); border-bottom: 1px solid var(--border); margin-bottom: var(--s-4); overflow-x: auto; }
.tab {
  padding: var(--s-2) var(--s-4); background: none; border: none;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  color: var(--text-2); font-size: var(--t-base); font-weight: 600;
  font-family: var(--font-sans); cursor: pointer; white-space: nowrap;
  transition: color var(--tr-veloce), border-color var(--tr-veloce);
}
.tab:hover { color: var(--text); }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }

.file-editor { font-family: var(--font); min-height: 280px; font-size: var(--t-sm); line-height: 1.65; }

/* --- Griglie ---
   `griglia-2/3/211` erano scritte a mano dentro l'attributo `style` di otto
   div: cosi' non si potevano stringere sul telefono, perche' uno stile in
   linea non lo sposta nessuna regola. Adesso sono classi, e sotto i 700 pixel
   diventano una colonna sola (vedi la sezione TELEFONO). */
.griglia-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3); }
.griglia-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--s-3); }
.griglia-211 { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: var(--s-3); }
/* Elenco a sinistra, dettaglio a destra (i cron): sul telefono uno sotto
   l'altro, con l'elenco basso quanto basta a vederne tre. */
.due-colonne { display: flex; gap: var(--s-3); min-height: 200px; }
.due-colonne-lato { width: 280px; border-right: 1px solid var(--border); overflow-y: auto; max-height: 350px; }
.due-colonne-corpo { flex: 1; padding-left: var(--s-3); min-width: 0; }

.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-4); }
.detail-grid .full-width { grid-column: 1 / -1; }
.grid { display: grid; gap: var(--s-3); }
.grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s-3); }
@media (max-width: 900px) { .detail-grid { grid-template-columns: 1fr; } }

/* --- Coda messaggi --- */
.queue-item {
  padding: var(--s-3); border: 1px solid var(--border); border-radius: var(--r);
  margin-bottom: var(--s-2); background: var(--surface);
}
.queue-detail { font-size: var(--t-sm); color: var(--text-2); }

/* --- Avvisi --- */
.toast-container { position: fixed; bottom: var(--s-5); right: var(--s-5); z-index: 9999; display: flex; flex-direction: column-reverse; gap: var(--s-2); max-width: min(420px, calc(100vw - 40px)); }
.toast {
  padding: var(--s-3) var(--s-4); color: #fff;
  font-size: var(--t-base); font-weight: 500;
  border-radius: var(--r); box-shadow: var(--shadow-lg);
  animation: slideIn 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}
.toast-success { background: var(--success); }
.toast-error { background: var(--danger); color: #fff; }
/* L'avviso informativo aveva il testo BIANCO su un grigio chiaro: 1,29:1,
   cioe' praticamente invisibile nel tema chiaro. Si usa un fondo scuro fisso,
   che funziona in tutti e due i temi — un avviso che non si legge tanto vale
   non mostrarlo. */
.toast-info { background: #2a3942; color: #fff; }
@keyframes slideIn { from { transform: translateX(40px); opacity: 0; } }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }
@keyframes spin { to { transform: rotate(360deg); } }

/* --- Menu a tendina --- */
.dropdown { position: relative; display: inline-block; }
.dropdown-toggle { cursor: pointer; }
.dropdown-menu {
  display: none; position: fixed; min-width: 180px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r); box-shadow: var(--shadow-lg);
  z-index: 9000; padding: var(--s-1); overflow: hidden;
}
.dropdown-menu.show { display: block; }
.dropdown-menu a {
  display: block; padding: var(--s-2) var(--s-3); border-radius: var(--r-sm);
  font-size: var(--t-base); color: var(--text); cursor: pointer; text-decoration: none;
}
.dropdown-menu a:hover { background: var(--surface-hover); }
.dropdown-menu a.text-danger, .dropdown-menu a.danger { color: var(--danger); }

.btn-delete-session {
  background: none; border: none; color: var(--text-3);
  font-size: var(--t-md); cursor: pointer; padding: 2px var(--s-1); line-height: 1;
  border-radius: var(--r-sm); transition: color var(--tr-veloce), background var(--tr-veloce);
}
.btn-delete-session:hover { color: var(--danger); background: var(--danger-debole); }

/* Testo di stato riusato ovunque nei template di app.js */
.ok { color: var(--success); }
.ko, .danger, .text-danger { color: var(--danger); }
.warn { color: var(--warning); }
.hint { font-size: var(--t-sm); color: var(--text-2); line-height: 1.55; }
.scope-check { accent-color: var(--accent); }

/* ============================================================
   I COMPUTER DEL CLIENTE E LA SUA RETE
   ============================================================
   Un cliente puo' avere piu' computer col bridge. Le icone dicono
   chi fa cosa senza doverlo leggere: prima si sapeva solo che
   "il bridge" era collegato, senza sapere quale ne' cosa avesse
   attaccato.
   ============================================================ */

.disp-griglia { display: block; }
.disp-griglia-interna { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--s-3); }
.disp-riepilogo { font-size: var(--t-sm); color: var(--text-2); margin-bottom: var(--s-3); }

/* Un computer acceso che il server rifiuta: non e' un dettaglio da log. */
.disp-respinto {
  border: 1px solid var(--warning); background: var(--warning-debole);
  color: var(--text); border-radius: var(--r-lg);
  padding: var(--s-3) var(--s-4); margin-bottom: var(--s-3);
  font-size: var(--t-sm); line-height: 1.55;
}
.disp-respinto code { font-family: var(--font); font-size: var(--t-xs); }
.disp-scheda {
  border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--s-4); background: var(--surface);
  display: flex; flex-direction: column; gap: var(--s-3);
}
.disp-scheda.spento { border-color: var(--danger); }
.disp-testa { display: flex; align-items: center; gap: var(--s-2); }
.disp-pallino { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; background: var(--text-3); }
.disp-pallino.acceso { background: var(--success); box-shadow: 0 0 0 3px var(--success-debole); }
/* Rosso e non grigio: un computer registrato ma non collegato e' una cosa a
   cui guardare, non un dettaglio in secondo piano. Il grigio lo faceva
   sembrare "non pertinente". */
.disp-pallino.spento { background: var(--danger); box-shadow: 0 0 0 3px var(--danger-debole); }
/* Il terzo stato: collegato, ma c'e' qualcosa da guardare — un backup fallito,
   una sessione WhatsApp che non si aggancia. Prima esistevano solo verde e
   rosso, e un computer che lavorava ma aveva un problema si confondeva con uno
   spento. */
.disp-pallino.attenzione { background: var(--warning, #b8860b); box-shadow: 0 0 0 3px var(--warning-debole, rgba(184,134,11,.18)); }
.attenzione { color: var(--warning, #b8860b); font-weight: 600; }
.disp-nome { font-weight: 650; font-size: var(--t-md); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.disp-nome-clic { cursor: pointer; text-decoration: underline dotted; text-underline-offset: 3px; }
.disp-nome-clic:hover { color: var(--accent); }
.disp-ver { font-family: var(--font); font-size: var(--t-xs); color: var(--text-3); }

/* --- La riga "Stato del computer": CPU, memoria, errori, storia --- */
/* Non un riquadro sopra tutto: una riga in piu' nella tabella, che si apre
   sotto quella del computer. bg-alt la stacca dalle righe normali senza
   sembrare un errore o un avviso. */
.diag-riga td { background: var(--bg-alt); padding: var(--s-4); border-top: none; }
.diag-riga[hidden] { display: none; }
.diag-testa { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--s-3); }
.diag-testa h4 { margin: 0; }
.diag-testa-azioni { display: flex; gap: var(--s-2); }
.diag-barra-riga { display: flex; align-items: center; gap: var(--s-2); margin-bottom: var(--s-2); }
.diag-barra-etichetta { flex: 0 0 auto; min-width: 90px; font-size: var(--t-sm); color: var(--text-2); }
.diag-barra-fondo { flex: 1; height: 10px; background: var(--bg-alt); border-radius: var(--r-tonda); overflow: hidden; }
.diag-barra-piena { height: 100%; background: var(--success); border-radius: var(--r-tonda); }
.diag-barra-piena.diag-barra-critica { background: var(--danger); }
.diag-barra-valore { flex: 0 0 auto; width: 40px; text-align: right; font-size: var(--t-sm); font-weight: 600; }

/* Il grafichetto accanto alla barra: linea sola, scala fissa 0-100, niente
   assi. La barra dice "quanto adesso", la linea dice "sta salendo o no" — sono
   due domande diverse e per questo stanno una accanto all'altra. Transizione
   morbida sulla barra perche' si aggiorna ogni tre secondi e uno scatto secco
   sembrerebbe un guasto. */
.diag-barra-piena { transition: width .35s ease, background-color .35s ease; }
.diag-spark-box { flex: 0 0 auto; width: 132px; height: 30px; line-height: 0; }
.diag-spark { width: 132px; height: 30px; display: block; overflow: visible; }
.diag-spark-linea { fill: none; stroke: var(--success); stroke-width: 1.5; vector-effect: non-scaling-stroke;
                    stroke-linejoin: round; stroke-linecap: round; }
.diag-spark-area  { fill: var(--success); opacity: .14; stroke: none; }
.diag-spark-critica .diag-spark-linea { stroke: var(--danger); }
.diag-spark-critica .diag-spark-area  { fill: var(--danger); }
.diag-spark-nota { color: var(--text-2); }

/* Sotto i 700px il grafico se ne va: in quella larghezza toglierebbe spazio
   all'etichetta e alla cifra, che sono quello che si legge davvero. */
@media (max-width: 700px) {
  .diag-spark-box { display: none; }
  .diag-spark-nota { display: none; }
}

.diag-errori, .diag-storia {
  max-height: 220px; overflow-y: auto; border: 1px solid var(--border);
  border-radius: var(--r-lg); margin-top: var(--s-2);
}
.diag-errore { padding: var(--s-2) var(--s-3); border-bottom: 1px solid var(--border); border-left: 3px solid var(--info); }
.diag-errore:last-child { border-bottom: none; }
.diag-errore-grave { border-left-color: var(--danger); }
.diag-errore-avviso { border-left-color: var(--warning, #b8860b); }
.diag-errore-testa { display: flex; justify-content: space-between; gap: var(--s-3); font-size: var(--t-sm); }
.diag-errore-dettagli { margin-top: 4px; font-size: var(--t-xs); color: var(--text-2); word-break: break-word; }
.diag-storia-riga {
  display: flex; justify-content: space-between; gap: var(--s-3);
  padding: var(--s-2) var(--s-3); border-bottom: 1px solid var(--border); font-size: var(--t-sm);
}
.diag-storia-riga:last-child { border-bottom: none; }

.disp-icone { display: flex; gap: var(--s-2); }
.disp-cap {
  width: 30px; height: 30px; border-radius: var(--r);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--t-md); background: var(--surface-alt); border: 1px solid var(--border);
}
/* Due cose diverse devono sembrare diverse: un'icona che dice soltanto "ce
   l'ha" (rete, stampanti) e' piatta e senza cornice; una su cui si clicca
   (schermo, terminale, file) e' un tasto vero, con bordo, ombra e mano. */
.disp-cap.si { background: transparent; border-color: transparent; opacity: 0.6; }
.disp-cap.si.attiva {
  opacity: 1; background: var(--success-debole); border: 1px solid var(--success);
  box-shadow: 0 1px 2px rgba(11, 20, 26, 0.12), inset 0 -2px 0 rgba(0, 0, 0, 0.06);
}
/* Il menu piccolo sotto un'icona (PowerShell o prompt dei comandi). */
.menu-rapido {
  position: fixed; z-index: 9700; min-width: 200px; padding: 4px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg); display: flex; flex-direction: column;
}
.menu-rapido button {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  background: transparent; border: 0; color: var(--text); text-align: left;
  padding: 8px 12px; border-radius: var(--r); cursor: pointer; font: inherit; font-size: var(--t-sm);
}
.menu-rapido button:hover, .menu-rapido button:focus { background: var(--surface-alt); outline: none; }
.menu-rapido button small { color: var(--text-2); font-size: var(--t-xs); }
/* Un'icona su cui si puo' cliccare deve sembrarlo prima del clic, non dopo:
   il cursore a mano da solo si scopre solo passandoci sopra per caso. */
button.disp-cap { font: inherit; cursor: pointer; padding: 0; }
.disp-cap.attiva:hover { transform: translateY(-1px); filter: brightness(1.05); box-shadow: 0 3px 8px rgba(11, 20, 26, 0.18); }
.disp-cap.attiva:active { transform: none; }
.disp-cap.attiva:focus-visible { outline: 2px solid var(--success); outline-offset: 1px; }
/* Assente e "non lo sappiamo" non sono la stessa cosa e non devono sembrarlo:
   un bridge vecchio non dichiara le proprie capacita', non e' che non le abbia. */
.disp-cap.no { opacity: 0.28; filter: grayscale(1); }
.disp-cap.ignota { opacity: 0.45; filter: grayscale(1); border-style: dashed; }

.disp-righe { font-size: var(--t-sm); color: var(--text-2); display: flex; flex-direction: column; gap: 2px; }
/* Barra di ricerca e filtri sopra una tabella. Una sola, usata dai computer e
   dai clienti: due tabelle che si cercano nello stesso modo devono anche
   somigliarsi, o ogni elenco diventa un posto nuovo da imparare. */
.barra-filtri { display: flex; gap: var(--s-2); align-items: center; flex-wrap: wrap; margin-bottom: var(--s-3); }
.barra-filtri .form-control { width: auto; }
.barra-filtri .campo-cerca { flex: 1; min-width: 200px; }
.barra-filtri .conteggio { font-size: var(--t-xs); color: var(--text-3); white-space: nowrap; margin-left: auto; }
.disp-sotto { font-size: var(--t-xs); color: var(--text-3); margin-top: 2px; }
/* La riga di sintesi di un'esecuzione di backup. Il messaggio d'errore di
   kopia per un server con file aperti e' arrivato a 249.452 caratteri: senza
   questo tetto la colonna si allargava fino a mandare la pagina fuori schermo,
   e lo storico si scorreva solo in orizzontale. Il testo intero sta sotto
   "vedi dettaglio". */
.riga-sintesi { max-width: 44ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.link-dettaglio {
  background: none; border: 0; padding: 0; margin-top: 2px;
  font-family: inherit; font-size: var(--t-xs); color: var(--accent);
  text-decoration: underline; cursor: pointer;
}
.link-dettaglio:hover { color: var(--accent-2); }
/* Il log per intero dentro la modale: a scorrere e' lui, non la finestra, se
   no il pulsante "Chiudi" finisce a migliaia di righe di distanza. */
.testo-integrale {
  max-height: 55vh; overflow: auto;
  background: var(--code-bg); border: 1px solid var(--border);
  border-radius: var(--r); padding: var(--s-3);
}
.testo-integrale pre {
  margin: 0; white-space: pre-wrap; overflow-wrap: anywhere;
  font-family: var(--font); font-size: var(--t-xs); color: var(--text-2);
}
/* Un allarme sulla riga della macchina: si deve vedere scorrendo la tabella,
   senza doverlo leggere. */
.disp-allarme { font-size: var(--t-xs); margin-top: 3px; padding: 2px 6px; border-radius: 4px;
  background: var(--warning-debole); color: var(--warning); display: inline-block; }
.disp-allarme.grave { background: var(--danger-debole); color: var(--danger); }
/* Nella tabella le celle sono strette: le azioni non devono andare a capo
   una per riga. */
.disp-azioni .btn-sm { white-space: nowrap; }

/* Il ripristino: si sfoglia dentro una copia come dentro una cartella, ogni
   riga ha la sua casella di spunta, e quella scelta resta evidente — nel
   giorno in cui si ripristina non ci si puo' permettere di non essere sicuri
   di cosa si sta riportando indietro. Una riga "coperta" (dentro una cartella
   gia' spuntata piu' sopra) si vede spenta: e' gia' presa, non si spunta da
   sola, e la scritta accanto dice perche' invece di lasciarlo indovinare. */
/* L'elenco delle copie e' una TABELLA e non una tendina: su un server con
   piu' dischi ce n'e' una per disco per notte, e prima di scegliere da dove
   riprendere qualcosa si guardano quale disco, quanto pesa e quanti file non
   sono stati letti. Dentro un menu a tendina si vede una riga per volta e non
   si confrontano. */
.rip-copie { max-height: 190px; overflow-y: auto; border: 1px solid var(--border); border-radius: var(--r-lg); }
.rip-tabella { width: 100%; border-collapse: collapse; font-size: var(--t-xs); }
.rip-tabella th, .rip-tabella td { padding: var(--s-2) var(--s-3); text-align: left; white-space: nowrap; }
.rip-tabella th { position: sticky; top: 0; background: var(--surface-2); color: var(--text-2); font-weight: 600; z-index: 1; }
.rip-tabella td.num, .rip-tabella th.num { text-align: right; font-variant-numeric: tabular-nums; }
.rip-copia-riga { cursor: pointer; border-top: 1px solid var(--border); }
.rip-copia-riga:hover { background: var(--surface-hover); }
.rip-copia-riga.scelta { background: var(--success-debole); }
.rip-copia-riga.scelta td:first-child { box-shadow: inset 3px 0 0 var(--success); }

.rip-percorso { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin-bottom: var(--s-2); font-size: var(--t-xs); }
.rip-lista { max-height: 260px; overflow-y: auto; border: 1px solid var(--border); border-radius: var(--r-lg); }
.rip-riga {
  display: flex; align-items: center; gap: var(--s-2); justify-content: space-between;
  padding: var(--s-2) var(--s-3); border-bottom: 1px solid var(--border);
}
.rip-riga:last-child { border-bottom: none; }
.rip-riga:hover { background: var(--surface-hover); }
.rip-riga.scelta { background: var(--success-debole); border-left: 3px solid var(--success); }
.rip-riga.coperta { opacity: 0.6; }
.rip-spunta { display: flex; align-items: center; gap: var(--s-2); cursor: pointer; min-width: 0; flex: 1; }
.rip-spunta span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Il riepilogo di quanto e' scelto: sempre visibile, dal passo "cosa" al
   passo "dove", con la possibilita' di togliere una voce senza tornare a
   scovarla nella lista — vedi ripRidisegnaSelezionati() in app.js. */
.rip-selezionati { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; }
.rip-selezionato {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--success-debole); border: 1px solid var(--success);
  border-radius: var(--r-sm); padding: 2px 6px; font-size: var(--t-xs);
}
.rip-selezionato button { background: none; border: none; cursor: pointer; color: var(--text-2); font-size: var(--t-base); line-height: 1; }

/* Il selettore delle cartelle. Sta sopra la modale del piano (z-index 9600
   contro 9500) perche' quella deve restare dov'e' con quello che ci hai gia'
   scritto dentro. */
.sfoglia-finestra { width: min(720px, 96vw); height: min(560px, 88vh); }
/* La riga per scrivere un percorso a mano (un NAS non ancora raggiungibile
   non compare cliccando: va scritto) — vedi carica() in sfogliaCartelle(). */
.sfoglia-vai { display: flex; gap: var(--s-2); padding: 0 var(--s-4) var(--s-3); flex-shrink: 0; }
.sfoglia-vai input { flex: 1; }
.sfoglia-corpo { flex: 1; min-height: 0; overflow-y: auto; background: var(--surface); }
.sfoglia-riga {
  display: flex; align-items: center; gap: var(--s-3); justify-content: space-between;
  padding: var(--s-2) var(--s-4); border-bottom: 1px solid var(--border);
}
.sfoglia-riga:hover { background: var(--surface-hover); }
.sfoglia-riga.coperta { opacity: 0.6; }
.sfoglia-spunta { display: flex; align-items: center; gap: var(--s-2); cursor: pointer; min-width: 0; }
.sfoglia-spunta span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sfoglia-piede {
  border-top: 1px solid var(--border); padding: var(--s-3) var(--s-4);
  background: var(--surface-alt); display: flex; gap: var(--s-3);
  align-items: center; justify-content: space-between; flex-wrap: wrap;
}
.sfoglia-scelte { display: flex; gap: var(--s-2); flex-wrap: wrap; flex: 1; min-width: 0; }
.sfoglia-scelta {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--success-debole); border: 1px solid var(--success);
  border-radius: var(--r-sm); padding: 2px 6px; font-size: var(--t-xs);
}
.sfoglia-scelta button { background: none; border: none; cursor: pointer; color: var(--text-2); font-size: var(--t-base); line-height: 1; }
.sfoglia-azioni { display: flex; gap: var(--s-2); flex-shrink: 0; }

/* Il grafico dei backup: una barra per esecuzione, la piu' alta al 100%.
   Quella "principale" (il primo backup di un computer+destinazione) si vede
   diversa dalle altre — vedi il commento su renderBackupGrafico() in
   app.js sul perche' l'altezza da sola non basta a dire cos'e' incrementale. */
.backup-grafico-barre {
  display: flex; align-items: flex-end; gap: 2px; height: 110px;
  padding: var(--s-3); margin-bottom: var(--s-2);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface-alt); overflow-x: auto;
}
/* `backup-grafico-barra`, NON `backup-barra`: quel nome lo usa anche la
   barra di avanzamento di un backup in corso (piu' sotto), che veniva dopo
   nel foglio e vinceva: tutte le barre del grafico prendevano il suo grigio,
   e restavano colorate solo quelle fallite. "Non c'e' niente di verde"
   (Corvezzo, 12/09/2026). */
.backup-grafico-barra {
  flex: 1 0 4px; min-width: 4px; max-width: 22px; min-height: 3px;
  background: var(--accent); border-radius: 2px 2px 0 0;
}
.backup-grafico-barra.principale { background: var(--warning); }
.backup-grafico-barra.errore { background: var(--danger); }
.backup-grafico-legenda {
  display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center;
  margin-bottom: var(--s-3); font-size: var(--t-xs); color: var(--text-2);
}
.backup-legenda-pallino {
  display: inline-block; width: 9px; height: 9px; border-radius: 2px;
  background: var(--accent); margin-right: 4px; vertical-align: middle;
}
.backup-legenda-pallino.principale { background: var(--warning); }
.backup-legenda-pallino.errore { background: var(--danger); }

/* I giorni dei backup: una casella per giorno per computer, colorata da
   com'e' FINITO il giorno (services/backup-giorni.js). E' la prima cosa
   della scheda perche' risponde alla prima domanda: sta funzionando? */
.backup-giorni {
  padding: var(--s-3); margin-bottom: var(--s-2);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface-alt);
}
.backup-giorni-riga { display: flex; align-items: center; gap: var(--s-3); margin-bottom: 4px; }
.backup-giorni-nome {
  flex: 0 0 150px; font-size: var(--t-xs); color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.backup-giorni-celle { display: flex; gap: 3px; overflow-x: auto; }
.backup-giorno {
  display: inline-block; flex: 0 0 14px; width: 14px; height: 14px;
  border-radius: 3px; background: var(--border);
}
.backup-giorno.ok { background: var(--success); }
.backup-giorno.parziale { background: var(--warning); }
.backup-giorno.errore { background: var(--danger); }
.backup-giorno.in_corso { background: var(--text-2); }
.backup-grafico-legenda .backup-giorno { width: 10px; height: 10px; flex-basis: 10px; margin-right: 4px; vertical-align: middle; }
@media (max-width: 700px) { .backup-giorni-nome { flex-basis: 90px; } }

/* Il cruscotto della scheda Stato: pochi numeri grandi, e sotto solo i
   problemi veri. Se non c'e' niente che non va, non c'e' niente da leggere. */
.cruscotto { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--s-3); }
.cruscotto-tessera {
  border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--s-3) var(--s-4); background: var(--surface-alt);
}
.cruscotto-tessera.ok { border-color: var(--success); background: var(--success-debole); }
.cruscotto-tessera.ko { border-color: var(--danger); background: var(--danger-debole); }
.cruscotto-tessera.attenzione { border-color: var(--warning, #b8860b); }
.cruscotto-valore { font-size: var(--t-xl); font-weight: 700; line-height: 1.2; }
.cruscotto-su { font-size: var(--t-sm); font-weight: 500; color: var(--text-2); }
.cruscotto-etichetta { font-size: var(--t-xs); text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-2); margin-top: 2px; }
.cruscotto-nota { font-size: var(--t-xs); color: var(--text-3); margin-top: var(--s-1); }
button.cruscotto-tessera { font: inherit; text-align: left; width: 100%; }
.cruscotto-tessera.apribile { cursor: pointer; transition: transform var(--tr-veloce), box-shadow var(--tr-veloce); }
.cruscotto-tessera.apribile:hover { transform: translateY(-1px); box-shadow: var(--shadow-lg); }
.cruscotto-elenco {
  margin-top: var(--s-4); padding: var(--s-3) var(--s-4);
  border: 1px solid var(--border); border-radius: var(--r-lg); background: var(--surface-alt);
}
.cruscotto-elenco.evidenzia { animation: evidenziaProblemi 1.4s ease; }
@keyframes evidenziaProblemi {
  0%   { border-color: var(--danger); box-shadow: 0 0 0 4px var(--danger-debole); }
  100% { border-color: var(--border); box-shadow: none; }
}
/* I pacchetti che il cliente ha, in chiaro nel cruscotto: la domanda "cosa gli
   abbiamo venduto" e' la prima che ci si fa aprendo un cliente, e la risposta
   non deve stare dietro un pulsante. */
.moduli-riga { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; margin-top: var(--s-4); }
.modulo-pastiglia {
  font-size: var(--t-xs); padding: 3px 10px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface-alt); color: var(--text-2);
}
.modulo-pastiglia.attivo { border-color: var(--success); background: var(--success-debole); color: var(--text); font-weight: 600; }
.modulo-pastiglia.spento { opacity: 0.45; text-decoration: line-through; }

.cruscotto-problemi { margin: var(--s-2) 0 0; padding-left: var(--s-5); font-size: var(--t-sm); color: var(--text-2); }
.cruscotto-problemi li { margin-bottom: var(--s-1); }
.disp-os { font-family: var(--font); font-size: var(--t-xs); color: var(--text-3); }
.disp-azioni { display: flex; gap: var(--s-2); align-items: center; flex-wrap: wrap; margin-top: auto; }
.disp-ruolo {
  font-size: var(--t-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px;
  color: var(--accent); background: var(--accent-debole);
  padding: var(--s-1) var(--s-2); border-radius: var(--r-tonda);
}

/* --- Rete del cliente --- */
.rete-griglia { display: flex; flex-direction: column; gap: var(--s-1); }
.rete-riga {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface);
}
.rete-riga.assente { opacity: 0.6; }
.rete-icona {
  width: 34px; height: 34px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--t-lg); background: var(--surface-alt); border-radius: var(--r);
}
.rete-corpo { flex: 1; min-width: 0; }
.rete-nome { font-weight: 600; font-size: var(--t-base); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rete-sotto { font-size: var(--t-xs); color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rete-rete { text-align: right; flex-shrink: 0; }
.rete-ip { font-family: var(--font); font-size: var(--t-sm); }
.rete-mac { font-family: var(--font); font-size: var(--t-xs); color: var(--text-3); }
.rete-stato {
  flex-shrink: 0; font-size: var(--t-xs); font-weight: 600;
  padding: var(--s-1) var(--s-2); border-radius: var(--r-tonda);
  background: var(--surface-alt); color: var(--text-3);
}
.rete-stato.vivo { background: var(--success-debole); color: var(--success); }

@media (max-width: 700px) {
  .rete-rete { display: none; }
}

/* ============================================================
   ACCESSO "SOLO CONVERSAZIONI"
   ============================================================
   Un utente del negozio con il solo permesso WhatsApp non deve
   vedere un gestionale con dentro una chat: deve vedere una
   finestra di messaggistica e basta. Via il menu, l'intestazione
   del cliente, le schede e tutte le altre carte.

   Si nasconde per struttura, non elencando gli id da spegnere:
   una carta aggiunta domani sarebbe invisibile per difetto invece
   di comparire a sorpresa a chi non deve vederla.
   ============================================================ */

body.solo-conversazioni .sidebar,
body.solo-conversazioni .client-hero,
body.solo-conversazioni #client-tabs,
body.solo-conversazioni .page-header,
body.solo-conversazioni #page-dashboard,
body.solo-conversazioni #page-clients,
body.solo-conversazioni #page-chat,
body.solo-conversazioni #page-users,
body.solo-conversazioni #page-automations,
body.solo-conversazioni #page-antispam { display: none !important; }

/* Dentro il dettaglio cliente resta in piedi solo la scheda delle
   conversazioni, e dentro quella solo la sua carta. */
body.solo-conversazioni .ctab-panel:not(#ctab-conversazioni) { display: none !important; }
body.solo-conversazioni #ctab-conversazioni > .card:not(#section-whatsapp) { display: none !important; }
/* Il cassetto della riparazione e' fuori da #page-client-detail (e' globale,
   vedi piu' sotto ".rip-drawer-tab"): senza questa riga un amministratore in
   modalita' solo-conversazioni lo vedrebbe comunque spuntare sul bordo,
   proprio quello che questa modalita' vuole evitare. */
body.solo-conversazioni .rip-drawer-tab,
body.solo-conversazioni .rip-drawer { display: none !important; }

/* `.app-layout` e' un flex in riga: la barra, inserita come fratello del
   contenuto, finiva come colonna a sinistra e rubava larghezza invece di
   stare sopra. In questa modalita' l'impaginazione torna a blocchi. */
body.solo-conversazioni .app-layout { display: block; }
body.solo-conversazioni .main-content { margin-left: 0; padding: 0; min-height: 0; }
body.solo-conversazioni #page-client-detail { display: block !important; }
body.solo-conversazioni #section-whatsapp { margin: 0; border: none; border-radius: 0; box-shadow: none; }
body.solo-conversazioni .wa-webchat { height: calc(100vh - 46px); border: none; border-radius: 0; }

/* Una barra sottile con il nome del negozio e l'uscita: senza, non si
   capisce a nome di chi si sta scrivendo e non si sa come uscire. */
/* ACCESSO CLIENTE (utente con ruolo client, non "solo conversazioni").
   Tutto nascosto PER DIFETTO: si vede solo quello che applyPermissions() ha
   segnato con .cliente-visibile, cioe' le schede e i riquadri dei permessi
   dati. Una scheda aggiunta domani al pannello nasce invisibile al cliente. */
body.accesso-cliente .page:not(#page-client-detail),
body.accesso-cliente .sidebar-nav,
body.accesso-cliente .campana,
body.accesso-cliente .rip-drawer-tab,
body.accesso-cliente .rip-drawer,
body.accesso-cliente .client-hero-top > .btn,
body.accesso-cliente .client-hero-agent,
body.accesso-cliente .client-hero-state,
body.accesso-cliente #client-tabs .ctab:not(.cliente-visibile),
body.accesso-cliente .ctab-panel > :not(.cliente-visibile) { display: none !important; }

.pc-cliente { display: flex; gap: var(--s-3); align-items: center; justify-content: space-between;
  flex-wrap: wrap; padding: var(--s-2) 0; border-top: 1px solid var(--border); }
.pc-cliente-nome { display: flex; gap: var(--s-2); align-items: center; }

.sc-barra { display: none; }
body.solo-conversazioni .sc-barra {
  display: flex; align-items: center; gap: var(--s-3);
  height: 46px; padding: 0 var(--s-4);
  background: var(--sidebar-bg); color: #fff;
}
.sc-barra img { height: 22px; width: auto; }
.sc-nome { font-weight: 600; font-size: var(--t-base); flex: 1; min-width: 0;
           overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sc-utente { font-size: var(--t-xs); color: var(--grigio-500); }
.sc-esci {
  background: transparent; border: 1px solid rgba(255,255,255,0.18); color: #fff;
  border-radius: var(--r-sm); padding: var(--s-1) var(--s-3);
  font-size: var(--t-xs); cursor: pointer; font-family: var(--font-sans);
}
.sc-esci:hover { background: rgba(255,255,255,0.1); }

/* --- Terminale SSH e desktop remoto --- */
.rete-ssh, .rete-desktop {
  flex-shrink: 0; margin-left: var(--s-2);
  border: 1px solid var(--accent); color: var(--accent); background: transparent;
  border-radius: var(--r-sm); padding: var(--s-1) var(--s-3);
  font-size: var(--t-xs); font-weight: 700; cursor: pointer; font-family: var(--font-sans);
  transition: background var(--tr-veloce), color var(--tr-veloce);
}
.rete-ssh:hover, .rete-desktop:hover { background: var(--accent); color: var(--su-accento); }

.ssh-overlay {
  position: fixed; inset: 0; z-index: 9600; overscroll-behavior: contain;
  background: var(--modal-bg); backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center; padding: var(--s-4);
}
/* Una finestra aperta sopra un'altra (i file sopra il desktop remoto): niente
   sfocatura, che sopra una tela che cambia venti volte al secondo costa un
   ricalcolo a ogni fotogramma e rallenta tutto. */
.ssh-overlay.sopra { backdrop-filter: none; background: rgba(0, 0, 0, 0.45); }
/* Il desktop remoto: niente sfocatura del fondo. Vedi apriFinestraDesktop. */
.ssh-overlay.desk-overlay { backdrop-filter: none; background: rgba(0, 0, 0, 0.72); }
.ssh-finestra {
  position: relative;
  width: min(1000px, 96vw); height: min(680px, 92vh);
  display: flex; flex-direction: column;
  background: #0b141a; border: 1px solid var(--border-forte);
  border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-lg);
}
.ssh-barra {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-2) var(--s-4); background: var(--grigio-800); color: #e9edef;
  flex-shrink: 0;
}
.ssh-titolo { font-family: var(--font); font-size: var(--t-sm); font-weight: 600; flex: 1; min-width: 0;
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ssh-stato { font-size: var(--t-xs); color: var(--grigio-500); }
.ssh-chiudi { background: transparent; border: none; color: #e9edef; font-size: var(--t-xl);
              line-height: 1; cursor: pointer; padding: 0 var(--s-1); }
.ssh-chiudi:hover { color: var(--danger); }
.ssh-term { flex: 1; min-height: 0; padding: var(--s-2); background: #0b141a; }
.ssh-term .xterm { height: 100%; }

/* Il desktop remoto riusa la finestra del terminale: cambia solo il contenuto,
   che qui e' la tela disegnata da guacamole-common-js. Centrata, su fondo nero:
   quando il desktop e' piu' piccolo dell'area restano bande, non uno stiramento. */
.desk-schermo {
  flex: 1; min-height: 0; overflow: hidden; background: #000;
  display: flex; align-items: center; justify-content: center;
}
.desk-schermo:focus { outline: none; }
.desk-errore { color: var(--danger); font-size: var(--t-sm); padding: var(--s-4); text-align: center; }

/* Comandi nella barra: schermo intero e tastiera del telefono. */
.desk-btn {
  background: transparent; border: 1px solid #3b4a54; color: #e9edef;
  border-radius: var(--r-sm); padding: 2px 8px; font-size: var(--t-base);
  line-height: 1.4; cursor: pointer; flex-shrink: 0;
}
.desk-btn:hover { border-color: #e9edef; }

/* ---- La barra del desktop remoto ----
   A sinistra chi si sta guardando e come va (pallino, nome, statistiche),
   a destra i comandi. Sfondo piu' scuro della barra del terminale, cosi' la
   tela e' la cosa piu' chiara sullo schermo. Niente <select> native: i menu
   sono nostri, dentro la finestra, e funzionano anche a schermo intero. */
.desk-barra {
  gap: var(--s-3); padding: var(--s-2) var(--s-3);
  background: #111b21; border-bottom: 1px solid #233138;
}
.desk-barra-sx { display: flex; align-items: center; gap: var(--s-2); flex: 1; min-width: 0; }
.desk-barra-dx { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.desk-titolo { flex: 0 1 auto; }
.desk-pallino {
  width: 8px; height: 8px; border-radius: 50%; background: #8696a0; flex-shrink: 0;
  transition: background var(--tr-veloce), box-shadow var(--tr-veloce);
}
.desk-pallino.acceso { background: var(--wa-400); box-shadow: 0 0 0 3px rgba(37, 211, 102, 0.18); }
.desk-pallino.spento { background: #8696a0; }
.desk-pallino.errore { background: var(--danger); box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.18); }
.desk-stat {
  font-family: var(--font); font-size: var(--t-xs); color: #8696a0;
  background: #202c33; border-radius: 999px; padding: 2px 10px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.desk-barra .desk-btn {
  height: 30px; min-width: 30px; padding: 0 10px;
  display: inline-flex; align-items: center; gap: 6px;
  background: #202c33; border: 1px solid transparent; color: #e9edef;
  border-radius: 8px; font-size: var(--t-sm); line-height: 1; cursor: pointer; flex-shrink: 0;
  transition: background var(--tr-veloce), border-color var(--tr-veloce);
}
.desk-barra .desk-btn:hover { background: #2a3942; border-color: #3b4a54; }
.desk-barra .desk-btn.attivo { background: var(--wa-800); border-color: var(--wa-700); }
.desk-barra .desk-btn-icona { padding: 0; width: 30px; justify-content: center; font-size: var(--t-base); }
.desk-barra .ssh-chiudi { margin-left: var(--s-1); }
.desk-freccia { font-style: normal; font-size: 10px; opacity: 0.7; }
.desk-menu-wrap { position: relative; }
.desk-menu {
  position: absolute; right: 0; top: calc(100% + 6px); min-width: 280px; max-width: min(360px, 90vw);
  background: #202c33; border: 1px solid #3b4a54; border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45); padding: 6px; z-index: 5;
}
.desk-menu-titolo {
  font-size: var(--t-xs); color: #8696a0; text-transform: uppercase; letter-spacing: 0.04em;
  padding: 4px 10px 6px;
}
.desk-menu-voce {
  display: flex; flex-direction: column; gap: 2px; width: 100%; text-align: left;
  background: transparent; border: 0; color: #e9edef; padding: 8px 10px;
  border-radius: 8px; cursor: pointer; font: inherit; font-size: var(--t-sm);
}
.desk-menu-voce:hover, .desk-menu-voce:focus { background: #2a3942; outline: none; }
.desk-menu-voce.scelta { background: var(--wa-800); }
.desk-menu-voce small { color: #8696a0; font-size: var(--t-xs); line-height: 1.3; }
.desk-barra .desk-btn:disabled { opacity: 0.4; cursor: default; }

/* ---- Sola visione e controllo ----
   La sessione si apre guardando soltanto, quindi lo stato deve leggersi senza
   cercarlo: qui il colore e l'etichetta nella barra, e sopra la tela il
   cartellino .desk-visione, che e' dove il tecnico ha gli occhi. */
.desk-barra .desk-btn.desk-controllo.sola-visione { border-color: var(--wa-700); color: var(--wa-400); }
.desk-barra .desk-btn.desk-controllo.attivo { background: var(--wa-700); border-color: var(--wa-400); color: #fff; }
/* Le due regole qui sopra vincono per specificita' anche sul :hover comune:
   il ritorno al passaggio del mouse va rimesso, o il comando piu' importante
   della barra e' l'unico che sembra morto. */
.desk-barra .desk-btn.desk-controllo:hover { filter: brightness(1.2); }
/* Un clic o un tasto mentre si guarda soltanto non fa niente sul computer di
   la': il pulsante lampeggia, cosi' la risposta al "perche' non succede
   niente" sta dov'e' anche il rimedio. */
.desk-barra .desk-btn.desk-lampeggia { animation: desk-lampeggio 0.85s ease-out 2; }
@keyframes desk-lampeggio {
  0%, 100% { box-shadow: 0 0 0 0 rgba(37, 211, 102, 0); }
  35% { box-shadow: 0 0 0 4px rgba(37, 211, 102, 0.5); }
}
.desk-visione[hidden] { display: none; }
/* Sbiadisce da solo dopo qualche secondo per non coprire il desktop che si sta
   guardando, e torna pieno passandoci sopra col mouse. */
.desk-visione {
  position: absolute; top: 52px; left: 50%; transform: translateX(-50%); z-index: 5;
  max-width: min(560px, 92%);
  background: rgba(17, 27, 33, 0.94); color: #e9edef;
  border: 1px solid var(--wa-700); border-radius: 999px;
  padding: 7px 16px; font: inherit; font-size: var(--t-xs); line-height: 1.3;
  cursor: pointer; text-align: center;
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.45);
  animation: desk-visione-sbiadisce 1.2s ease-out 6s forwards;
}
.desk-visione:hover, .desk-visione:focus { animation: none; outline: none; border-color: var(--wa-400); }
.desk-visione b { color: var(--wa-400); }
@keyframes desk-visione-sbiadisce { to { opacity: 0.35; } }

/* Un file trascinato sopra lo schermo remoto (finisce sul suo Desktop) o
   sulla finestra dei file (finisce nella cartella aperta). */
/* `hidden` da solo non basta: la regola display:flex qui sotto lo
   vincerebbe, e la zona resterebbe sempre a schermo — sopra la tela del
   desktop, che cosi' ridisegnava anche lei a ogni fotogramma. */
.desk-drop[hidden], .file-coda[hidden], .desk-menu-wrap[hidden] { display: none; }
.desk-drop {
  position: absolute; inset: 0; z-index: 4; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 168, 132, 0.16); outline: 3px dashed var(--wa-400); outline-offset: -8px;
}
/* Trascinare un file mentre si guarda soltanto: il verde prometterebbe che il
   file parte, e invece resta dov'e' finche' non si prende il controllo.
   Il giallo e' scritto qui e non preso da --yellow: la finestra del desktop e'
   scura in tutti e due i temi, e sul tema chiaro quella variabile e' un ambra
   scuro che su questo fondo non si vedrebbe. */
.desk-drop.vietata { background: rgba(0, 0, 0, 0.45); outline-color: #e0a33c; }
/* Le schede dei file in caricamento sullo schermo remoto: in basso a destra,
   stondate, con la barra. Non prendono il mouse: sotto c'e' il desktop. */
.desk-carichi {
  position: absolute; right: 14px; bottom: 14px; z-index: 6; width: min(300px, 80%);
  display: flex; flex-direction: column; gap: 8px; pointer-events: none;
}
.desk-carico {
  background: rgba(32, 44, 51, 0.96); color: #e9edef; border-radius: 14px; padding: 10px 12px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45); font-size: var(--t-xs);
  transition: opacity 0.4s, transform 0.4s;
}
.desk-carico.attesa { opacity: 0.75; }
.desk-carico.via { opacity: 0; transform: translateY(8px); }
.desk-carico-testa { display: flex; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.desk-carico-nome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.desk-carico-perc { color: #8696a0; flex-shrink: 0; }
.desk-carico-barra { height: 8px; border-radius: 999px; background: #111b21; overflow: hidden; }
.desk-carico-barra i { display: block; height: 100%; border-radius: 999px; background: var(--wa-400); transition: width 0.15s; }
.desk-carico.errore .desk-carico-barra i { background: var(--danger); }
.desk-carico.fatto .desk-carico-perc { color: var(--wa-400); }
.desk-carico.errore .desk-carico-perc, .desk-carico.errore .desk-carico-nota { color: var(--danger); }
.desk-carico-nota { color: #8696a0; margin-top: 5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* La scheda che avvisa "il cliente ha copiato dei file": non ha una barra di
   avanzamento — non sta succedendo niente — ma un pulsante, perche' portarseli
   qui e' una scelta del tecnico e non un travaso automatico. */
.desk-carico.appunti { background: rgba(0, 92, 75, 0.96); }
.desk-carico-chiudi {
  background: none; border: 0; color: #8696a0; font-size: var(--t-md);
  line-height: 1; cursor: pointer; padding: 0 2px; flex-shrink: 0;
}
.desk-carico-chiudi:hover { color: #e9edef; }

/* ---- Attivita' in background ----
   I trasferimenti di file vivono FUORI dalle finestre: chiuso il gestore file
   il lavoro continua, e qui si vede. In basso a sinistra (a destra ci sono gli
   avvisi), sopra le finestre a tutto schermo (9600) e sotto i menu (9700).
   Schede uguali a quelle del desktop remoto. Vedi App.vassoioTrasferimenti. */
.trasf-vassoio {
  position: fixed; left: 16px; bottom: 16px; z-index: 9650;
  width: min(340px, calc(100vw - 32px));
  display: flex; flex-direction: column; gap: 8px;
}
.trasf-vassoio[hidden] { display: none; }
.trasf-lista {
  display: flex; flex-direction: column; gap: 8px;
  max-height: min(50vh, 420px); overflow-y: auto; overscroll-behavior: contain;
}
.trasf-vassoio.chiuso .trasf-lista { display: none; }
.trasf-testa {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: #111b21; color: #e9edef; border: 1px solid #233138; border-radius: 999px;
  padding: 8px 14px; font: inherit; font-size: var(--t-sm); cursor: pointer; text-align: left;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45); min-height: 40px;
}
.trasf-testa:hover { background: #1f2c33; }
.trasf-titolo { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trasf-freccia { color: #8696a0; transition: transform 0.2s; }
.trasf-vassoio.chiuso .trasf-freccia { transform: rotate(180deg); }
.trasf-spia { width: 10px; height: 10px; border-radius: 50%; background: var(--wa-400); flex-shrink: 0; }
.trasf-vassoio.attivo .trasf-spia { animation: trasf-pulsa 1.2s ease-in-out infinite; }
.trasf-vassoio.con-errori .trasf-spia { background: var(--danger); }
@keyframes trasf-pulsa { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
@media (prefers-reduced-motion: reduce) { .trasf-vassoio.attivo .trasf-spia { animation: none; } }
.desk-carico-azioni { margin-top: 8px; }
.desk-carico-prendi { width: 100%; justify-content: center; }
.desk-carico-prendi:disabled { opacity: 0.6; cursor: default; }
.desk-drop-testo {
  background: #111b21; color: #e9edef; padding: 14px 22px; border-radius: 12px;
  font-size: var(--t-base); box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
}

/* ---- La finestra dei file ----
   Stessa cornice scura del desktop e del terminale: sono i tre attrezzi con
   cui si entra nel computer del cliente. Briciole in alto, elenco al centro,
   i caricamenti in corso in fondo. */
.file-finestra { width: min(900px, 96vw); height: min(640px, 92vh); }
.file-percorso {
  display: flex; align-items: center; gap: 2px; flex-wrap: wrap;
  padding: 6px 12px; background: #111b21; border-bottom: 1px solid #233138;
  font-size: var(--t-sm); color: #8696a0; flex-shrink: 0;
}
.file-briciola {
  background: transparent; border: 0; color: #e9edef; padding: 2px 6px;
  border-radius: 6px; font: inherit; font-size: var(--t-sm);
}
button.file-briciola { cursor: pointer; }
button.file-briciola:hover { background: #2a3942; }
.file-briciola.attuale { font-weight: 600; }
.file-sep { color: #8696a0; padding: 0 2px; }
.file-corpo { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; background: #0b141a; }
.file-lista { flex: 1; min-height: 0; overflow: auto; padding: 6px; overscroll-behavior: contain; }
.file-lista.attesa { opacity: 0.5; }
.file-riga {
  display: grid; grid-template-columns: 28px minmax(0, 1fr) 90px 120px 24px; align-items: center; gap: 8px;
  width: 100%; text-align: left; background: transparent; border: 0; color: #e9edef;
  padding: 7px 10px; border-radius: 8px; cursor: pointer; font: inherit; font-size: var(--t-sm);
}
.file-riga:hover, .file-riga:focus { background: #202c33; outline: none; }
.file-icona { text-align: center; }
.file-nome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-misura, .file-data { color: #8696a0; font-size: var(--t-xs); text-align: right; white-space: nowrap; }
.file-azione { color: #8696a0; text-align: center; }
.file-riga.file:hover .file-azione { color: var(--wa-400); }
.file-vuota { color: #8696a0; padding: var(--s-4); text-align: center; font-size: var(--t-sm); }
.file-vuota.errore { color: var(--danger); }
.file-coda {
  flex-shrink: 0; max-height: 160px; overflow: auto; background: #111b21; border-top: 1px solid #233138;
  padding: 6px 10px; display: flex; flex-direction: column; gap: 4px;
}
.file-trasf {
  display: grid; grid-template-columns: minmax(0, 1fr) 70px 160px minmax(0, 1fr); gap: 8px; align-items: center;
  font-size: var(--t-xs); color: #e9edef;
}
.file-trasf-nome, .file-trasf-esito { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-trasf-misura { color: #8696a0; text-align: right; }
.file-trasf-barra { height: 6px; background: #233138; border-radius: 999px; overflow: hidden; }
.file-trasf-barra i { display: block; height: 100%; background: var(--wa-400); transition: width 0.2s; }
.file-trasf-esito { color: #8696a0; }
.file-trasf.errore .file-trasf-barra i { background: var(--danger); }
.file-trasf.errore .file-trasf-esito { color: var(--danger); }
@media (max-width: 700px) {
  .file-riga { grid-template-columns: 28px minmax(0, 1fr) 70px 24px; }
  .file-data { display: none; }
  .file-trasf { grid-template-columns: minmax(0, 1fr) 100px; }
  .file-trasf-misura, .file-trasf-esito { display: none; }
}
/* Il desktop remoto si apre grande quasi quanto la finestra del browser: a
   1000 pixel un 1080p si vedeva al 52%, e il bridge lo mandava gia' ridotto
   perche' il tetto e' la finestra. */
.ssh-finestra.desk-finestra { width: 96vw; height: 94vh; max-width: none; }
/* A schermo intero la finestra E' lo schermo: via cornice e angoli.
   Questa regola sta DOPO quella del desktop remoto, e lo nomina: `:fullscreen`
   e' una pseudo-classe, quindi `.ssh-finestra:fullscreen` pesa quanto
   `.ssh-finestra.desk-finestra` e, stando prima, perdeva. Era il motivo per
   cui a schermo intero restava una cornice del 4% e la tela si ridimensionava
   due volte. */
.ssh-finestra:fullscreen,
.ssh-finestra.desk-finestra:fullscreen {
  width: 100vw; height: 100vh; max-width: none; border: 0; border-radius: 0;
}
/* La tela del protocollo diretto (schermo.js): il contenitore ha esattamente
   la misura della tela scalata, cosi' il mouse si legge dal contenitore. */
.schermo-diretto { position: relative; line-height: 0; flex-shrink: 0; }
.schermo-diretto canvas { display: block; }
/* Zoom 100%: lo schermo resta grande com'e' e l'area scorre. */
.desk-schermo.uno-a-uno { display: block; overflow: auto; }
/* La casella nascosta che tiene il fuoco dentro la finestra del desktop.
   Non si nasconde con display:none ne' si porta fuori schermo con left:-9999px:
   deve poter ricevere il fuoco (e con esso l'evento `paste`, che i browser
   mandano solo dove si puo' scrivere) senza far scorrere la pagina. Sta sopra
   la tela ma e' trasparente e non intercetta il puntatore. */
.desk-casella {
  position: absolute; top: 0; left: 0; width: 1px; height: 1px;
  opacity: 0; border: 0; padding: 0; margin: 0; resize: none;
  pointer-events: none; z-index: 1;
}

/* Da telefono e tablet la finestra prende tutto: su 6 pollici una cornice con
   i bordi arrotondati e' spazio tolto al desktop che si sta guardando. */
@media (max-width: 860px), (pointer: coarse) {
  .ssh-overlay { padding: 0; }
  /* Anche il desktop remoto, che ha una regola sua piu' pesante: su sei
     pollici il 96% dello schermo lascia una cornice e basta. */
  .ssh-finestra,
  .ssh-finestra.desk-finestra {
    width: 100vw; height: 100vh; height: 100dvh;
    max-width: none; border: 0; border-radius: 0;
  }
  .ssh-barra { padding: var(--s-2); gap: var(--s-2); }
  .ssh-titolo { font-size: var(--t-xs); }
  .ssh-stato { display: none; }
  .desk-barra { flex-wrap: wrap; gap: var(--s-2); }
  .desk-barra-sx { flex-basis: 100%; }
  .desk-stat { display: none; }
  .desk-barra .desk-btn span { display: none; }
  .desk-barra .desk-btn { padding: 0 8px; }
  /* Tranne questo: e' l'unico comando il cui stato non si puo' indovinare
     dall'icona, e sapere se si sta comandando o guardando conta piu' di due
     centimetri di barra. */
  .desk-barra .desk-btn.desk-controllo span { display: inline; }
  .desk-menu { right: auto; left: 0; }
  .desk-visione { top: 84px; font-size: 11px; padding: 6px 12px; }
}

/* --- Mini chat --- */
.mini-chat { display: flex; flex-direction: column; height: 320px; }
.mini-chat .chat-messages { flex: 1; overflow-y: auto; padding: var(--s-3); display: flex; flex-direction: column; gap: var(--s-2); background: var(--bg); border: 1px solid var(--border); border-radius: var(--r); margin-bottom: var(--s-2); }
.mini-chat .chat-message { max-width: 85%; font-size: var(--t-sm); padding: var(--s-2) var(--s-3); }
.mini-chat .chat-input-area { display: flex; gap: var(--s-2); padding: 0; border-top: none; }
.mini-chat .chat-input { flex: 1; padding: var(--s-2) var(--s-3); font-size: var(--t-sm); }
.mini-chat .chat-send { padding: var(--s-2) var(--s-4); font-size: var(--t-sm); }

/* WhatsApp WebChat */
/* ============================================================
   CONVERSAZIONI WHATSAPP
   ============================================================
   Deve reggere il confronto con WhatsApp Web, quindi occupa
   l'altezza disponibile invece dei 380px fissi di prima: una
   finestra di messaggistica alta un terzo di schermo si scorre
   in continuazione e non la usa nessuno.
   ============================================================ */

.wa-webchat {
  display: flex;
  height: calc(100vh - 210px);
  min-height: 460px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface);
}

/* --- Colonna delle conversazioni --- */
.wa-chat-list {
  width: 320px;
  flex-shrink: 0;
  border-right: 1px solid var(--border);
  overflow-y: auto;
  background: var(--surface);
  display: flex;
  flex-direction: column;
}
.wa-lista-testa {
  position: sticky; top: 0; z-index: 2;
  padding: var(--s-3);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  display: flex; gap: var(--s-2); align-items: center;
}
.wa-cerca {
  flex: 1; min-width: 0;
  border: 1px solid var(--border); border-radius: var(--r-tonda);
  background: var(--bg); color: var(--text);
  padding: var(--s-2) var(--s-3);
  font-family: var(--font-sans); font-size: var(--t-sm);
}
.wa-cerca::placeholder { color: var(--text-3); }
.wa-nuova {
  flex-shrink: 0; width: 32px; height: 32px;
  border: none; border-radius: var(--r-tonda);
  background: var(--accent); color: var(--su-accento);
  font-size: var(--t-md); line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background var(--tr-veloce);
}
.wa-nuova:hover { background: var(--accent-2); }

.wa-chat-item {
  padding: var(--s-3);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  display: flex; align-items: center; gap: var(--s-3);
  transition: background var(--tr-veloce);
}
.wa-chat-item:hover { background: var(--surface-hover); }
.wa-chat-item.active { background: var(--accent-debole); }
/* La conversazione aperta si riconosce da una barra sul bordo, non solo dal
   fondo colorato: sul tema scuro la differenza di fondo da sola non si vede. */
.wa-chat-item.active { box-shadow: inset 3px 0 0 var(--accent); }

.wa-chat-avatar {
  width: 42px; height: 42px; border-radius: var(--r-tonda);
  background: var(--grigio-300); color: var(--grigio-700);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--t-sm); font-weight: 700; flex-shrink: 0;
  font-family: var(--font-sans);
}
.wa-chat-avatar.gruppo { background: var(--info-debole); color: var(--info); }
.wa-chat-info { flex: 1; min-width: 0; }
.wa-chat-riga { display: flex; align-items: baseline; gap: var(--s-2); }
.wa-chat-name {
  font-size: var(--t-base); font-weight: 600; flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wa-chat-time { font-size: var(--t-xs); color: var(--text-3); flex-shrink: 0; }
.wa-chat-sotto { display: flex; align-items: center; gap: var(--s-2); margin-top: 2px; }
.wa-chat-last {
  font-size: var(--t-sm); color: var(--text-2); flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wa-chat-item.non-letta .wa-chat-name { font-weight: 700; }
.wa-chat-item.non-letta .wa-chat-last { color: var(--text); font-weight: 500; }
.wa-badge-nonletti {
  flex-shrink: 0; min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: var(--r-tonda); background: var(--nonletti); color: var(--su-nonletti);
  font-size: var(--t-xs); font-weight: 700; line-height: 20px; text-align: center;
}

/* --- Pannello dei messaggi --- */
.wa-chat-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.wa-chat-header {
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  display: flex; align-items: center; gap: var(--s-3);
  min-height: 60px;
}
.wa-chat-header .wa-chat-avatar { width: 36px; height: 36px; }
.wa-testa-nome { font-weight: 600; font-size: var(--t-md); }
.wa-testa-sotto { font-size: var(--t-xs); color: var(--text-3); }

.wa-messages {
  flex: 1; overflow-y: auto;
  padding: var(--s-4);
  display: flex; flex-direction: column; gap: var(--s-1);
  background: var(--chat-sfondo);
  scroll-behavior: smooth;
}
.wa-giorno {
  align-self: center;
  margin: var(--s-3) 0 var(--s-2);
  padding: var(--s-1) var(--s-3);
  border-radius: var(--r-tonda);
  background: var(--surface); border: 1px solid var(--border);
  font-size: var(--t-xs); color: var(--text-2); font-weight: 600;
}
.wa-carica-altri { align-self: center; margin-bottom: var(--s-2); }

.wa-msg {
  max-width: min(78%, 620px);
  padding: var(--s-2) var(--s-3);
  font-size: var(--t-base); line-height: 1.45;
  border-radius: var(--r-lg);
  word-break: break-word; white-space: pre-wrap;
  box-shadow: var(--shadow-sm);
}
.wa-msg.incoming {
  background: var(--bolla-entrata); color: var(--su-bolla-entrata);
  align-self: flex-start; border-bottom-left-radius: var(--r-sm);
}
/* Verde chiaro con testo scuro, come su WhatsApp: il bianco su verde pieno
   che c'era prima faceva 3:1 di contrasto, cioe' faticoso da leggere per
   chi passa la giornata su questa pagina. */
.wa-msg.outgoing {
  background: var(--bolla-uscita); color: var(--su-bolla-uscita);
  align-self: flex-end; border-bottom-right-radius: var(--r-sm);
}
/* Messaggi consecutivi della stessa parte: si stringono, cosi' si legge un
   blocco invece di una scala di bolle staccate. */
.wa-msg.seguito.incoming { border-top-left-radius: var(--r-sm); }
.wa-msg.seguito.outgoing { border-top-right-radius: var(--r-sm); }

.wa-msg-sender {
  font-size: var(--t-xs); font-weight: 700; color: var(--accent);
  margin-bottom: 2px;
}
.wa-msg.outgoing .wa-msg-sender { color: var(--accent-2); }
.wa-msg-piede {
  display: flex; align-items: center; justify-content: flex-end; gap: 4px;
  font-size: var(--t-xs); opacity: 0.7; margin-top: 2px;
}
.wa-msg.in-invio { opacity: 0.6; }
.wa-msg.fallito { background: var(--danger-debole); color: var(--danger); border: 1px solid var(--danger); }

.wa-media { max-width: 100%; border-radius: var(--r); display: block; }
.wa-media-fallback {
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-3); border-radius: var(--r);
  background: var(--surface-alt); border: 1px solid var(--border);
  color: var(--text); text-decoration: none; font-size: var(--t-sm);
}
.wa-msg.outgoing .wa-media-fallback { background: rgba(0,0,0,0.06); border-color: rgba(0,0,0,0.12); color: inherit; }

/* --- Citazione e azioni sul messaggio --- */
.wa-msg { position: relative; }
.wa-azioni {
  position: absolute; top: 2px; right: 2px;
  width: 22px; height: 22px; border: none; border-radius: var(--r-sm);
  background: transparent; color: inherit; opacity: 0;
  cursor: pointer; font-size: var(--t-base); line-height: 1;
  transition: opacity var(--tr-veloce), background var(--tr-veloce);
}
.wa-msg:hover .wa-azioni, .wa-azioni:focus-visible { opacity: 0.75; background: rgba(0,0,0,0.08); }
.wa-azioni:hover { opacity: 1; }

/* Il messaggio citato, dentro la bolla */
.wa-citato {
  border-left: 3px solid var(--accent-vivo);
  background: rgba(0,0,0,0.05);
  border-radius: var(--r-sm);
  padding: var(--s-2) var(--s-3);
  margin-bottom: var(--s-2);
  font-size: var(--t-sm); color: inherit; opacity: 0.85;
  max-height: 84px; overflow: hidden;
}
.wa-citato-chi { display: block; font-weight: 700; font-size: var(--t-xs); color: var(--accent); margin-bottom: 2px; }

/* La barra sopra la casella, quando si sta rispondendo a qualcosa */
.wa-cita-barra {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-2) var(--s-4);
  border-top: 1px solid var(--border);
  background: var(--surface-alt);
}
.wa-cita-barra[hidden] { display: none; }
.wa-cita-corpo { flex: 1; min-width: 0; border-left: 3px solid var(--accent-vivo); padding-left: var(--s-3); }
.wa-cita-eti { display: block; font-size: var(--t-xs); font-weight: 700; color: var(--accent); }
.wa-cita-testo { display: block; font-size: var(--t-sm); color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wa-cita-x {
  flex-shrink: 0; border: none; background: transparent; color: var(--text-3);
  font-size: var(--t-lg); cursor: pointer; line-height: 1; padding: var(--s-1);
  border-radius: var(--r-sm);
}
.wa-cita-x:hover { color: var(--text); background: var(--surface-hover); }

/* --- Barra di scrittura --- */
.wa-scrivi {
  display: flex; align-items: flex-end; gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  border-top: 1px solid var(--border); background: var(--surface);
}
.wa-scrivi textarea {
  flex: 1; resize: none; max-height: 140px;
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--bg); color: var(--text);
  padding: var(--s-3); font-family: var(--font-sans); font-size: var(--t-base);
  line-height: 1.45;
}
.wa-scrivi textarea:disabled { background: var(--surface-alt); cursor: not-allowed; }
.wa-invia {
  flex-shrink: 0; width: 40px; height: 40px;
  border: none; border-radius: var(--r-tonda);
  background: var(--accent); color: var(--su-accento);
  cursor: pointer; font-size: var(--t-md);
  display: flex; align-items: center; justify-content: center;
  transition: background var(--tr-veloce), opacity var(--tr-veloce);
}
.wa-invia:hover:not(:disabled) { background: var(--accent-2); }
.wa-invia:disabled { opacity: 0.4; cursor: not-allowed; }

.wa-vuoto {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--s-3);
  color: var(--text-3); font-size: var(--t-sm); text-align: center; padding: var(--s-8);
}
.wa-vuoto .wa-vuoto-icona { font-size: 40px; opacity: 0.5; }

/* Su schermo stretto le due colonne non ci stanno: si mostra una alla volta,
   come sul telefono. */
@media (max-width: 860px) {
  .wa-webchat { height: calc(100dvh - 190px); }
  .wa-chat-list { width: 100%; }
  .wa-webchat.chat-aperta .wa-chat-list { display: none; }
  .wa-webchat:not(.chat-aperta) .wa-chat-main { display: none; }
  .wa-indietro { display: inline-flex !important; }
}
.wa-indietro { display: none; }
/* Spinner */
.spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.5s linear infinite; }

/* Responsive
   Il menu ridotto a una colonna di sole icone non c'e' piu': sette icone senza
   parole non le riconosceva nessuno, e 48 pixel di larghezza restavano tolti al
   contenuto per sempre. Sotto gli 820 pixel il menu e' un cassetto che si apre
   dalla barra in alto (vedi la sezione TELEFONO in fondo al foglio). */
@media (max-width: 768px) {
  /* La colonna delle conversazioni non ci sta di fianco, ma nasconderla
     — com'era prima — vuol dire che dal telefono non si puo' piu' ne'
     cambiare conversazione ne' aprirne una. Diventa una striscia sopra la
     chat, che si scorre col dito. */
  .chat-layout { flex-direction: column; height: calc(100dvh - 150px); gap: var(--s-2); }
  .chat-sidebar { width: 100%; flex: 0 0 auto; }
  .chat-sidebar .sessions-list {
    display: flex; gap: var(--s-2); overflow-x: auto; overflow-y: hidden;
    padding: var(--s-2); scrollbar-width: none;
  }
  .chat-sidebar .sessions-list::-webkit-scrollbar { display: none; }
  .chat-session-item {
    flex: 0 0 auto; max-width: 62vw; border: 1px solid var(--border);
    border-radius: var(--r-tonda); padding: var(--s-2) var(--s-3);
  }
  .chat-session-item.active { box-shadow: none; border-color: var(--accent); }
  .chat-session-item .session-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .chat-session-item .session-meta { display: none; }
  .chat-main { min-height: 0; }
}

/* ============================================================
   DETTAGLIO CLIENTE — intestazione e schede
   La pagina aveva dieci sezioni una sotto l'altra: per arrivare
   alla coda messaggi si scorreva oltre tutta l'anagrafica e la
   configurazione dell'autoresponder. Ora sono schede, e i due
   indicatori che contano (WhatsApp, bridge) restano sempre in
   alto, visibili da qualunque scheda.
   Classi .ctab* e non .tab*: quelle esistono gia' e le usa
   l'editor dei file di configurazione.
   ============================================================ */

.client-hero {
  position: sticky; top: 0; z-index: 20;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  margin: calc(var(--pad-pagina) * -1) calc(var(--pad-pagina) * -1) 16px;
  padding: 16px var(--pad-pagina) 0;
}
.client-hero-top { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 12px; }
.client-hero-id { display: flex; align-items: baseline; gap: 10px; min-width: 0; flex: 1; }
.client-hero-id h1 { font-size: 19px; font-weight: 650; letter-spacing: -0.2px; margin: 0; }
.client-hero-agent {
  font-family: var(--font); font-size: 11px; color: var(--text-3);
  background: var(--bg-alt); border: 1px solid var(--border); border-radius: 5px;
  padding: 2px 7px; white-space: nowrap;
}
.client-hero-state { display: flex; gap: 8px; flex-wrap: wrap; }
.hero-chip {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 999px;
  padding: 4px 10px 4px 12px;
}
.hero-chip-k { font-size: 11px; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.4px; }

.ctabs { display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none; }
.ctabs::-webkit-scrollbar { display: none; }
.ctabs .ctab {
  border: 0; background: transparent; color: var(--text-2);
  font: inherit; font-size: 13px; font-weight: 600; white-space: nowrap;
  padding: 9px 14px; cursor: pointer;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color 0.15s, border-color 0.15s;
}
.ctabs .ctab:hover { color: var(--text); }
.ctabs .ctab.active { color: var(--accent); border-bottom-color: var(--accent); }
.ctabs .ctab:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; border-radius: 4px; }

.ctab-panel[hidden] { display: none; }
.ctab-panel { display: grid; gap: 14px; align-content: start; }
/* Stato e Coda stanno comode affiancate sugli schermi larghi */
@media (min-width: 1280px) {
  #ctab-stato { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  #ctab-coda { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
  #ctab-anagrafica { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
}
.ctab-panel > .card { margin-bottom: 0; min-width: 0; }

/* Il riquadro della versione nuova del bridge, dentro la card del bridge */
#bridge-nuovo {
  display: flex; gap: 10px; align-items: flex-start;
  margin-top: 12px; padding: 10px 12px;
  border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: 8px; background: var(--bg-alt); font-size: 12px; line-height: 1.5;
}
#bridge-nuovo a { color: var(--accent); font-weight: 600; white-space: nowrap; }
.pill-nuovo {
  flex: 0 0 auto; font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.5px; color: var(--yellow);
  border: 1px solid var(--yellow); border-radius: 999px; padding: 1px 7px;
}

/* --- Assistenza: la tabella delle sessioni su telefono --- */
@media (max-width: 700px) {
  #page-assistenza .table-wrapper { overflow-x: auto; }
  #page-assistenza .form-group { max-width: none !important; }
  #page-assistenza .card > div { flex-direction: column; align-items: stretch; }
}

/* ============================================================
   RIPARAZIONE ASSISTITA
   ============================================================
   La chat dove un tecnico fa diagnosticare un computer di un
   cliente. Tre generi di riquadro, e si devono distinguere a
   colpo d'occhio perche' dicono cose diverse:

     .rip-bolla   chi ha parlato (tecnico o assistente)
     .rip-cmd     cosa e' stato eseguito davvero sulla macchina
     .rip-prop    cosa aspetta un clic per partire

   Il cartellino di una proposta e' l'unico con un pulsante ed e'
   l'unico bordato di giallo: e' il punto in cui una persona si
   assume una modifica su un computer che sta lavorando.
   ============================================================ */

.rip-intro { margin-bottom: var(--s-3); line-height: 1.55; }
.rip-guasto { color: var(--danger); }
.rip-avviso { margin-top: var(--s-2); }

/* --- Apertura della sessione --- */
.rip-apri { display: flex; gap: var(--s-3); align-items: flex-end; flex-wrap: wrap; }
.rip-campo { display: flex; flex-direction: column; gap: var(--s-1); min-width: 200px; }
.rip-campo-largo { flex: 1; min-width: 260px; }
.rip-campo > span { font-size: var(--t-sm); color: var(--text-2); font-weight: 600; }

/* --- Sessione aperta --- */
.rip-stato {
  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--border); border-left: 3px solid var(--accent-vivo);
  border-radius: var(--r); background: var(--bg-alt);
}
.rip-stato-corpo { flex: 1; min-width: 220px; }
.rip-stato-titolo { font-size: var(--t-base); }
.rip-stato-sotto { font-size: var(--t-sm); color: var(--text-2); margin-top: 2px; }
.rip-pallino {
  width: 9px; height: 9px; border-radius: var(--r-tonda);
  background: var(--accent-vivo); flex: 0 0 auto;
}

/* --- La conversazione --- */
.rip-card { padding: 0; overflow: hidden; }
.rip-messaggi {
  display: flex; flex-direction: column; gap: var(--s-3);
  padding: var(--s-4); min-height: 320px; max-height: 62vh; overflow-y: auto;
  background: var(--bg-alt);
}
.rip-vuoto {
  margin: auto; max-width: 420px; text-align: center;
  color: var(--text-2); font-size: var(--t-base); line-height: 1.6;
}

.rip-bolla {
  max-width: min(85%, 720px); padding: var(--s-3) var(--s-4);
  font-size: var(--t-base); line-height: 1.55;
  border-radius: var(--r-lg); white-space: pre-wrap; word-break: break-word;
}
.rip-bolla-tecnico {
  align-self: flex-end; background: var(--bolla-uscita); color: var(--su-bolla-uscita);
}
.rip-bolla-ai {
  align-self: flex-start; background: var(--bolla-entrata); color: var(--su-bolla-entrata);
  border: 1px solid var(--border);
}
.rip-bolla pre {
  background: var(--code-bg); padding: var(--s-2) var(--s-3); border-radius: var(--r);
  margin: var(--s-2) 0; overflow-x: auto; font-size: var(--t-sm); font-family: var(--font);
}
.rip-bolla code { font-family: var(--font); font-size: var(--t-sm); }

/* Dentro un riquadro di codice le righe NON si spezzano: scorrono.
   La bolla che lo contiene ha `word-break: break-word`, che si eredita e
   spaccherebbe a meta' un percorso o una riga di registro nel punto sbagliato,
   rendendola illeggibile proprio quando la si sta leggendo. Con `pre` +
   `overflow-x: auto` la riga resta intera e si scorre di lato. */
.rip-bolla pre, .chat-message pre {
  white-space: pre; word-break: normal; overflow-wrap: normal; overflow-x: auto;
}
.rip-bolla pre code, .chat-message pre code { white-space: inherit; }

/* Le righe che mette a verbale il pannello: non le ha scritte nessuno. */
.rip-verbale {
  align-self: center; max-width: min(90%, 760px);
  font-size: var(--t-sm); color: var(--text-2); line-height: 1.5;
  padding: var(--s-2) var(--s-3); border: 1px dashed var(--border-forte);
  border-radius: var(--r); background: transparent; white-space: pre-wrap; word-break: break-word;
}

/* --- Un comando eseguito sulla macchina --- */
.rip-cmd {
  align-self: stretch; border: 1px solid var(--border); border-left: 3px solid var(--info);
  border-radius: var(--r); background: var(--surface); overflow: hidden;
}
.rip-cmd-male { border-left-color: var(--danger); }
.rip-cmd-testa {
  display: flex; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap;
  padding: var(--s-2) var(--s-3); border-bottom: 1px solid var(--border);
  font-size: var(--t-xs); color: var(--text-2);
}
.rip-cmd-chi { font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px; }
.rip-cmd-comando {
  margin: 0; padding: var(--s-2) var(--s-3);
  font-family: var(--font); font-size: var(--t-sm); color: var(--accent);
  white-space: pre-wrap; word-break: break-all;
}
.rip-cmd-uscita {
  margin: 0; padding: var(--s-2) var(--s-3); border-top: 1px solid var(--border);
  background: var(--code-bg); font-family: var(--font); font-size: var(--t-sm);
  line-height: 1.45; max-height: 260px; overflow: auto; white-space: pre;
}
.rip-cmd-nota, .rip-cmd-errore {
  padding: var(--s-2) var(--s-3); font-size: var(--t-sm); border-top: 1px solid var(--border);
}
.rip-cmd-nota { color: var(--text-3); }
.rip-cmd-errore { color: var(--danger); }

/* --- Una proposta che aspetta il clic --- */
.rip-prop {
  align-self: stretch; padding: var(--s-3) var(--s-4);
  border: 1px solid var(--warning); border-left: 3px solid var(--warning);
  border-radius: var(--r); background: var(--warning-debole);
}
.rip-prop-fatta { border-color: var(--border); border-left-color: var(--text-3); background: var(--surface); }
.rip-prop-testa {
  display: flex; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap;
  margin-bottom: var(--s-2);
}
.rip-prop-eti {
  font-size: var(--t-xs); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.4px; color: var(--warning);
}
.rip-prop-fatta .rip-prop-eti { color: var(--text-3); }
.rip-prop-gia { font-size: var(--t-xs); color: var(--text-2); }
.rip-prop-cosa { font-size: var(--t-md); line-height: 1.5; }
.rip-prop-perche { font-size: var(--t-base); color: var(--text-2); line-height: 1.5; margin-top: var(--s-1); }
.rip-prop-comando {
  margin: var(--s-3) 0; padding: var(--s-2) var(--s-3);
  background: var(--code-bg); border-radius: var(--r);
  font-family: var(--font); font-size: var(--t-sm);
  white-space: pre-wrap; word-break: break-all;
}
.rip-prop-azioni { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.rip-prop-nota { font-size: var(--t-sm); color: var(--text-2); }
.rip-avviso-storto {
  align-self: stretch; padding: var(--s-2) var(--s-3);
  border: 1px dashed var(--warning); border-radius: var(--r);
  font-size: var(--t-sm); color: var(--warning); line-height: 1.5;
}

/* --- L'attesa: decine di secondi non sono un blocco, ma lo sembrano --- */
.rip-attesa {
  align-self: flex-start; display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-2) var(--s-4); border: 1px solid var(--border);
  border-radius: var(--r-lg); background: var(--bolla-entrata);
}
.rip-attesa-testo { font-size: var(--t-sm); color: var(--text-2); }

/* --- Dove si scrive --- */
/* Sopra la casella di scrittura: il modello AI della sessione e i tasti delle
   procedure pronte (controllo sicurezza, PC lento...). Vedi ripDisegnaStrumenti. */
.rip-strumenti {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-3); border-top: 1px solid var(--border); background: var(--surface);
}
.rip-strumenti[hidden] { display: none; }
.rip-modello { display: flex; align-items: center; gap: var(--s-2); font-size: var(--t-sm); color: var(--text-2); }
.rip-modello select { width: auto; min-width: 0; max-width: 100%; padding: 4px 8px; font-size: var(--t-sm); }
.rip-procedure { display: flex; flex-wrap: wrap; gap: 6px; }
.rip-procedura { white-space: nowrap; }

/* Il Markdown delle risposte dell'AI (formatMarkdown). La bolla ha
   white-space: pre-wrap per i messaggi semplici; qui i blocchi sono gia'
   separati dall'HTML, e gli a capo in piu' diventerebbero righe vuote. */
.rip-bolla.md { white-space: normal; }
.md > :first-child { margin-top: 0; }
.md > :last-child { margin-bottom: 0; }
.md p { margin: 0 0 var(--s-2); }
.md .md-titolo { margin: var(--s-3) 0 var(--s-2); font-size: var(--t-md); font-weight: 700; line-height: 1.3; }
.md h5.md-titolo, .md h6.md-titolo { font-size: var(--t-base); }
.md ul, .md ol { margin: 0 0 var(--s-2); padding-left: 1.4em; }
.md li { margin: 2px 0; }
.md hr { border: 0; border-top: 1px solid var(--border); margin: var(--s-3) 0; }
.md blockquote { margin: 0 0 var(--s-2); padding: 2px var(--s-3); border-left: 3px solid var(--border-forte); color: var(--text-2); }
.md a { color: var(--accent); text-decoration: underline; }
.md code { background: var(--code-bg); padding: 1px 5px; border-radius: 4px; }
.md pre code { background: none; padding: 0; }
.md-tabella { overflow-x: auto; margin: 0 0 var(--s-2); }
.md table { border-collapse: collapse; width: 100%; font-size: var(--t-sm); }
.md th, .md td { border: 1px solid var(--border); padding: 5px 8px; text-align: left; vertical-align: top; }
.md th { background: var(--bg-alt); font-weight: 600; }
.md td { word-break: normal; overflow-wrap: anywhere; }

.rip-scrivi {
  display: flex; gap: var(--s-2); align-items: flex-end;
  padding: var(--s-3); border-top: 1px solid var(--border); background: var(--surface);
}
.rip-input {
  flex: 1; resize: vertical; min-height: 46px;
  padding: var(--s-2) var(--s-3); font: inherit; font-size: var(--t-base);
  color: var(--text); background: var(--surface);
  border: 1px solid var(--border-forte); border-radius: var(--r);
}
.rip-input:focus { outline: none; border-color: var(--accent); box-shadow: var(--anello); }
.rip-input:disabled { background: var(--bg-alt); color: var(--text-3); }
.rip-invia { align-self: stretch; }

/* --- Il cassetto globale (non piu' una scheda del cliente) --- */
:root {
  /* Una sola misura, letta sia dal cassetto (la sua larghezza) sia dal resto
     della pagina (di quanto si restringe quando il cassetto e' aperto):
     tenerle in un posto solo evita che finiscano per divergere. */
  --rip-larg: min(420px, 92vw);
}
@media (max-width: 820px) {
  :root { --rip-larg: min(340px, 85vw); }
}

.rip-drawer-tab {
  /* In basso a destra, non a meta' altezza: e' dove ci si aspetta un
     pulsante di assistenza, e non copre il centro dello schermo mentre si
     lavora su una tabella larga. Piu' in alto dei toast (che stanno nello
     stesso angolo, var(--s-5) dal bordo) cosi' non ci si sovrappongono. */
  position: fixed; bottom: 96px; right: 0;
  z-index: 9300; display: flex; align-items: center; gap: 6px;
  background: var(--accent); color: #fff; border: none;
  padding: 10px 14px; border-radius: var(--r-lg) 0 0 var(--r-lg);
  box-shadow: var(--shadow-lg); cursor: pointer;
  font: inherit; font-size: var(--t-sm); font-weight: 700;
}
.rip-drawer-tab:hover { background: var(--accent-vivo); }
.rip-drawer-tab-icona { font-size: var(--t-md); }

.rip-drawer {
  /* Sempre una colonna, mai un pieno schermo: chi la apre deve poter
     continuare a vedere e toccare il resto del pannello sotto/accanto,
     su un computer come su un telefono — e' il motivo per cui esiste come
     cassetto invece che come pagina a se'. */
  position: fixed; top: 0; right: 0; bottom: 0; width: var(--rip-larg);
  background: var(--surface); border-left: 1px solid var(--border);
  box-shadow: var(--shadow-lg); z-index: 9400;
  display: flex; flex-direction: column;
}
/* Non sopra al resto: ACCANTO. Sopra gli 820px (dove il menu resta sempre in
   vista, .main-content e' gia' flex:1/min-width:0) si restringe la pagina
   della stessa misura del cassetto invece di lasciarglielo coprire — "a
   scapito della pagina", come chiesto. Sotto gli 820px il telefono e' gia'
   troppo stretto per starci affiancati: li' resta un cassetto sopra, non
   accanto, o la pagina sotto diventerebbe uno spazio inutile di pochi pixel. */
@media (min-width: 821px) {
  body.rip-drawer-aperto .main-content {
    margin-right: var(--rip-larg);
    transition: margin-right var(--tr);
  }
}
.rip-drawer[hidden] { display: none; }

.rip-drawer-testa {
  display: flex; align-items: flex-end; gap: var(--s-2);
  padding: var(--s-3); border-bottom: 1px solid var(--border);
  background: var(--bg-alt); flex: 0 0 auto;
}
.rip-drawer-cliente { flex: 1; min-width: 0; }
.rip-drawer-chiudi {
  background: none; border: none; font-size: 26px; line-height: 1; cursor: pointer;
  color: var(--text-2); padding: 0 2px; flex: 0 0 auto;
}
.rip-drawer-chiudi:hover { color: var(--text); }

.rip-drawer-corpo {
  flex: 1; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--s-3);
  padding: var(--s-3);
}
.rip-drawer-vuoto { margin: auto; text-align: center; }
#rip-drawer-attivo[hidden] { display: none; }
.rip-drawer .rip-card { border: 1px solid var(--border); border-radius: var(--r-lg); }
/* Nel cassetto stretto il tetto della vecchia scheda (62vh di una pagina
   intera) e' troppo: qui la conversazione condivide lo spazio col resto. */
.rip-drawer .rip-messaggi { min-height: 180px; max-height: 46vh; }

.rip-memoria {
  /* --success-debole/--success sono gia' quelli giusti per tema: chiaro
     tenue in chiaro, verde translucido su fondo scuro in scuro. --wa-50 no —
     resta lo stesso verde pallido in entrambi i temi, che col testo chiaro
     del tema scuro si legge a stento. */
  background: var(--success-debole); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: var(--s-3); font-size: var(--t-sm);
  line-height: 1.5; color: var(--text);
}
.rip-memoria-titolo { font-weight: 700; color: var(--success); margin-bottom: 4px; }
.rip-memoria-testo { white-space: pre-wrap; color: var(--text); }
.rip-memoria-quando { font-size: var(--t-xs); color: var(--text-3); margin-top: var(--s-2); }

/* --- La cronologia: le sessioni chiuse di un computer --- */
.rip-cronologia {
  border: 1px solid var(--border); border-radius: var(--r-lg);
  overflow: hidden; background: var(--surface);
}
.rip-cronologia-titolo {
  padding: var(--s-2) var(--s-3); font-size: var(--t-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.4px; color: var(--text-2);
  background: var(--bg-alt); border-bottom: 1px solid var(--border);
}
.rip-cronologia-riga {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-2);
  padding: var(--s-2) var(--s-3); border-bottom: 1px solid var(--border);
}
.rip-cronologia-riga:last-child { border-bottom: none; }
.rip-cronologia-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rip-cronologia-quando { font-size: var(--t-xs); color: var(--text-3); }
.rip-cronologia-motivo { font-size: var(--t-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rip-cronologia-azioni { display: flex; gap: var(--s-1); flex: 0 0 auto; }
.rip-cronologia-elimina { color: var(--danger); border-color: var(--danger); }
.rip-cronologia-elimina:hover { background: var(--danger); color: #fff; }

/* Sopra la chat quando si sta rileggendo una conversazione chiusa: non e' un
   errore ne' un avviso, solo un promemoria che qui non si scrive. */
.rip-cronologia-banner {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  padding: var(--s-2) var(--s-3); background: var(--info-debole); color: var(--text);
  border-bottom: 1px solid var(--border); font-size: var(--t-sm);
}
.rip-cronologia-banner[hidden] { display: none; }

/* --- Lo switcher: piu' sessioni aperte insieme sullo stesso cliente --- */
.rip-switcher {
  display: flex; flex-wrap: wrap; gap: var(--s-1);
}
.rip-switcher:empty { display: none; }
.rip-switch-pill {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-tonda);
  padding: 6px 12px; font-size: var(--t-xs); font-weight: 600; color: var(--text-2);
  cursor: pointer; max-width: 140px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-family: inherit;
}
.rip-switch-pill:hover { border-color: var(--border-forte); color: var(--text); }
.rip-switch-attiva { background: var(--accent); border-color: var(--accent); color: #fff; }
.rip-switch-attiva:hover { color: #fff; }
.rip-switch-nuova { color: var(--accent); border-style: dashed; }

@media (max-width: 820px) {
  /* La larghezza (piu' stretta sul telefono) la da' gia' --rip-larg,
     ridefinita piu' sopra sotto la stessa soglia. */
  .rip-drawer-tab { padding: 10px 10px; }
}

@media (max-width: 700px) {
  .rip-apri { flex-direction: column; align-items: stretch; }
  .rip-messaggi { max-height: none; }
  .rip-bolla { max-width: 100%; }
}


/* Il link dell'assistenza, in chiaro sulla pagina.
   Stava solo dentro una finestra da aprire con un pulsante: chi lo cerca di
   corsa mentre ha il cliente al telefono non lo trova. */
.assist-link { margin-bottom: var(--s-4); }
.assist-link-nota { margin: var(--s-1) 0 var(--s-3) 0; }
.assist-link-riga { display: flex; gap: var(--s-2); align-items: center; flex-wrap: wrap; }
.assist-link-riga .form-control { flex: 1 1 22rem; font-family: var(--font); }


/* Bridge: prima si agisce, poi si legge.
   La spiegazione di cos'e' un bridge stava sopra ai pulsanti e la leggeva
   ogni volta chi quei pulsanti li usa dieci volte al giorno. */
.bridge-testa { margin-bottom: var(--s-3); }
.bridge-azioni { display: flex; gap: var(--s-2); flex-wrap: wrap; align-items: center; }
.bridge-riserva { display: flex; align-items: center; gap: 6px; font-size: var(--t-base); margin-left: var(--s-1); }
.bridge-nota { margin: var(--s-3) 0; }
.bridge-info { font-size: var(--t-base); margin-bottom: var(--s-3); }


/* ============================================================
   TELEFONO
   ============================================================
   Fino a qui il pannello era un programma da scrivania a cui,
   sotto i 768 pixel, si stringeva il menu a una colonna di
   icone. Bastava per guardare, non per lavorare: le tabelle
   uscivano di lato, i pulsanti erano piu' piccoli di un dito,
   e ogni campo di testo faceva ingrandire la pagina a iOS.

   Le regole stanno tutte qui in fondo, in un blocco solo, e in
   ordine di larghezza. Tre soglie:

     820 px  il menu diventa un cassetto e compare la barra in alto
     700 px  le tabelle diventano schede, una riga per scheda
     520 px  si stringe: due colonne di numeri, meno margini

   piu' una regola che non guarda la larghezza ma il DITO
   (pointer: coarse): le aree da toccare devono essere grandi
   abbastanza anche su un tablet largo.
   ============================================================ */

/* --- La barra in alto e il cassetto del menu --- */

.app-bar { display: none; }
.velo-menu { display: none; }

@media (max-width: 820px) {
  /* La barra e' fissa: da qualunque punto della pagina il menu e il nome di
     dove si sta sono a portata di pollice, senza risalire in cima. */
  .app-bar {
    position: fixed; top: 0; left: 0; right: 0; z-index: 120;
    display: flex; align-items: center; gap: var(--s-3);
    height: calc(var(--h-barra) + env(safe-area-inset-top, 0px));
    padding: env(safe-area-inset-top, 0px) var(--s-3) 0;
    background: var(--sidebar-bg); color: #fff;
    box-shadow: 0 1px 3px rgba(11,20,26,0.25);
  }
  .app-bar img { height: 22px; width: auto; }
  .app-bar-titolo {
    flex: 1; min-width: 0; font-size: var(--t-md); font-weight: 650;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .app-bar-menu {
    background: transparent; border: 0; color: #fff;
    font-size: 22px; line-height: 1; cursor: pointer;
    width: 40px; height: 40px; border-radius: var(--r);
    display: flex; align-items: center; justify-content: center;
    margin-left: -6px;
  }
  .app-bar-menu:active { background: rgba(255,255,255,0.12); }
  .app-bar .theme-toggle { margin-left: 0; color: #fff; }

  /* Il menu esce da sinistra. Resta un `position: fixed` come sul computer:
     cambia solo che di norma sta fuori dallo schermo. */
  .sidebar {
    /* Sopra la barra (z 120): il cassetto la copre quando e' aperto, cosi' la
       sua intestazione col logo si vede tutta invece di finirle sotto. */
    z-index: 130;
    width: min(280px, 84vw);
    transform: translateX(-100%);
    transition: transform var(--tr);
    overflow-y: auto; overscroll-behavior: contain;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    box-shadow: none;
  }
  .sidebar.aperta { transform: none; box-shadow: 0 0 40px rgba(0,0,0,0.4); }
  .velo-menu {
    display: block; position: fixed; inset: 0; z-index: 125;
    background: rgba(11,20,26,0.5);
    opacity: 0; pointer-events: none; transition: opacity var(--tr);
  }
  .velo-menu.visibile { opacity: 1; pointer-events: auto; }
  /* Col cassetto aperto la pagina sotto non deve scorrere. */
  body.menu-aperto { overflow: hidden; }

  .main-content {
    margin-left: 0;
    padding: var(--pad-pagina);
    padding-top: calc(var(--h-barra) + env(safe-area-inset-top, 0px) + var(--pad-pagina));
    /* Rete di sicurezza contro lo scorrimento laterale: `clip` taglia senza
       creare un contenitore di scorrimento, quindi le intestazioni appiccicate
       (.client-hero) continuano a funzionare. Con `hidden` non sarebbe cosi'. */
    overflow-x: clip;
  }
  /* Quello che resta appiccicato in alto deve fermarsi SOTTO la barra. */
  .client-hero { top: calc(var(--h-barra) + env(safe-area-inset-top, 0px)); }

  /* Il titolo della pagina e' gia' nella barra: ripeterlo qui ruba una riga
     su tre. Restano i pulsanti dell'intestazione. */
  .page-header h1 { display: none; }
  .page-header { margin-bottom: var(--s-3); }
  .page-header:empty { display: none; }

  /* In modalita' "solo conversazioni" la barra c'e' gia' (.sc-barra). */
  body.solo-conversazioni .app-bar,
  body.solo-conversazioni .velo-menu { display: none; }
  body.solo-conversazioni .main-content { padding-top: 0; }
}

/* --- Le tabelle diventano schede --- */

@media (max-width: 700px) {
  :root { --pad-pagina: 12px; }

  /* Una tabella di sei colonne su uno schermo di 360 pixel non si legge:
     scorre di lato e si perde la colonna del nome, che e' l'unica che dice di
     chi si sta parlando. Ogni riga diventa una scheda e ogni cella una riga
     "etichetta: valore". Le etichette le copia il JS dalle intestazioni
     (App.etichettaTabelle), cosi' vale per tutte le tabelle del pannello
     senza toccarne nemmeno una. */
  /* `:not(.tabella-vera)` su tutte le righe qui sotto: una tabella puo'
     chiedere di restare una tabella, e allora non la si tocca. Farlo
     "trasformando e poi rimettendo a posto" non funzionava — le regole del
     ripristino erano meno specifiche di quelle della trasformazione. */
  .table-wrapper:not(.tabella-vera) {
    border: 0; background: transparent; border-radius: 0; overflow: visible;
  }
  .table-wrapper:not(.tabella-vera) table,
  .table-wrapper:not(.tabella-vera) tbody,
  .table-wrapper:not(.tabella-vera) tr,
  .table-wrapper:not(.tabella-vera) td { display: block; width: auto; }
  .table-wrapper:not(.tabella-vera) thead { display: none; }
  .table-wrapper:not(.tabella-vera) tr {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
    margin-bottom: var(--s-2); padding: var(--s-2) var(--s-3);
  }
  .table-wrapper:not(.tabella-vera) tr:hover { background: var(--surface); }
  .table-wrapper:not(.tabella-vera) td {
    border: 0; padding: 6px 0; font-size: var(--t-base);
    overflow-wrap: anywhere;
  }
  .table-wrapper:not(.tabella-vera) td + td { border-top: 1px dashed var(--border); }
  .table-wrapper:not(.tabella-vera) td[data-etichetta] {
    display: grid; grid-template-columns: minmax(5.5rem, 34%) minmax(0, 1fr);
    gap: var(--s-3); align-items: start;
  }
  .table-wrapper:not(.tabella-vera) td[data-etichetta]::before {
    content: attr(data-etichetta);
    font-size: var(--t-xs); font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.4px; color: var(--text-3); padding-top: 2px;
  }
  /* La prima cella e' il titolo della scheda: quasi sempre e' il nome, la
     data o il cliente, cioe' di CHI parla la riga. Con l'etichetta davanti
     ("Nome: Rossi") si leggerebbe come un campo qualunque, e la scheda non
     avrebbe piu' un capo. */
  .table-wrapper:not(.tabella-vera) td:first-child:not([colspan]) {
    display: block; font-size: var(--t-md); font-weight: 650; padding-top: 2px;
  }
  .table-wrapper:not(.tabella-vera) td:first-child:not([colspan])::before { content: none; }
  /* Una cella vuota non merita una riga con l'etichetta e il vuoto accanto. */
  .table-wrapper:not(.tabella-vera) td[data-etichetta]:empty { display: none; }
  /* Una cella che nella tabella occupava tutta la riga — un "Caricamento…",
     un "nessun risultato" — non e' un campo: niente etichetta. */
  .table-wrapper:not(.tabella-vera) td[colspan] { display: block; text-align: center; }
  .table-wrapper:not(.tabella-vera) td[colspan]::before { content: none; }
  /* La colonna dei pulsanti non e' un campo da etichettare: i pulsanti vanno
     in fila per largo, e se non ci stanno vanno a capo. */
  .table-wrapper:not(.tabella-vera) td[data-etichetta="Azioni"] {
    display: flex; flex-wrap: wrap; gap: var(--s-2); padding-top: var(--s-2);
  }
  .table-wrapper:not(.tabella-vera) td[data-etichetta="Azioni"]::before { content: none; }
  .table-wrapper:not(.tabella-vera) td[data-etichetta="Azioni"] .btn { flex: 1 1 auto; }

  /* Chi resta tabella si porta dietro lo scorrimento laterale, che senza
     l'inquadratura del riquadro non si capirebbe. */
  .table-wrapper.tabella-vera { -webkit-overflow-scrolling: touch; }

  /* Le righe messe in fila con un `display:flex` scritto dentro l'attributo
     `style` — ce ne sono una cinquantina fra pagina e JS — quasi mai hanno il
     permesso di andare a capo: su uno schermo stretto i pulsanti si
     stringono finche' il testo non si legge piu'. Qui glielo si da', e chi
     ci sta su una riga resta su una riga. */
  [style*="display:flex"], [style*="display: flex"] { flex-wrap: wrap; }
  /* Chi invece DEVE restare in riga (una barra con un campo che si allunga)
     lo dice con questa classe. */
  .senza-capo, .senza-capo[style] { flex-wrap: nowrap; }

  /* --- Il resto che sul telefono stava stretto --- */
  /* Il nome del cliente e' nella barra in alto, che resta sempre in vista:
     nell'intestazione occuperebbe una riga per dire la stessa cosa, e quella
     riga la si toglie alle conversazioni. Restano il "torna ai clienti",
     l'agent id e i due indicatori. */
  .client-hero { padding-top: var(--s-2); }
  .client-hero-id h1 { display: none; }
  .client-hero-top { gap: var(--s-2); margin-bottom: var(--s-2); }
  .card { padding: var(--s-4) var(--s-3); border-radius: var(--r); }
  .card-header { gap: var(--s-2); margin-bottom: var(--s-3); }
  .barra-filtri { flex-direction: column; align-items: stretch; }
  .barra-filtri .form-control, .barra-filtri .campo-cerca { width: 100%; min-width: 0; }
  .barra-filtri .conteggio { margin-left: 0; }
  .form-row { grid-template-columns: 1fr; }
  .detail-grid, .grid-3, .disp-griglia-interna,
  .griglia-2, .griglia-3, .griglia-211 { grid-template-columns: 1fr; }
  .due-colonne { flex-direction: column; min-height: 0; }
  .due-colonne-lato {
    width: 100%; max-height: 200px;
    border-right: 0; border-bottom: 1px solid var(--border);
  }
  .due-colonne-corpo { padding-left: 0; }

  /* Le finestre diventano fogli che salgono dal basso: e' il gesto che sul
     telefono si conosce, e cosi' i pulsanti in fondo restano sopra il pollice
     invece che a meta' schermo. */
  .modal-overlay { padding: 0; align-items: flex-end; }
  .modal {
    max-width: none; max-height: 92dvh;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    padding: var(--s-5) var(--s-4) calc(var(--s-4) + env(safe-area-inset-bottom, 0px));
    transform: translateY(16px);
  }
  .modal-footer { flex-direction: column-reverse; }
  .modal-footer .btn { width: 100%; }

  .toast-container {
    left: var(--s-3); right: var(--s-3); max-width: none;
    bottom: calc(var(--s-3) + env(safe-area-inset-bottom, 0px));
  }

  /* Le conversazioni: l'altezza dello schermo vero (dvh), non quella con la
     barra del browser aperta, e senza il minimo di 460 pixel che su un
     telefono basso obbligava a scorrere. */
  .wa-webchat { height: calc(100dvh - 260px); min-height: 320px; }
  body.solo-conversazioni .wa-webchat { height: calc(100dvh - 46px); min-height: 0; }
  .chat-layout { height: calc(100dvh - 150px); }
  .chat-message { max-width: 92%; }
}

@media (max-width: 520px) {
  .stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2); }
  .stat-card { padding: var(--s-3); }
  .stat-card .stat-value { font-size: var(--t-xl); }
  .stat-card .stat-label { font-size: var(--t-xs); }
  .page-header .btn { width: 100%; }
  .ctabs .ctab { padding: 9px 11px; }
}

/* --- Il dito, non la larghezza ---
   Un tablet da 1024 px non entra in nessuna soglia qui sopra, ma si tocca
   uguale. Quello che conta e' che l'area da colpire sia grande: sotto i
   40 px si sbaglia bersaglio, e su un campo con meno di 16 px di testo iOS
   ingrandisce la pagina da solo — e da li' in poi si scorre di lato per il
   resto della sessione. */
@media (pointer: coarse) {
  .btn { min-height: 40px; }
  .btn-sm { min-height: 34px; padding: var(--s-2) var(--s-3); }
  .sidebar-nav a { padding: var(--s-3); }
  .tabs .tab, .ctabs .ctab { min-height: 42px; }
  .modal-close { min-width: 40px; min-height: 40px; }
  /* "vedi dettaglio" e' scritto piccolo perche' sta sotto una riga di
     tabella, ma col dito serve comunque qualcosa da colpire. */
  .link-dettaglio { min-height: 32px; padding: var(--s-2) 0; }
  /* La finestra del desktop remoto ha una barra sua, gia' pensata per il
     telefono: ingrandirne i pulsanti la manderebbe a capo. */
  .desk-barra .btn, .ssh-barra .btn { min-height: 0; }

  /* La chiusura invece deve essere presa al primo colpo. Non e' un `.btn`,
     quindi le regole qui sopra non la toccavano: restava una crocetta di
     pochi millimetri in cima a una finestra che occupa tutto lo schermo, e
     da telefono la si mancava. Da qui non si esce con Escape, non c'e' una
     tastiera: se non si prende quella, si resta dentro. */
  .ssh-chiudi {
    min-width: 44px; min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 26px;
  }

  input.form-control, select.form-control, textarea.form-control,
  .chat-input, .rip-input, .wa-scrivi input, .wa-scrivi textarea {
    font-size: 16px;
  }
  input.form-control, select.form-control { min-height: 42px; }
}

/* La scelta "tutto il computer" nel piano di backup. Sta sopra il riquadro
   delle cartelle e non accanto: e' un'alternativa a quello, non un'opzione in
   piu' da spuntare insieme. */
.piano-tutto {
  display: flex;
  gap: var(--s-2);
  align-items: flex-start;
  padding: var(--s-3);
  margin-bottom: var(--s-3);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  background: var(--bg-2);
  cursor: pointer;
  font-weight: 400;
}
.piano-tutto input { margin-top: 3px; flex: 0 0 auto; }
.piano-tutto span { font-size: 13.5px; line-height: 1.45; color: var(--text-2); }
.piano-tutto strong { color: var(--text-1); }


/* === La prima domanda del piano di backup: file o immagine ===
   Sta in cima e si vede, perche' e' la scelta che non si puo' sbagliare:
   "salvo tutto il computer" suona come "posso rimetterlo in piedi" e non e'
   vero, e la differenza si scopriva il giorno del guasto. */
.tipo-backup { border: 1px solid var(--border); border-radius: var(--r-lg); padding: var(--s-3); }
.tipo-scelta {
  display: flex; align-items: flex-start; gap: var(--s-2);
  padding: var(--s-2); border-radius: var(--r); cursor: pointer;
  font-size: var(--t-sm); line-height: 1.5;
}
.tipo-scelta:hover { background: var(--bg-alt); }
.tipo-scelta input { margin-top: 3px; flex: 0 0 auto; }
.tipo-scelta em { color: var(--text-2); font-style: normal; }
.tipo-nota {
  margin-top: var(--s-2); padding: var(--s-3);
  border-left: 3px solid var(--attesa, #e0a800); background: var(--bg-alt);
  border-radius: var(--r); font-size: var(--t-sm); line-height: 1.55;
}
.tipo-nota p { margin: 0 0 var(--s-2); }
.tipo-nota p:last-child { margin-bottom: 0; }


/* === La barra di un backup che sta girando ===
   "In corso…" senza un numero ha fatto guardare per ore un backup da 2,5 TB
   senza sapere se lavorava o era piantato. La barra e' li' per rispondere a
   colpo d'occhio; la percentuale e i MB/s per chi vuole il dettaglio. */
.backup-avanza { min-width: 130px; }
.backup-avanza-testa { display: flex; align-items: center; gap: var(--s-2); margin-bottom: 4px; }
.backup-barra {
  height: 8px; background: var(--bg-alt); border-radius: var(--r-tonda);
  overflow: hidden; border: 1px solid var(--border);
}
.backup-barra-piena {
  height: 100%; background: var(--accent); border-radius: var(--r-tonda);
  transition: width .6s ease;
  /* Le righe oblique che scorrono dicono "sta lavorando" anche quando la
     percentuale resta ferma per un po' — su un disco grande capita, ed e'
     proprio il momento in cui uno si chiede se e' bloccato. */
  background-image: linear-gradient(45deg,
    rgba(255,255,255,.22) 25%, transparent 25%, transparent 50%,
    rgba(255,255,255,.22) 50%, rgba(255,255,255,.22) 75%, transparent 75%, transparent);
  background-size: 1rem 1rem;
  animation: scorre 1s linear infinite;
}
@keyframes scorre { from { background-position: 1rem 0; } to { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) { .backup-barra-piena { animation: none; } }

/* Barra senza percentuale: sappiamo che scrive, non quanto manca. Piu' chiara
   e a righe piu' larghe, cosi' si distingue a colpo d'occhio da una barra vera
   arrivata al 100% — che vorrebbe dire una cosa completamente diversa. */
.backup-barra-piena.backup-barra-ignota {
  background-color: var(--text-3, #9aa0a6);
  background-size: 1.6rem 1.6rem;
  animation-duration: 1.4s;
}

/* === Riparazione: le uscite lunghe non seppelliscono la conversazione ===
   Un `Get-ChildItem -Recurse` su un server ha stampato 60.024 caratteri dentro
   la chat: i messaggi dell'assistente, che sono corti, sparivano fra due muri
   di testo. Si mostrano le prime righe e il resto si apre a richiesta. */
.rip-cmd-apri {
  display: inline-block; margin-top: var(--s-1);
  background: none; border: none; padding: 2px 0;
  color: var(--accent); font-size: var(--t-xs); cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.rip-cmd-apri:hover { filter: brightness(1.15); }
/* Su schermo tattile il bersaglio deve restare prendibile col dito. */
@media (pointer: coarse) { .rip-cmd-apri { padding: 8px 0; } }


/* === Chat con chi sta davanti al computer del cliente ===
   Non e' una messaggistica: e' un pannello di assistenza. La grammatica e'
   quella del resto del pannello — chi scrive a destra, chi risponde a
   sinistra — ma con due cose che una chat normale non ha: SU QUALE computer e'
   andato ogni messaggio, e se e' arrivato davvero. */
.chatp { display: flex; flex-direction: column; gap: var(--s-2); }

.chatp-testa {
  display: flex; align-items: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-3); background: var(--bg-alt);
  border: 1px solid var(--border); border-radius: var(--r);
}
.chatp-testa label { font-size: var(--t-sm); color: var(--text-2); white-space: nowrap; font-weight: 600; }
.chatp-testa .form-control { flex: 1; }
.chatp-conta { font-size: var(--t-xs); color: var(--text-3); white-space: nowrap; }

.chatp-lista {
  min-height: 220px; max-height: 44vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--s-2);
  padding: var(--s-3); background: var(--bg-alt);
  border: 1px solid var(--border); border-radius: var(--r);
}
.chatp-b {
  max-width: 82%; padding: var(--s-2) var(--s-3); border-radius: var(--r-lg);
  font-size: var(--t-sm); line-height: 1.5; white-space: pre-wrap; word-break: break-word;
  box-shadow: 0 1px 2px rgba(11, 20, 26, .08);
}
.chatp-tec {
  align-self: flex-end; background: var(--bolla-uscita); color: var(--su-bolla-uscita);
  border-bottom-right-radius: 4px;
}
.chatp-cli {
  align-self: flex-start; background: var(--surface); border: 1px solid var(--border);
  border-bottom-left-radius: 4px;
}
/* Non consegnato: si vede SUBITO che e' diverso. E' la differenza fra
   "gliel'ho detto" e "credevo di averglielo detto". */
.chatp-perso { opacity: .72; border: 1px dashed var(--danger); }
.chatp-ko { color: var(--danger); font-weight: 700; }
.chatp-q { font-size: var(--t-xs); color: var(--text-3); margin-top: 4px; }
.chatp-tec .chatp-q { color: rgba(255, 255, 255, .85); }
/* Il giorno: una conversazione lunga senza date e' un muro, e "ieri" o "tre
   settimane fa" cambiano completamente il senso di quello che si legge. */
.chatp-giorno {
  align-self: center; font-size: var(--t-xs); color: var(--text-3);
  background: var(--surface); border: 1px solid var(--border);
  padding: 2px 10px; border-radius: var(--r-tonda); margin: var(--s-1) 0;
}
.chatp-vuoto {
  margin: auto; text-align: center; color: var(--text-3);
  font-size: var(--t-sm); max-width: 320px; line-height: 1.6;
}
.chatp-vuoto strong { display: block; color: var(--text); margin-bottom: 4px; font-size: var(--t-base); }

.chatp-scrivi { display: flex; gap: var(--s-2); }
.chatp-scrivi .form-control { flex: 1; }

/* Le frasi che si ripetono tutti i giorni. Scriverle a mano ogni volta e'
   tempo perso, e di fretta si sbaglia proprio quella che deve essere chiara. */
.chatp-pronte { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.chatp-pronte > span { font-size: var(--t-xs); color: var(--text-3); }
.chatp-pronta {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-tonda);
  padding: 4px 10px; font-size: var(--t-xs); color: var(--text-2); cursor: pointer;
}
.chatp-pronta:hover { border-color: var(--accent); color: var(--accent); }
.chatp-nota { margin: 0; }

/* === La chat dentro la sessione di assistenza ===
   Sta di lato e non copre la tela: quello che il tecnico deve guardare e' lo
   schermo del cliente, la chat e' un accessorio. Si apre e si chiude col
   pulsante nella barra. */
.desk-chat {
  /* `top` lo imposta il codice misurando la barra: quando i comandi vanno a
     capo la barra cresce, e un valore fisso qui coprirebbe l'intestazione
     della chat — col pulsante di chiusura sotto, che smette di rispondere. */
  position: absolute; top: 44px; right: 0; bottom: 0; width: min(320px, 40vw);
  display: flex; flex-direction: column; gap: var(--s-2); padding: var(--s-2);
  background: var(--surface); border-left: 1px solid var(--border);
  box-shadow: -4px 0 16px rgba(11, 20, 26, .18); z-index: 6;
}
/* IL PULSANTE DI CHIUSURA NON FUNZIONAVA PER QUESTO.
   `display:flex` qui sopra batte il `display:none` che il browser da' agli
   elementi con [hidden], che ha specificita' minima. Mettere `hidden` sul
   pannello quindi non lo nascondeva: il codice faceva la cosa giusta e non
   succedeva niente, che e' il difetto piu' difficile da vedere. */
.desk-chat[hidden] { display: none !important; }
.desk-chat-testa { display: flex; align-items: center; gap: var(--s-2); font-size: var(--t-sm); flex: none; }
/* Il pulsante di chiusura non deve mai essere schiacciato via dal nome del
   computer, che puo' essere lungo. */
.desk-chat-testa .desk-btn { flex: none; margin-left: auto; }
.desk-chat-testa span { color: var(--text-3); font-size: var(--t-xs); flex: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.desk-chat-lista {
  flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 6px;
  padding: var(--s-2); background: var(--bg-alt); border-radius: var(--r);
}
.desk-chat-b {
  max-width: 92%; padding: 6px 10px; border-radius: 10px; font-size: var(--t-xs);
  line-height: 1.45; white-space: pre-wrap; word-break: break-word;
}
.desk-chat-b.tec { align-self: flex-end; background: var(--bolla-uscita); color: var(--su-bolla-uscita); }
.desk-chat-b.cli { align-self: flex-start; background: var(--surface); border: 1px solid var(--border); }
.desk-chat-b.perso { border: 1px dashed var(--danger); opacity: .75; }
/* Niente `opacity` per smorzare il testo: riduce il contrasto in modo
   incontrollabile e sopra una bolla colorata diventa illeggibile. Si usa un
   colore, che si puo' misurare. */
.desk-chat-q { display: block; font-size: 10px; color: var(--text-3); margin-top: 3px; }
.desk-chat-b.tec .desk-chat-q { color: rgba(255, 255, 255, .85); }
.desk-chat-vuoto { margin: auto; text-align: center; color: var(--text-3); font-size: var(--t-xs); padding: 12px; }
.desk-chat-scrivi { display: flex; gap: 6px; }
.desk-chat-scrivi input {
  flex: 1; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--r);
  background: var(--bg-alt); color: var(--text); font: inherit; font-size: var(--t-xs);
}
.desk-chat-scrivi button {
  padding: 8px 12px; border: 0; border-radius: var(--r); background: var(--accent);
  color: #fff; font: inherit; font-size: var(--t-xs); font-weight: 600; cursor: pointer;
}
.desk-chat-pronte { display: flex; flex-wrap: wrap; gap: 4px; }
.desk-chat-pronta {
  background: var(--bg-alt); border: 1px solid var(--border); border-radius: var(--r-tonda);
  padding: 3px 8px; font-size: 10px; color: var(--text-2); cursor: pointer;
}
.desk-chat-pronta:hover { border-color: var(--accent); color: var(--accent); }
/* La pastiglia sul pulsante: e' l'unico modo di accorgersi che il cliente ha
   risposto mentre si sta guardando il suo schermo. */
.desk-chat-btn { position: relative; }
.desk-chat-badge {
  position: absolute; top: -4px; right: -4px; min-width: 15px; padding: 0 4px;
  background: var(--danger); color: #fff; border-radius: 8px;
  font-size: 10px; font-weight: 700; line-height: 15px; text-align: center;
}
@media (max-width: 700px) { .desk-chat { width: 100%; } }

/* L'avviso "hanno scritto anche da un altro computer": la conversazione e' per
   macchina, e senza questo aprendo la chat della cassa non si saprebbe mai che
   dall'ufficio stanno aspettando una risposta. */
.chatp-altri {
  font-size: var(--t-xs); color: var(--warning);
  background: var(--warning-debole); border: 1px solid var(--warning);
  border-radius: var(--r); padding: var(--s-2) var(--s-3); margin-bottom: var(--s-2);
}

/* Le due schede del pannello laterale: col cliente e con l'assistente. Sono
   due conversazioni diverse e devono sembrarlo, ma stare nello stesso posto —
   passare dall'una all'altra non deve costare l'uscita dalla sessione. */
.desk-chat-scheda {
  background: none; border: 0; border-bottom: 2px solid transparent;
  padding: 4px 8px; font: inherit; font-size: var(--t-xs); color: var(--text-2);
  cursor: pointer; white-space: nowrap;
}
.desk-chat-scheda.attiva { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
.desk-chat-dove {
  font-size: 10px; color: var(--text-3); flex: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.desk-chat-corpo { flex: 1; display: flex; flex-direction: column; gap: var(--s-2); min-height: 0; }
/* SENZA QUESTO le due schede non si scambiano.
   `display:flex` qui sopra batte il `display:none` che il browser da' a
   [hidden], che ha specificita' minima: il risultato e' che nascondere una
   scheda non la nasconde, si vedono tutte e due sovrapposte e il pulsante
   sembra non funzionare. E' il classico difetto di [hidden] contro display. */
.desk-chat-corpo[hidden] { display: none !important; }
/* I comandi che l'assistente esegue: si vede COSA sta guardando, non l'uscita
   per intero — per quella c'e' il cassetto grande della riparazione. */
.desk-rip-cmd {
  align-self: stretch; background: var(--bg-alt); border: 1px solid var(--border);
  border-radius: var(--r); padding: 5px 8px; font-size: 10px;
}
.desk-rip-cmd code { color: var(--accent); word-break: break-all; }
.desk-rip-cmd pre {
  margin: 4px 0 0; white-space: pre-wrap; word-break: break-word;
  color: var(--text-3); max-height: 62px; overflow: hidden;
}
.desk-rip-verbale {
  align-self: center; font-size: 10px; color: var(--text-3); font-style: italic;
  border: 1px dashed var(--border); border-radius: var(--r); padding: 3px 8px;
}
.desk-rip-attesa { align-self: flex-start; font-size: 10px; color: var(--text-3); font-style: italic; }

/* Aprire una riparazione dal pannello laterale: una riga per il motivo e un
   pulsante. Il motivo non e' una formalita' — finisce nel registro accanto a
   ogni comando eseguito su quel computer. */
.desk-rip-apri { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.desk-rip-apri input {
  padding: 7px 9px; border: 1px solid var(--border); border-radius: var(--r);
  background: var(--bg-alt); color: var(--text); font: inherit; font-size: var(--t-xs);
}
.desk-rip-prop {
  align-self: stretch; background: var(--bg-alt); border: 1px solid var(--accent);
  border-radius: var(--r); padding: 7px 9px; font-size: 10px;
  display: flex; flex-direction: column; gap: 5px;
}
.desk-rip-prop-eti { font-weight: 700; color: var(--accent); text-transform: uppercase; letter-spacing: .03em; }
.desk-rip-prop code { color: var(--text-2); word-break: break-all; }
.desk-rip-esegui {
  align-self: flex-start; background: var(--accent); color: #fff; border: 0;
  border-radius: var(--r); padding: 5px 10px; font: inherit; font-size: 10px;
  font-weight: 600; cursor: pointer;
}
.desk-rip-esegui:disabled { opacity: .6; cursor: default; }

/* Credenziali del desktop remoto ricordate per computer. Su un server lo
   schermo condiviso non funziona — non c'e' desktop da catturare finche'
   nessuno e' collegato — e il desktop remoto e' la strada giusta: ma
   riscrivere utente e password a ogni intervento e' l'attrito che porta a
   mettere la stessa password ovunque pur di non ripeterlo. */
.desk-salva { display: flex; align-items: center; gap: var(--s-2); font-size: var(--t-sm); cursor: pointer; }
.desk-salva input { width: auto; }
.desk-salvate-nota {
  display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap;
  margin-top: var(--s-2); padding: var(--s-2) var(--s-3);
  background: var(--success-debole); border: 1px solid var(--success);
  border-radius: var(--r); font-size: var(--t-sm);
}

/* Il riquadro dell'errore quando non c'e' niente da mostrare: spiega il perche'
   e offre la strada che funziona, invece di lasciare una finestra da chiudere
   e ricominciare indovinando. */
.desk-errore { display: flex; flex-direction: column; align-items: center; gap: var(--s-3); max-width: 460px; }
.desk-errore-perche { color: var(--text-2); font-size: var(--t-sm); line-height: 1.55; }

/* === BACKUP IMMAGINE (PROXMOX) ===
   Poche regole, e ognuna per un motivo che si e' visto in faccia.

   La riga di un server si apre cliccandola: e' fatta di quattro dati che non
   si toccano mai, e chi la guarda ci clicca sopra aspettandosi che succeda
   qualcosa. Senza il cursore a mano nessuno ci prova, e il quadro delle
   macchine — cioe' l'unica cosa per cui questa card esiste — resta chiuso.

   Le righe rosse a sinistra non sono decorazione. In una tabella di quaranta
   macchine il colore del testo dentro una cella si perde: la macchina che
   nessuno sta salvando deve saltare all'occhio scorrendo, non leggendo. Il
   segno e' un box-shadow interno e non un border-left perche' con `border` la
   cella si sposta di tre pixel e la colonna balla fra una riga e l'altra. */
.prox-riga { cursor: pointer; }
.prox-riga.scelta { background: var(--success-debole); }
.prox-riga.scelta td:first-child { box-shadow: inset 3px 0 0 var(--success); }
.prox-mai td:first-child, .prox-guasta td:first-child { box-shadow: inset 3px 0 0 var(--danger); }

.prox-quadro { margin-top: var(--s-4); border-top: 1px solid var(--border); padding-top: var(--s-3); }
.prox-quadro-testa {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-3); flex-wrap: wrap; margin-bottom: var(--s-3);
}

/* Quello che NON si e' potuto leggere, detto prima della tabella e non dopo.
   Un nodo che non risponde fa comparire le sue macchine come «mai salvate»:
   se l'avviso stesse in fondo verrebbe letto dopo aver gia' creduto alla
   tabella, e si andrebbe a cercare un backup che c'e'. Stesso riquadro giallo
   di .disp-respinto, per la stessa ragione: e' un «attenzione, qui manca un
   pezzo», non un errore rosso. */
.prox-avviso {
  border: 1px solid var(--warning); background: var(--warning-debole);
  color: var(--text); border-radius: var(--r-lg);
  padding: var(--s-3) var(--s-4); margin-bottom: var(--s-3);
  font-size: var(--t-sm); line-height: 1.55;
}
.prox-avviso ul { margin: var(--s-2) 0 0 var(--s-4); }
.prox-avviso code { font-family: var(--font); font-size: var(--t-xs); }

/* Sotto i 700 pixel ogni riga diventa una scheda (vedi «Le tabelle diventano
   schede» piu' sopra) e il segno rosso, che li' vive su `td:first-child`,
   resterebbe un trattino accanto al nome. La macchina mai salvata e' la
   ragione per cui si apre questa tabella anche dal telefono: qui il segno
   passa al bordo della scheda, che si vede scorrendo. */
@media (max-width: 700px) {
  .table-wrapper:not(.tabella-vera) .prox-mai,
  .table-wrapper:not(.tabella-vera) .prox-guasta { border-color: var(--danger); }
  .table-wrapper:not(.tabella-vera) .prox-riga.scelta { border-color: var(--success); }
  .table-wrapper:not(.tabella-vera) .prox-mai td:first-child,
  .table-wrapper:not(.tabella-vera) .prox-guasta td:first-child,
  .table-wrapper:not(.tabella-vera) .prox-riga.scelta td:first-child { box-shadow: none; }
}


/* === Quanto spazio resta sui depositi di backup ===
   Le classi cominciano tutte per `spz-` apposta: in questo foglio `.backup-barra`
   esiste gia' due volte e vuol dire due cose diverse (l'istogramma delle
   esecuzioni e la barra di avanzamento di un backup in corso). Una terza
   barra chiamata cosi' avrebbe ereditato gli stili di una delle due, a caso
   secondo l'ordine delle righe. */
.spz-scheda {
  border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--s-4); background: var(--surface-alt);
  margin-bottom: var(--s-3);
}
.spz-scheda:last-child { margin-bottom: 0; }
/* Il pericolo si deve vedere da lontano, prima di aver letto un numero: il
   bordo e il fondo colorati fanno saltare fuori la scheda giusta anche in un
   cliente che ne ha sei. */
.spz-scheda.attenzione { border-color: var(--warning); }
.spz-scheda.ko { border-color: var(--danger); background: var(--danger-debole); }
/* Una destinazione disattivata si vede ma non grida: i backup di ieri sono
   ancora li' dentro, pero' non e' lei il problema di oggi. */
.spz-scheda.spenta { opacity: .7; }

.spz-testa {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s-3); flex-wrap: wrap; margin-bottom: var(--s-3);
}
.spz-titolo { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; min-width: 0; }
.spz-nome { font-size: var(--t-md); overflow-wrap: anywhere; }
.spz-allarme { color: var(--danger); background: var(--danger-debole); }
.spz-resta { text-align: right; }
.spz-grande { font-size: var(--t-xl); font-weight: 700; line-height: 1.15; }
.spz-scheda.ko .spz-grande { color: var(--danger); }
.spz-scheda.attenzione .spz-grande { color: var(--warning); }
/* "Non si sa" non e' un numero e non deve pesare come un numero: stessa riga,
   ma piu' piccolo e grigio, cosi' non si legge come una misura. */
.spz-grande.spz-ignoto { font-size: var(--t-md); font-weight: 600; color: var(--text-2); }
.spz-grande-eti { display: block; font-size: var(--t-xs); color: var(--text-2); }

/* La barra: nostro, di altri, libero. I bordi arrotondati stanno sul
   contenitore e non sui segmenti, se no un segmento sottile diventa una
   pastiglia e sembra piu' grande di quello che e'. */
.spz-barra {
  display: flex; height: 24px; border-radius: var(--r-sm); overflow: hidden;
  border: 1px solid var(--border-forte); background: var(--surface);
}
.spz-seg {
  display: flex; align-items: center; justify-content: center;
  font-size: var(--t-xs); font-weight: 600; white-space: nowrap; overflow: hidden;
  min-width: 0;
}
.spz-seg-nostro { background: var(--accent); color: var(--su-accento); }
/* Il blu per "di altri": e' un'altra tinta, non un altro verde, cosi' si
   distingue anche da chi non separa bene il rosso dal verde. */
.spz-seg-altri { background: var(--info); color: #ffffff; }
/* Sul tema scuro --info diventa un azzurro chiaro e il testo bianco ci
   sparisce sopra: li' il testo va scuro. */
[data-theme="dark"] .spz-seg-altri { color: #06212e; }
/* Occupato ma non si sa da chi: grigio, non verde. Il verde e' "roba nostra",
   e qui non lo sappiamo. */
.spz-seg-ignoto { background: var(--text-3); color: var(--surface); }
.spz-seg-libero { background: var(--surface); color: var(--text-2); }
.spz-scheda.ko .spz-seg-libero { background: var(--danger-debole); }

.spz-legenda {
  display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4);
  margin-top: var(--s-2); font-size: var(--t-sm); color: var(--text-2);
}
.spz-voce { display: inline-flex; align-items: center; gap: 6px; }
.spz-voce strong { color: var(--text); }
.spz-pallino { display: inline-block; width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }
.spz-pallino.spz-seg-libero { border: 1px solid var(--border-forte); }

.spz-date { margin-top: var(--s-2); display: flex; flex-wrap: wrap; gap: var(--s-2); }
.spz-sep { color: var(--text-3); }
.spz-nota { margin-top: var(--s-2); line-height: 1.5; }

/* Il riquadro della stima: e' la risposta che si viene a cercare, e sta in
   un numero grande da leggere senza avvicinarsi allo schermo. */
.spz-stima {
  margin-top: var(--s-3); padding: var(--s-3);
  border: 1px solid var(--border); border-left-width: 4px;
  border-radius: var(--r); background: var(--surface);
}
.spz-stima-testa {
  display: block; font-size: var(--t-xs); text-transform: uppercase;
  letter-spacing: 0.5px; color: var(--text-3); margin-bottom: 2px;
}
.spz-stima strong { font-size: var(--t-xl); font-weight: 700; line-height: 1.2; }
.spz-stima .spz-quando { font-size: var(--t-md); color: var(--text-2); margin-left: var(--s-1); }
.spz-stima .hint { display: block; margin-top: var(--s-1); line-height: 1.5; }
.spz-stima-ok { border-left-color: var(--success); }
.spz-stima-attenzione { border-left-color: var(--warning); }
.spz-stima-attenzione strong { color: var(--warning); }
.spz-stima-allarme { border-left-color: var(--danger); background: var(--danger-debole); }
.spz-stima-allarme strong { color: var(--danger); }
/* Il riquadro del "non si sa" resta grigio e col numero piccolo: deve essere
   evidente a colpo d'occhio che li' NON c'e' una previsione, altrimenti si
   legge come una e si torna a casa tranquilli. */
.spz-stima-ignota { border-left-color: var(--border-forte); }
.spz-stima-ignota strong { font-size: var(--t-md); font-weight: 600; color: var(--text-2); }

/* L'andamento. L'SVG ha altezza fissa e larghezza libera (`preserveAspectRatio
   ="none"`): cosi' la curva si allarga quanto la card senza sformarsi in
   altezza, e le linee restano spesse un pixel grazie a `non-scaling-stroke`.
   Le scritte stanno FUORI dal disegno, in HTML: dentro si sarebbero
   ristrette insieme al resto e sul telefono non si leggevano piu'. */
.spz-grafico { margin-top: var(--s-3); }
.spz-grafico-testa, .spz-grafico-piede {
  display: flex; justify-content: space-between; gap: var(--s-2);
  flex-wrap: wrap; margin: var(--s-1) 0;
}
.spz-delta { font-weight: 600; color: var(--text-2); }
.spz-svg {
  display: block; width: 100%; height: 120px;
  border: 1px solid var(--border); border-radius: var(--r); background: var(--surface);
}
.spz-area { fill: var(--accent); fill-opacity: .16; stroke: none; }
.spz-linea { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.spz-punto { stroke: var(--accent); stroke-width: 2; }
.spz-scheda.ko .spz-area { fill: var(--danger); }
.spz-scheda.ko .spz-linea, .spz-scheda.ko .spz-punto { stroke: var(--danger); }

@media (max-width: 700px) {
  /* Il numero grande torna sotto al nome e a sinistra: allineato a destra, su
     una riga sua, sembrava appartenere alla scheda dopo. */
  .spz-testa { flex-direction: column; align-items: flex-start; gap: var(--s-1); }
  .spz-resta { text-align: left; }
  .spz-legenda { gap: var(--s-1) var(--s-3); font-size: var(--t-xs); }
  .spz-svg { height: 96px; }
  .spz-stima strong { font-size: var(--t-lg); }
}

/* === Sicurezza: l'antivirus dei computer === */
.sic-pallino { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 5px; vertical-align: middle; background: var(--border); }
.sic-pallino.ok { background: var(--success); }
.sic-pallino.ko { background: var(--danger); }
.sic-pallino.boh { background: var(--warning); }
.sic-tabella td { vertical-align: top; }
.sic-sotto { font-size: var(--t-xs); color: var(--text-2); }
.sic-grave { color: var(--danger); font-weight: 600; }
.sic-attenzione { color: var(--warning); font-weight: 600; }

/* === La scheda di un computer (Cliente › Computer) === */
.comp-briciole { display: flex; align-items: center; gap: var(--s-2); font-size: var(--t-sm); color: var(--text-2); margin-bottom: var(--s-3); flex-wrap: wrap; }
.comp-briciole a { color: var(--accent); cursor: pointer; text-decoration: none; }
.comp-briciole .attuale { color: var(--text); font-weight: 600; }
.comp-testa { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--s-3); flex-wrap: wrap; }
.comp-testa h2 { margin: 0 0 4px; font-size: var(--t-lg); }
.comp-griglia { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--s-3); }
.servizio-riga { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-2) 0; border-top: 1px solid var(--border); }
.servizio-riga:first-child { border-top: 0; }
.servizio-riga .servizio-nome { flex: 1; }
.servizio-riga .servizio-prezzo { font-size: var(--t-xs); color: var(--text-2); white-space: nowrap; }
.servizio-riga input[type=checkbox] { width: 18px; height: 18px; }
.comp-sezione h4 { margin: 0 0 var(--s-2); font-size: var(--t-sm); color: var(--text-2); text-transform: uppercase; letter-spacing: .04em; }
.comp-tabs { display: flex; gap: var(--s-2); border-bottom: 1px solid var(--border); margin-bottom: var(--s-3); overflow-x: auto; }
.comp-tab { background: none; border: 0; border-bottom: 2px solid transparent; padding: var(--s-2) var(--s-3); cursor: pointer; color: var(--text-2); font-size: var(--t-sm); white-space: nowrap; }
.comp-tab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
.comp-tab .n { display: inline-block; min-width: 18px; padding: 0 5px; margin-left: 4px; border-radius: 9px; background: var(--danger); color: #fff; font-size: var(--t-xs); text-align: center; }

/* === La sonda di presenza dei server (14/09/2026) ===
   Una casella per giorno come per i backup, ma con un'altra domanda: non
   "com'e' finito il backup" ma "quanto e' mancato il computer". Il riquadro
   della dashboard si accende di rosso quando un server e' fuori servizio:
   e' l'unico riquadro che deve saltare all'occhio. */
.stat-card.allarme .stat-value { color: var(--danger); }
.stat-card.allarme { border-color: var(--danger); }
.card.card-allarme { border-color: var(--danger); box-shadow: 0 0 0 3px var(--danger-debole); }
.card.card-allarme .card-header h3 { color: var(--danger); }
.presenza-celle { display: inline-flex; gap: 2px; vertical-align: middle; max-width: 100%; overflow-x: auto; }
.presenza-giorno {
  display: inline-block; flex: 0 0 9px; width: 9px; height: 14px;
  border-radius: 2px; background: var(--border);
}
.presenza-giorno.ok { background: var(--success); }
.presenza-giorno.breve { background: var(--warning); }
.presenza-giorno.giu { background: var(--danger); }
.presenza-giorno.niente { background: var(--border); }
.presenza-legenda {
  display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center;
  margin-top: var(--s-3); font-size: var(--t-xs); color: var(--text-2);
}
.presenza-legenda .presenza-giorno { width: 10px; height: 10px; flex-basis: 10px; margin-right: 4px; vertical-align: middle; }
.presenza-grande { font-size: var(--t-xl); font-weight: 700; }
/* La riga di un cliente o di un server fuori servizio: il bordo rosso a
   sinistra, come le copie guaste di Proxmox. */
.riga-server-giu td:first-child { box-shadow: inset 3px 0 0 var(--danger); }
@media (max-width: 700px) {
  .table-wrapper:not(.tabella-vera) .riga-server-giu { border-color: var(--danger); }
  .table-wrapper:not(.tabella-vera) .riga-server-giu td:first-child { box-shadow: none; }
}

/* === La campanella del centro notifiche === */
.campana {
  position: relative; background: none; border: 0; cursor: pointer;
  font-size: 19px; line-height: 1; padding: 6px; border-radius: 8px;
  color: inherit; -webkit-tap-highlight-color: transparent;
}
.sidebar-header .campana { color: #fff; margin-left: auto; }
.campana:hover { background: rgba(255,255,255,0.12); }
.app-bar .campana:hover { background: rgba(255,255,255,0.12); }
.campana-badge {
  position: absolute; top: -2px; right: -2px; min-width: 17px; height: 17px;
  padding: 0 4px; border-radius: 9px; background: var(--rosso, #d64541); color: #fff;
  font-size: 10.5px; font-weight: 700; line-height: 17px; text-align: center;
  box-shadow: 0 0 0 2px var(--sidebar-bg, #111b21);
}
.campana-badge.solo-note { background: var(--grigio-500, #8696a0); }
.app-bar .campana-badge { box-shadow: 0 0 0 2px var(--sidebar-bg, #111b21); }

/* Pannello del centro notifiche (dentro la modale) */
.cn-riga {
  display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px;
  border: 1px solid var(--border); border-radius: 10px; margin-bottom: 8px;
  cursor: pointer; background: var(--surface); color: var(--text);
  transition: border-color .12s, background .12s;
}
.cn-riga:hover { border-color: var(--accent-vivo); background: var(--surface-hover); }
.cn-riga.grave { border-left: 4px solid #e5534b; }
.cn-riga.avviso { border-left: 4px solid #d6a441; }
.cn-ico { font-size: 18px; flex-shrink: 0; margin-top: 1px; }
.cn-corpo { flex: 1; min-width: 0; }
.cn-tit { font-weight: 600; font-size: 14px; color: var(--text); }
.cn-tit .cn-grave { color: #e5534b; font-size: 11px; font-weight: 700; margin-left: 6px; }
.cn-meta { color: var(--text-3); font-size: 12.5px; margin-top: 2px; }
.cn-msg { color: var(--text-2); font-size: 13px; margin-top: 3px; word-break: break-word; }
.cn-quando { color: var(--text-3); font-size: 11.5px; white-space: nowrap; flex-shrink: 0; }
.cn-sez { font-size: 12px; text-transform: uppercase; letter-spacing: .5px; color: var(--text-3); margin: 14px 0 8px; }
.cn-vuoto { text-align: center; color: var(--text-3); padding: 24px 0; }

/* Tasto "ricollega la chat" nella barra del desktop: gira mentre ricarica. */
#desk-chat-ric.gira { animation: deskRicGira 0.6s linear; }
@keyframes deskRicGira { from { transform: rotate(0); } to { transform: rotate(360deg); } }

/* Accesso con biglietto del gestionale (18/10/2026): si vede solo la scheda
   del computer del biglietto; menu, campanella, altre schede e pulsanti del
   cliente spariscono. Il server li rifiuta comunque (middleware/auth.js). */
body.accesso-biglietto .page:not(#page-client-detail),
body.accesso-biglietto .sidebar-nav,
body.accesso-biglietto .campana,
body.accesso-biglietto:not(.biglietto-completo) .rip-drawer-tab,
body.accesso-biglietto:not(.biglietto-completo) .rip-drawer,
body.accesso-biglietto .client-hero-top > .btn,
body.accesso-biglietto #client-tabs,
body.accesso-biglietto .ctab-panel:not(#ctab-computer) { display: none !important; }
.biglietto-avviso {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  background: var(--warning-debole); border: 1px solid var(--warning); border-radius: 8px;
  padding: 10px 14px; margin-bottom: 12px; font-size: var(--t-sm);
}
.biglietto-avviso .btn { margin-left: auto; }
