/* ────────────────────────────────────────────────────────────────────────────
   ROBOTO OSPITATO IN LOCALE
   Prima veniva da fonts.googleapis.com: una richiesta esterna che blocca il
   rendering, quindi su connessione lenta o con la rete del cliente che filtra
   i domini Google la pagina restava bianca ad aspettare.
   I file stanno in wwwroot/fonts e vengono pubblicati con l'app.
   Roboto v51 e' un font VARIABILE: un solo file copre tutti i pesi, per questo
   c'e' una regola per subset (non una per peso) con font-weight come intervallo.
   Roboto e' Apache License 2.0, quindi l'auto-hosting e' consentito.
   Subset: solo latin e latin-ext (accenti europei). Cirillico, greco, vietnamita
   e simboli non servono e sarebbero 7 file in piu' per subset.
   ──────────────────────────────────────────────────────────────────────────── */

@font-face {
    font-family: 'Roboto';
    font-style: normal;
    font-weight: 100 900;
    font-stretch: 100%;
    font-display: swap;
    src: url('fonts/roboto-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Roboto';
    font-style: normal;
    font-weight: 100 900;
    font-stretch: 100%;
    font-display: swap;
    src: url('fonts/roboto-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

html {
    /* Riserva sempre lo spazio della barra di scorrimento verticale. Senza, ogni volta che il
       contenuto passa sopra/sotto l'altezza della finestra (tipico cambiando tastone nei ticket)
       la barra compare o sparisce e l'intera pagina slitta di ~15px in orizzontale. */
    scrollbar-gutter: stable;
}

html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;

}
.gantt-header-fixed {
    position: fixed;
    top: var(--mud-appbar-height);
    left: var(--mud-drawer-width);
    right: 0;
    z-index: 1000;
    background: white;
}


.gantt-body-offset {
    margin-top: calc(var(--mud-appbar-height) + 110px);
}
 




.login-overlay {
    position: fixed;
    inset: 0;
    background: rgba(255,255,255,0.8);
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
}

.page-transition {
    animation: pageFade 1.5s cubic-bezier(0.4, 0, 0.2, 1) forwards; 
}


@keyframes pageFade {
    from {
        opacity: 0;
        transform: translateY(15px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.page-slide {
    animation: slideIn 0.9s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateX(60px);
    }

    to {
        opacity: 1;
        transform: translateX(0);
    }
}

.page-slide-left {
    animation: slideLeftIn 0.9s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

@keyframes slideLeftIn {
    from {
        opacity: 0;
        transform: translateX(-60px);
    }

    to {
        opacity: 1;
        transform: translateX(0);
    }
}

 
.page-fade-blur {
    animation: fadeBlur 1s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

@keyframes fadeBlur {
    from {
        opacity: 0;
        filter: blur(10px);
    } 
 
    to {
        opacity: 1;
        filter: blur(0);
    }
}

.page-rotate {
    animation: rotateIn 0.9s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

@keyframes rotateIn {
    from {
        opacity: 0;
        transform: rotate(-8deg) translateY(10px);
    }

    to {
        opacity: 1;
        transform: rotate(0) translateY(0);
    }
}
/* Transizione combinata fade + slide */
.page-smooth {
    animation: smoothIn 1s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

@keyframes smoothIn {
    from {
        opacity: 0;
        transform: translateX(40px) translateY(15px) scale(0.95);
    }

    50% {
        opacity: 0.6;
        transform: translateX(20px) translateY(8px) scale(0.975);
    }

    to {
        opacity: 1;
        transform: translateX(0) translateY(0) scale(1);
    }
}

/* Variante slide + fade da sinistra */
.page-smooth-left {
    animation: smoothLeftIn 1s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

@keyframes smoothLeftIn {
    from {
        opacity: 0;
        transform: translateX(-40px) translateY(15px) scale(0.95);
    }

    50% {
        opacity: 0.6;
        transform: translateX(-20px) translateY(8px) scale(0.975);
    }

    to {
        opacity: 1;
        transform: translateX(0) translateY(0) scale(1);
    }
}

/* Variante con leggero blur */
.page-smooth-blur {
    animation: smoothBlurIn 1s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

@keyframes smoothBlurIn {
    from {
        opacity: 0;
        filter: blur(8px);
        transform: translateY(15px) scale(0.95);
    }

    50% {
        opacity: 0.6;
        filter: blur(4px);
        transform: translateY(8px) scale(0.975);
    }

    to {
        opacity: 1;
        filter: blur(0);
        transform: translateY(0) scale(1);
    }
}
.page-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(255,255,255,0.15);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    z-index: 5000;
    opacity: 1;
    pointer-events: all;
    transition: opacity 0.6s cubic-bezier(0.4,0,0.2,1);
}

    .page-overlay.hidden {
        opacity: 0;
        pointer-events: none;
    }

.page-zoom {
    animation: zoomIn 0.9s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

@keyframes zoomIn {
    from {
        opacity: 0;
        transform: scale(0.85);
    }

    to {
        opacity: 1;
        transform: scale(1);
    }
}
 


body {
    background-image: url('img/background/background-wawe.webp');
    background-size: cover; /* Adatta l'immagine alla finestra */
    background-position: center;
    background-repeat: no-repeat;
    background-attachment: fixed; /* Mantiene l'immagine fissa allo scrolling */
}

.mud-snackbar {
    z-index: 9500 !important;
}

.mud-dialog {
    z-index: 3500 !important; /* Default � circa 2000 */
}

.mic-pulse {
    animation: mic-blink 1.2s infinite;
    color: #ff5252; /* puoi cambiarlo per adattarlo al tuo tema */
}

.col-piccola {
    width: 90px;
    min-width: 80px;
    max-width: 180px;
    white-space: normal;
   /* word-break: break-word;*/
    text-align: left;
}

 

@keyframes mic-blink {
    0%, 100% {
        opacity: 1;
        transform: scale(1);
    }

    50% {
        opacity: 0.5;
        transform: scale(1.2);
    }
}

.my-dialog-background {
    background-color: rgba(0,0,0,0.7); /* sfondo scuro semi-trasparente */
}

.my-dialog-content {
    border-radius: 16px;
    padding: 24px;
    background-color: #fff;
    min-height: 90vh; /* come volevi tu */
    display: flex;
    flex-direction: column;
}


.wave-container {
    display: flex;
    justify-content: center; /* centra orizzontalmente */
    align-items: center; /* centra verticalmente */
    height: 86px;
    width: 100%;
    background-color: #263238;
    border-radius: 6px;
    padding: 10px;
    gap: 6px;
    color: #ECEFF1;
    box-sizing: border-box;
}


.wave {
    width: 6px;
    height: 40%;
    background: #ECEFF1;
    animation: wave-animation 1s infinite ease-in-out;
    border-radius: 3px;
}

    .wave:nth-child(1) {
        animation-delay: 0s;
    }

    .wave:nth-child(2) {
        animation-delay: 0.2s;
    }

    .wave:nth-child(3) {
        animation-delay: 0.4s;
    }

    .wave:nth-child(4) {
        animation-delay: 0.6s;
    }

    .wave:nth-child(5) {
        animation-delay: 0.8s;
    }

@keyframes wave-animation {
    0%, 100% {
        height: 20%;
    }

    50% {
        height: 100%;
    }
}
 

.mud-chip > .mud-chip-content {
    align-items: normal !important;
    /*display: inline-flex !important;*/
    /*height: 100% !important;*/
    max-width: 100% !important;
    white-space: normal !important;
    word-break: break-word;
    text-align: left;
}

/* Questo funziona davvero su MudBlazor */
.mud-calendar-hour {
    height: 30px !important;
    min-height: 30px !important;
}
/* Calendario su telefono: la toolbar esterna va a capo senza allargare la pagina; le viste con
   più giorni mantengono colonne leggibili e scorrono orizzontalmente dentro il solo calendario. */
.gaia-calendario-toolbar,
.gaia-calendario-toolbar-filtri,
.gaia-calendario-toolbar-stato,
.gaia-calendario-operatore,
.gaia-calendario-scroll {
    min-width: 0;
}

.gaia-calendario-ricerca {
    width: 300px;
    max-width: 100%;
    min-width: 0;
}

.gaia-calendario-scroll {
    width: 100%;
    max-width: 100%;
    overflow-x: hidden;
}

/* Gestione Azienda: l'opzione raggiunta dalla ricerca lampeggia per un paio di secondi.
   Serve perche' dopo il cambio di scheda il campo e' uno fra decine uguali: senza l'evidenziazione
   si perde comunque tempo a cercarlo con gli occhi. */
.gaia-opzione-trovata {
    border-radius: 6px;
    animation: gaia-opzione-lampeggio 2.4s ease-out;
}

@keyframes gaia-opzione-lampeggio {
    0%, 65% {
        box-shadow: 0 0 0 3px var(--mud-palette-primary);
        background-color: var(--mud-palette-primary-hover);
    }

    100% {
        box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
        background-color: transparent;
    }
}

.gaia-calendario-operatori-lista {
    max-height: 744px;
    overflow-y: auto;
}

/* Elementi del drawer usati soltanto su telefono: sul desktop la sidebar mantiene esattamente
   il layout esistente e il wrapper non introduce una nuova box. */
.gaia-calendario-operatori-backdrop,
.gaia-calendario-operatori-drawer-header {
    display: none;
}

.gaia-calendario-operatori-drawer-contenuto {
    display: contents;
}

@media (max-width: 600px) {
    /* Intestazioni di pagina lunghe: su telefono restano su una riga senza alterare il desktop. */
    .gaia-page-title-mobile {
        min-width: 0;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: 1rem !important;
        line-height: 1.25 !important;
    }

    .gaia-page-title-mobile > .mud-icon-root {
        font-size: 1.35rem !important;
        margin-right: 4px !important;
    }

    .gaia-calendario-toolbar {
        width: 100%;
        flex-direction: column !important;
        align-items: stretch !important;
        gap: 8px;
    }

    .gaia-calendario-toolbar-filtri {
        width: 100%;
        flex-wrap: wrap !important;
        gap: 8px;
    }

    /* Il campo di ricerca deve prendere lo spazio che AVANZA, cosi' la fila "icona altri calendari
       + ricerca + tre puntini" resta UNA. Attenzione al bersaglio: gaia-calendario-ricerca sta sul
       .mud-input-control INTERNO, mentre il figlio della fila e' il .mud-autocomplete che lo
       contiene. Finche' la regola stava solo sull'elemento interno, il figlio vero restava a
       flex:1 1 auto, cioe' largo quanto il suo contenuto (299px misurati), e i tre puntini
       venivano spinti a capo. La regola va quindi su ENTRAMBI. */
    .gaia-calendario-toolbar-filtri > .mud-autocomplete {
        flex: 1 1 0;
        min-width: 120px;
    }

    .gaia-calendario-ricerca {
        width: auto !important;
        min-width: 120px;
        flex: 1 1 0;
    }

    .gaia-calendario-toolbar-stato {
        width: 100%;
        justify-content: flex-end !important;
    }

    .gaia-calendario-griglia,
    .gaia-calendario-contenuto,
    .gaia-calendario-intestazione {
        width: 100% !important;
        max-width: 100% !important;
        box-sizing: border-box;
        margin-left: 0 !important;
        margin-right: 0 !important;
    }

    /* MudGrid compensa normalmente il padding sinistro dei MudItem con un margine negativo.
       Avendo azzerato quel margine per evitare overflow, va azzerato anche il gutter: altrimenti
       tutto il calendario resta spostato a destra della stessa misura. */
    .gaia-calendario-griglia > .mud-grid-item,
    .gaia-calendario-contenuto > .mud-grid-item,
    .gaia-calendario-intestazione > .mud-grid-item {
        padding-left: 0 !important;
    }

    .gaia-calendario-operatori-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 1399;
        background: rgba(0, 0, 0, .38);
        touch-action: none;
    }

    .gaia-calendario-operatori-drawer {
        position: fixed !important;
        top: 0;
        right: 0;
        bottom: 0;
        left: auto;
        z-index: 1400;
        display: flex;
        flex-direction: column;
        width: min(88vw, 360px) !important;
        max-width: min(88vw, 360px) !important;
        height: 100vh;
        height: 100dvh;
        padding: 0 !important;
        background: var(--mud-palette-surface);
        box-shadow: var(--mud-elevation-16);
        overflow: hidden;
    }

    .gaia-calendario-operatori-drawer-header {
        display: flex;
        flex: 0 0 auto;
        align-items: center;
        justify-content: space-between;
        min-height: 56px;
        padding: 8px 10px 8px 16px;
        border-bottom: 1px solid var(--mud-palette-lines-default);
        background: var(--mud-palette-surface);
    }

    .gaia-calendario-operatori-drawer-contenuto {
        display: block;
        flex: 1 1 auto;
        min-height: 0;
        overflow: hidden;
    }

    .gaia-calendario-operatori-lista {
        height: 100%;
        max-height: none;
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
    }

    .gaia-calendario-scroll {
        overflow-x: auto;
        overscroll-behavior-x: contain;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: thin;
    }

    /* Settimana INTERA nello schermo: sette giornate piccole, nessuno scorrimento laterale.
       Prima erano fissi 680px, cioe' quasi il doppio dello schermo: si vedevano tre giorni e
       mezzo e gli altri si raggiungevano solo scorrendo di lato, senza che niente lo suggerisse.
       Chi vuole le giornate grandi accende "Settimana di 3 giorni" nel menu a tre puntini. */
    .gaia-calendario-largo .mud-calendar {
        min-width: 0;
    }

    /* "Settimana di 3 giorni" (menu tre puntini del calendario, solo telefono).
       Le colonne restano sette - Heron.MudCalendar 4.0 non sa disegnarne meno - ma diventano
       larghe un terzo di schermo l'una: se ne vedono tre per volta e si scorre di lato per le
       altre, come fa Outlook sul telefono.
       Lo scorrimento si aggancia alle colonne (scroll-snap), cosi' ci si sposta di giornata in
       giornata e non ci si ferma mai a meta' di una casella.
       Il conto: 56px di colonna orari + sette giornate larghe un terzo dello spazio utile. */
    .gaia-calendario-3giorni .mud-calendar {
        min-width: calc(56px + (100vw - 56px - 40px) / 3 * 7);
    }

    .gaia-calendario-3giorni {
        scroll-snap-type: x proximity;
    }

    .gaia-calendario-3giorni .mud-cal-grid > * {
        scroll-snap-align: start;
    }
}


.blinking-icon {
    animation: blinker 1s linear infinite;
}

@keyframes blinker {
    0%, 100% {
        opacity: 1;
    }

    50% {
        opacity: 0;
    }
}
/* ────────────────────────────────────────────────────────────────────────────
   TEMA "VETRO" (traslucido, stile chatbot GaIA)
   Attivato dalla classe gaia-vetro sul body (MainLayout -> setTemaVetro),
   solo per i temi con "Vetro": true in wwwroot/temi/temi.json.
   Le superfici diventano semitrasparenti e sfocano lo sfondo sottostante.
   ──────────────────────────────────────────────────────────────────────────── */

body.gaia-vetro {
    background-attachment: fixed;
    background-size: cover;
}

/* superfici principali: carte, pannelli, dialoghi, menu a tendina */
body.gaia-vetro .mud-paper,
body.gaia-vetro .mud-card,
body.gaia-vetro .mud-dialog,
body.gaia-vetro .mud-popover-cascading-value,
body.gaia-vetro .mud-expand-panel {
    background-color: rgba(255, 255, 255, 0.62) !important;
    backdrop-filter: blur(14px) saturate(140%);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 14px;
    box-shadow: 0 8px 24px rgba(15, 40, 80, 0.10);
}

/* barra in alto e menu laterale: piu' scuri, come l'header del bot */
body.gaia-vetro .mud-appbar,
body.gaia-vetro .mud-drawer {
    background-color: rgba(25, 118, 210, 0.72) !important;
    backdrop-filter: blur(16px) saturate(140%);
    -webkit-backdrop-filter: blur(16px) saturate(140%);
    border-right: 1px solid rgba(255, 255, 255, 0.12);
    box-shadow: 0 4px 18px rgba(10, 30, 60, 0.18);
}

/* le tabelle stanno gia' dentro una MudPaper: evito il doppio velo opaco */
body.gaia-vetro .mud-table,
body.gaia-vetro .mud-table-container,
body.gaia-vetro .mud-toolbar,
body.gaia-vetro .mud-expand-panel .mud-expand-panel-header {
    background-color: transparent !important;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
    border: none;
}

/* intestazione colonne e righe alternate: leggibili sopra il vetro */
body.gaia-vetro .mud-table-head .mud-table-cell {
    background-color: rgba(255, 255, 255, 0.55) !important;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}

body.gaia-vetro .mud-table-row:hover:not(.mud-table-no-hover) {
    background-color: rgba(25, 118, 210, 0.08) !important;
}

/* ── variante scura ── */
body.gaia-vetro.mud-theme-dark .mud-paper,
body.gaia-vetro.mud-theme-dark .mud-card,
body.gaia-vetro.mud-theme-dark .mud-dialog,
body.gaia-vetro.mud-theme-dark .mud-expand-panel {
    background-color: rgba(16, 27, 48, 0.58) !important;
    border: 1px solid rgba(255, 255, 255, 0.10);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}

body.gaia-vetro.mud-theme-dark .mud-appbar,
body.gaia-vetro.mud-theme-dark .mud-drawer {
    background-color: rgba(10, 27, 51, 0.75) !important;
}

body.gaia-vetro.mud-theme-dark .mud-table-head .mud-table-cell {
    background-color: rgba(16, 27, 48, 0.55) !important;
}

body.gaia-vetro.mud-theme-dark .mud-table-row:hover:not(.mud-table-no-hover) {
    background-color: rgba(79, 195, 247, 0.10) !important;
}

/* niente sfocatura per chi la disattiva a livello di sistema (o su GPU deboli):
   resta un fondo solido leggibile invece di un pannello semitrasparente illeggibile */
@media (prefers-reduced-transparency: reduce) {
    body.gaia-vetro .mud-paper,
    body.gaia-vetro .mud-card,
    body.gaia-vetro .mud-dialog,
    body.gaia-vetro .mud-expand-panel {
        background-color: var(--mud-palette-surface) !important;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }
}

/* ────────────────────────────────────────────────────────────────────────────
   TICKET - FASCIA "COMMENTO INTERNO"
   Marca in modo inequivocabile i commenti che il cliente NON vede: sia quelli
   gia' inseriti (dentro la bolla della chat) sia quello che si sta scrivendo
   con la spunta "Commento interno" attiva.
   Colori fissi (giallo avviso) invece delle variabili di tema: e' una fascia di
   allerta e deve restare riconoscibile con qualsiasi tema, chiaro o scuro.
   ──────────────────────────────────────────────────────────────────────────── */

.tk-fascia-interno {
    display: flex;
    align-items: center;
    gap: 4px;
    background: repeating-linear-gradient(
        45deg,
        #FFD54F,
        #FFD54F 10px,
        #FFCA28 10px,
        #FFCA28 20px
    );
    color: #4E342E;
    font-weight: 700;
    font-size: 0.78rem;
    letter-spacing: .04em;
    line-height: 1.2;
    padding: 6px 10px;
    margin-bottom: 8px;
    border-left: 5px solid #F57F17;
    border-radius: 4px;
    text-transform: uppercase;
}

/* l'icona eredita il colore scuro del testo, non quello del tema */
.tk-fascia-interno .mud-icon-root {
    color: #4E342E;
}

/* variante sopra l'editor: piu' larga e staccata, si vede mentre si scrive */
.tk-fascia-interno-editor {
    margin: 8px 0;
    padding: 8px 12px;
    font-size: 0.82rem;
    box-shadow: 0 2px 6px rgba(0, 0, 0, .15);
}

/* ────────────────────────────────────────────────────────────────────────────
   TICKET - ATTESA RISPOSTA IA
   Compare in cima ai commenti mentre l'assistente sta rispondendo: la domanda
   e' gia' stata registrata, quindi l'utente puo' andare avanti a lavorare.
   ──────────────────────────────────────────────────────────────────────────── */

.tk-ia-attesa {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px;
    background: var(--mud-palette-primary-hover, rgba(25, 118, 210, .08));
    border: 1px dashed var(--mud-palette-primary, #1976D2);
    color: var(--mud-palette-text-primary);
    border-radius: 8px;
    padding: 8px 12px;
    margin-bottom: 12px;
    font-size: .9rem;
}

.tk-ia-attesa-nota {
    margin-left: 6px;
    font-size: .8rem;
    opacity: .75;
}

/* puntini che pulsano uno dopo l'altro */
.tk-ia-puntini span {
    animation: tk-ia-blink 1.4s infinite both;
    font-weight: 700;
}

.tk-ia-puntini span:nth-child(2) {
    animation-delay: .2s;
}

.tk-ia-puntini span:nth-child(3) {
    animation-delay: .4s;
}

@keyframes tk-ia-blink {
    0%, 80%, 100% {
        opacity: .2;
    }
    40% {
        opacity: 1;
    }
}

/* ── Bianco "ceramica" più riposante per i Paper/Card (modalità "sfondo soft") ──
   MudBlazor colora Paper e Card con var(--mud-palette-surface) (in chiaro = bianco pieno).
   Ridefinendo la variabile a livello di body, tutti i Paper/Card ereditano un bianco panna
   più morbido, senza !important: gli sfondi inline (Style="background:...") continuano a
   vincere dove servono.
   È una PREFERENZA PER-UTENTE: la classe .gaia-sfondo-soft viene messa sul body solo se
   l'utente attiva "Sfondo soft" nel profilo (default off). In DARK la classe NON viene
   proprio applicata (lo decide MainLayout in C#, perche' in questa app il dark non aggiunge
   una classe sul body su cui poter fare leva in CSS). I temi che forzano il proprio sfondo
   con !important (es. "vetro") restano comunque invariati. */
body.gaia-sfondo-soft {
    --mud-palette-surface: #f6f4ef;
}

/* ────────────────────────────────────────────────────────────────────────────
   TICKET - COMPARSA DELLE GRIGLIE SENZA SCATTI
   Obiettivo dichiarato: STABILITA' VISIVA. I tecnici stanno su questa pagina
   otto ore e cambiano tastone (APERTI, TUTTI...) di continuo: ogni movimento
   inutile si accumula in affaticamento e nausea. Quindi non basta "mettere uno
   spinner", vanno tolti i movimenti. Tre accorgimenti, in ordine di importanza:

   1) NIENTE RIASSETTO A VIDEO. MudDataGrid calcola le larghezze delle colonne
      dopo il primo paint: quel riassetto era lo "scatto". Le griglie vengono
      renderizzate subito ma a opacita' 0 - restano nel flusso, quindi il
      browser le misura - e compaiono solo a layout assestato.
      Serve opacity: con display:none o visibility:hidden il contenuto non
      verrebbe misurato e lo scatto si ripresenterebbe alla comparsa.

   2) NIENTE COLLASSO DELL'AREA. L'attesa e' un overlay in posizione assoluta
      sopra l'area, non un blocco che prende il posto delle griglie: l'altezza
      della pagina non cambia, quindi non si muove nulla sotto e la posizione
      di scorrimento resta dov'e'.

   3) NIENTE LAMPO DELLO SPINNER. L'indicatore resta invisibile per i primi
      250ms: se il cambio tastone e' rapido (caso normale, i dati sono in RAM)
      non compare affatto e la griglia si sostituisce senza che l'occhio veda
      alcuna transizione. Compare solo quando l'attesa e' davvero percepibile.
   ──────────────────────────────────────────────────────────────────────────── */

.tk-griglie-area {
    position: relative;
    /* riserva spazio mentre si cambia contenuto, cosi' l'area non collassa */
    min-height: 240px;
}

.tk-griglie {
    /* dissolvenza breve e senza movimento: nessuno spostamento, solo opacita' */
    transition: opacity .15s ease-in;
}

.tk-griglie-nascoste {
    opacity: 0;
    pointer-events: none;
    /* sparizione istantanea: la dissolvenza serve solo in comparsa, farla anche in uscita
       raddoppierebbe il movimento a ogni cambio tastone */
    transition: none;
}

.tk-griglie-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* ancorato in alto, NON centrato: l'area conserva l'altezza piena delle griglie anche mentre
       sono invisibili (e' il senso di usare opacity), quindi con elenchi lunghi un indicatore
       centrato verticalmente finirebbe fuori schermo. */
    justify-content: flex-start;
    padding-top: 64px;
    gap: 8px;
    /* invisibile per i primi 250ms: le attese brevi non producono alcun lampo */
    opacity: 0;
    animation: tk-mostra-attesa 0s linear 250ms forwards;
}

@keyframes tk-mostra-attesa {
    to {
        opacity: 1;
    }
}

/* ── Dettaglio ticket (AddTicket): stessa tecnica dell'area griglie ──
   min-height allineata a quella della MudPaper interna del form, cosi' l'area non collassa
   mentre si passa dallo scheletro al form vero. */
.tk-area-form {
    position: relative;
    min-height: 700px;
}

/* Qui lo scheletro NON e' ritardato: aprire un ticket comporta sempre un'attesa percepibile,
   quindi mostrarlo subito e' informativo, non un lampo. Parte dall'alto, non centrato,
   perche' deve ricalcare la forma del contenuto che sta arrivando. */
.tk-overlay-form {
    position: absolute;
    inset: 0;
    overflow: hidden;
}

/* AddTicket: la testata conserva la stessa altezza mentre arrivano i dati del cliente.
   Evita che toolbar e corpo vengano spinti in basso al termine del caricamento. */
.tk-ticket-intestazione-stabile {
    min-height: 96px;
}

/* L'unico indicatore del dettaglio e' una barra lineare sovrapposta: non occupando
   spazio nel flusso, la sua rimozione non provoca un ulteriore salto verticale. */
.tk-caricamento-ticket {
    z-index: 1;
    padding: 16px 24px 0;
    pointer-events: none;
}

@media (max-width: 1279.98px) {
    .tk-ticket-intestazione-stabile {
        min-height: 132px;
    }
}

/* chi ha chiesto di ridurre le animazioni non vede nemmeno la dissolvenza */
@media (prefers-reduced-motion: reduce) {
    .tk-griglie {
        transition: none;
    }
}

/* Preferenza per-utente "effetto dissolvenza" (profilo -> mondo ticket), default ATTIVO.
   La classe sul body e' in negativo, quindi senza preferenza applicata il comportamento resta
   quello di prima. Disattivandola il contenuto compare di colpo: sparisce l'effetto grafico, NON
   la comparsa a layout assestato, quindi non tornano gli scatti delle colonne.
   Vale sia per le griglie (TicketsComponent) sia per il dettaglio (AddTicket): usano la stessa classe. */
body.gaia-ticket-no-fade .tk-griglie {
    transition: none;
}


/* ============================================================================
   COMPARSA IN DISSOLVENZA DI AREE COMPOSITE (Controls/Generic/GaiaFadeInComp.razor)

   Stessa tecnica di .tk-griglie-* del mondo ticket, ma per aree fatte di piu'
   componenti che si assestano in tempi diversi: oggi la home (Gantt + Rapportini,
   oppure Calendario). Il contenuto sta nel DOM da subito ma a opacita' 0, cosi'
   il riassetto di griglie e calendario avviene nascosto e non si vedono i salti.
   ============================================================================ */

.gaia-fade-area {
    position: relative;
}

.gaia-fade-contenuto {
    /* dissolvenza breve e senza movimento: nessuno spostamento, solo opacita' */
    transition: opacity .2s ease-in;
}

.gaia-fade-nascosto {
    opacity: 0;
    pointer-events: none;
    /* la dissolvenza serve solo in comparsa: in uscita sarebbe movimento in piu' */
    transition: none;
}

.gaia-fade-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* ancorato in alto come nei ticket: l'area conserva l'altezza piena del contenuto anche
       mentre e' invisibile, quindi un indicatore centrato finirebbe fuori schermo */
    justify-content: flex-start;
    padding-top: 64px;
    gap: 8px;
    /* invisibile per i primi 250ms: le attese brevi non producono alcun lampo */
    opacity: 0;
    animation: tk-mostra-attesa 0s linear 250ms forwards;
}

/* chi ha chiesto di ridurre le animazioni non vede nemmeno la dissolvenza */
@media (prefers-reduced-motion: reduce) {
    .gaia-fade-contenuto {
        transition: none;
    }
}

/* Stessa preferenza per-utente delle griglie ticket (profilo -> effetto dissolvenza): una sola
   opzione governa entrambe le cose, cosi' non serve una seconda impostazione da salvare.
   Disattivandola il contenuto compare di colpo: sparisce l'effetto grafico, NON la comparsa a
   layout assestato, quindi non tornano i salti. */
body.gaia-ticket-no-fade .gaia-fade-contenuto {
    transition: none;
}

/* ============================================================================
   CHAT (GaiaChat / GaiaChatHeader / GaiaChatBubble / GaiaChatFooter)

   MudBlazor 9 ha rimosso i componenti chat E il loro CSS. Queste regole sono quelle
   della 8.13 (prefisso mud-chat rinominato in gaia-chat) e servono ai componenti
   in Components/Controls/Messaggi/GaiaChat*.razor che li rimpiazzano.
   Usano le variabili --mud-palette-*, quindi seguono il tema come prima.
   ============================================================================ */
.gaia-chat {display:grid;column-gap:.75rem;padding-top:.25rem;padding-bottom:.25rem;border-radius:var(--mud-default-borderradius)}
.gaia-chat.gaia-chat-dense .gaia-chat-bubble {padding:.1875rem 1rem;min-height:.9166666667rem}
.gaia-chat.gaia-chat-dense .gaia-chat-bubble+.gaia-chat-bubble {margin-top:.1875rem}
.gaia-chat.gaia-chat-dense .gaia-chat-header {line-height:.4166666667rem}
.gaia-chat.gaia-chat-square {border-radius:0px}
.gaia-chat.gaia-chat-square .gaia-chat-bubble {border-radius:0px}
.gaia-chat.gaia-chat-arrow-top .gaia-chat-bubble:before {content:"";mask-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0nMycgaGVpZ2h0PSczJyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnPjxwYXRoIGZpbGw9J2JsYWNrJyBkPSdtIDAgMCBMIDMgMCBMIDMgMyBDIDMgMiAxIDAgMCAwJy8+PC9zdmc+);bottom:auto;top:0}
.gaia-chat.gaia-chat-arrow-top.gaia-chat-start .gaia-chat-bubble:before,.gaia-chat.gaia-chat-arrow-top.gaia-chat-end.gaia-chat-rtl .gaia-chat-bubble:before {transform:none}
.gaia-chat.gaia-chat-arrow-top.gaia-chat-end .gaia-chat-bubble:before,.gaia-chat.gaia-chat-arrow-top.gaia-chat-start.gaia-chat-rtl .gaia-chat-bubble:before {transform:scaleX(-1)}
.gaia-chat.gaia-chat-arrow-top.gaia-chat-start .gaia-chat-bubble,.gaia-chat.gaia-chat-arrow-top.gaia-chat-end.gaia-chat-rtl .gaia-chat-bubble {border-top-left-radius:0}
.gaia-chat.gaia-chat-arrow-top.gaia-chat-end .gaia-chat-bubble,.gaia-chat.gaia-chat-arrow-top.gaia-chat-start.gaia-chat-rtl .gaia-chat-bubble {border-top-right-radius:0}
.gaia-chat.gaia-chat-arrow-bottom .gaia-chat-bubble:before {content:"";mask-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0nMycgaGVpZ2h0PSczJyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnPjxwYXRoIGZpbGw9J2JsYWNrJyBkPSdtIDAgMyBMIDMgMyBMIDMgMCBDIDMgMSAxIDMgMCAzJy8+PC9zdmc+);bottom:0}
.gaia-chat.gaia-chat-arrow-bottom.gaia-chat-start .gaia-chat-bubble:before,.gaia-chat.gaia-chat-arrow-bottom.gaia-chat-end.gaia-chat-rtl .gaia-chat-bubble:before {transform:none}
.gaia-chat.gaia-chat-arrow-bottom.gaia-chat-end .gaia-chat-bubble:before,.gaia-chat.gaia-chat-arrow-bottom.gaia-chat-start.gaia-chat-rtl .gaia-chat-bubble:before {transform:scaleX(-1)}
.gaia-chat.gaia-chat-arrow-bottom.gaia-chat-start .gaia-chat-bubble,.gaia-chat.gaia-chat-arrow-bottom.gaia-chat-end.gaia-chat-rtl .gaia-chat-bubble {border-bottom-left-radius:0}
.gaia-chat.gaia-chat-arrow-bottom.gaia-chat-end .gaia-chat-bubble,.gaia-chat.gaia-chat-arrow-bottom.gaia-chat-start.gaia-chat-rtl .gaia-chat-bubble {border-bottom-right-radius:0}
.gaia-chat.gaia-chat-arrow-middle .gaia-chat-bubble:before {content:"";mask-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzIDMiIHdpZHRoPSIzMDAiIGhlaWdodD0iMzAwIj4KICA8cG9seWdvbiBwb2ludHM9IjMsMCAzLDMgMS41LDEuNSIgZmlsbD0iYmxhY2siIC8+Cjwvc3ZnPg==);top:50%}
.gaia-chat.gaia-chat-arrow-middle.gaia-chat-start .gaia-chat-bubble:before,.gaia-chat.gaia-chat-arrow-middle.gaia-chat-end.gaia-chat-rtl .gaia-chat-bubble:before {transform:translateY(-50%)}
.gaia-chat.gaia-chat-arrow-middle.gaia-chat-end .gaia-chat-bubble:before,.gaia-chat.gaia-chat-arrow-middle.gaia-chat-start.gaia-chat-rtl .gaia-chat-bubble:before {transform:scaleX(-1) translateY(-50%)}
.gaia-chat-bubble {position:relative;text-align:start;align-content:center;width:fit-content;padding:.5rem 1rem;max-width:90%;border-radius:var(--mud-default-borderradius);min-width:2.75rem;min-height:2.75rem}
.gaia-chat-bubble.gaia-chat-bubble-clickable {cursor:pointer;user-select:none;-webkit-appearance:none;-webkit-tap-highlight-color:rgba(0,0,0,0);transition:background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;--mud-ripple-color: var(--mud-palette-text-primary);--mud-ripple-opacity: var(--mud-ripple-opacity-secondary) !important}
.gaia-chat-bubble.gaia-chat-bubble-clickable:hover {box-shadow:0px 2px 4px -1px rgba(0,0,0,.2),0px 4px 5px 0px rgba(0,0,0,.14),0px 1px 10px 0px rgba(0,0,0,.12);background-color:var(--mud-palette-action-disabled-background)}
.gaia-chat-bubble.gaia-chat-bubble-clickable:focus-visible {box-shadow:0px 2px 4px -1px rgba(0,0,0,.2),0px 4px 5px 0px rgba(0,0,0,.14),0px 1px 10px 0px rgba(0,0,0,.12);background-color:var(--mud-palette-action-disabled-background)}
.gaia-chat-bubble.gaia-chat-bubble-clickable:active {box-shadow:0px 5px 5px -3px rgba(0,0,0,.2),0px 8px 10px 1px rgba(0,0,0,.14),0px 3px 14px 2px rgba(0,0,0,.12);background-color:var(--mud-palette-action-disabled-background)}
.gaia-chat-bubble:before {position:absolute;width:.75rem;height:.75rem;background-color:inherit;mask-size:contain;mask-repeat:no-repeat;mask-position:center}
.gaia-chat-bubble+.gaia-chat-bubble {margin-top:.5rem}
.gaia-chat-bubble+.gaia-chat-bubble:before {content:none !important}
.gaia-chat-header {grid-row-start:1;font-size:.875rem;line-height:1.25rem;margin-left:.25rem;margin-right:.25rem;min-height:.5rem}
.gaia-chat-header time {margin-left:.5rem;opacity:.5;font-size:.75rem;line-height:1rem}
.gaia-chat-footer {opacity:.5;font-size:.875rem;line-height:1rem;margin-left:.25rem;margin-right:.25rem;min-height:.5rem}
.gaia-chat .mud-avatar {align-self:center;grid-row-start:1}
.gaia-chat:has(.gaia-chat-header) .mud-avatar {grid-row-start:2}
.gaia-chat-start {place-items:start;grid-template-columns:1fr 99fr}
.gaia-chat-start .gaia-chat-header,.gaia-chat-start .gaia-chat-footer {grid-column-start:2}
.gaia-chat-start .mud-avatar {grid-column-start:1;margin-left:.25rem;margin-right:-0.35rem}
.gaia-chat-start .gaia-chat-bubble {grid-column-start:2}
.gaia-chat-start .gaia-chat-bubble:before {inset-inline-start:-0.749rem}
.gaia-chat-end {place-items:end;grid-template-columns:99fr 1fr}
.gaia-chat-end .gaia-chat-header,.gaia-chat-end .gaia-chat-footer {grid-column-start:1}
.gaia-chat-end .mud-avatar {grid-column-start:2;margin-right:.25rem;margin-left:-0.35rem}
.gaia-chat-end .gaia-chat-bubble {grid-column-start:1;text-align:end}
.gaia-chat-end .gaia-chat-bubble:before {inset-inline-start:100%;transform:scaleX(-1)}
.gaia-chat-text-default {color:var(--mud-palette-text-primary);background-color:var(--mud-palette-action-default-hover);--mud-ripple-color: var(--mud-palette-text-primary)}
.gaia-chat-text-primary {color:var(--mud-palette-primary-darken);background-color:var(--mud-palette-primary-hover);--mud-ripple-color: var(--mud-palette-primary-darken)}
.gaia-chat-text-secondary {color:var(--mud-palette-secondary-darken);background-color:var(--mud-palette-secondary-hover);--mud-ripple-color: var(--mud-palette-secondary-darken)}
.gaia-chat-text-tertiary {color:var(--mud-palette-tertiary-darken);background-color:var(--mud-palette-tertiary-hover);--mud-ripple-color: var(--mud-palette-tertiary-darken)}
.gaia-chat-text-info {color:var(--mud-palette-info-darken);background-color:var(--mud-palette-info-hover);--mud-ripple-color: var(--mud-palette-info-darken)}
.gaia-chat-text-success {color:var(--mud-palette-success-darken);background-color:var(--mud-palette-success-hover);--mud-ripple-color: var(--mud-palette-success-darken)}
.gaia-chat-text-warning {color:var(--mud-palette-warning-darken);background-color:var(--mud-palette-warning-hover);--mud-ripple-color: var(--mud-palette-warning-darken)}
.gaia-chat-text-error {color:var(--mud-palette-error-darken);background-color:var(--mud-palette-error-hover);--mud-ripple-color: var(--mud-palette-error-darken)}
.gaia-chat-text-dark {color:var(--mud-palette-dark-darken);background-color:var(--mud-palette-dark-hover);--mud-ripple-color: var(--mud-palette-dark-darken)}
.gaia-chat-outlined-default {color:var(--mud-palette-text-primary);border:1px solid var(--mud-palette-action-default-hover);--mud-ripple-color: var(--mud-palette-text-primary)}
.gaia-chat-outlined-default:before {background-color:var(--mud-palette-action-default-hover)}
.gaia-chat-outlined-default.gaia-chat-arrow-top:before {top:-0.05rem !important}
.gaia-chat-outlined-default.gaia-chat-arrow-bottom:before {bottom:-0.07rem !important}
.gaia-chat-outlined-primary {color:var(--mud-palette-primary-darken);border:1px solid var(--mud-palette-primary);--mud-ripple-color: var(--mud-palette-primary-darken)}
.gaia-chat-outlined-primary:before {background-color:var(--mud-palette-primary-darken)}
.gaia-chat-outlined-primary.gaia-chat-arrow-top:before {top:-0.05rem !important}
.gaia-chat-outlined-primary.gaia-chat-arrow-bottom:before {bottom:-0.02rem !important}
.gaia-chat-outlined-secondary {color:var(--mud-palette-secondary-darken);border:1px solid var(--mud-palette-secondary);--mud-ripple-color: var(--mud-palette-secondary-darken)}
.gaia-chat-outlined-secondary:before {background-color:var(--mud-palette-secondary-darken)}
.gaia-chat-outlined-secondary.gaia-chat-arrow-top:before {top:-0.05rem !important}
.gaia-chat-outlined-secondary.gaia-chat-arrow-bottom:before {bottom:-0.02rem !important}
.gaia-chat-outlined-tertiary {color:var(--mud-palette-tertiary-darken);border:1px solid var(--mud-palette-tertiary);--mud-ripple-color: var(--mud-palette-tertiary-darken)}
.gaia-chat-outlined-tertiary:before {background-color:var(--mud-palette-tertiary-darken)}
.gaia-chat-outlined-tertiary.gaia-chat-arrow-top:before {top:-0.05rem !important}
.gaia-chat-outlined-tertiary.gaia-chat-arrow-bottom:before {bottom:-0.02rem !important}
.gaia-chat-outlined-info {color:var(--mud-palette-info-darken);border:1px solid var(--mud-palette-info);--mud-ripple-color: var(--mud-palette-info-darken)}
.gaia-chat-outlined-info:before {background-color:var(--mud-palette-info-darken)}
.gaia-chat-outlined-info.gaia-chat-arrow-top:before {top:-0.05rem !important}
.gaia-chat-outlined-info.gaia-chat-arrow-bottom:before {bottom:-0.02rem !important}
.gaia-chat-outlined-success {color:var(--mud-palette-success-darken);border:1px solid var(--mud-palette-success);--mud-ripple-color: var(--mud-palette-success-darken)}
.gaia-chat-outlined-success:before {background-color:var(--mud-palette-success-darken)}
.gaia-chat-outlined-success.gaia-chat-arrow-top:before {top:-0.05rem !important}
.gaia-chat-outlined-success.gaia-chat-arrow-bottom:before {bottom:-0.02rem !important}
.gaia-chat-outlined-warning {color:var(--mud-palette-warning-darken);border:1px solid var(--mud-palette-warning);--mud-ripple-color: var(--mud-palette-warning-darken)}
.gaia-chat-outlined-warning:before {background-color:var(--mud-palette-warning-darken)}
.gaia-chat-outlined-warning.gaia-chat-arrow-top:before {top:-0.05rem !important}
.gaia-chat-outlined-warning.gaia-chat-arrow-bottom:before {bottom:-0.02rem !important}
.gaia-chat-outlined-error {color:var(--mud-palette-error-darken);border:1px solid var(--mud-palette-error);--mud-ripple-color: var(--mud-palette-error-darken)}
.gaia-chat-outlined-error:before {background-color:var(--mud-palette-error-darken)}
.gaia-chat-outlined-error.gaia-chat-arrow-top:before {top:-0.05rem !important}
.gaia-chat-outlined-error.gaia-chat-arrow-bottom:before {bottom:-0.02rem !important}
.gaia-chat-outlined-dark {color:var(--mud-palette-dark-darken);border:1px solid var(--mud-palette-dark);--mud-ripple-color: var(--mud-palette-dark-darken)}
.gaia-chat-outlined-dark:before {background-color:var(--mud-palette-dark-darken)}
.gaia-chat-outlined-dark.gaia-chat-arrow-top:before {top:-0.05rem !important}
.gaia-chat-outlined-dark.gaia-chat-arrow-bottom:before {bottom:-0.02rem !important}
.gaia-chat-filled-default {color:var(--mud-palette-text-primary);font-weight:500;background-color:var(--mud-palette-action-default-hover);--mud-ripple-color: var(--mud-palette-text-primary)}
.gaia-chat-filled-primary {color:var(--mud-palette-primary-text);font-weight:500;background-color:var(--mud-palette-primary);--mud-ripple-color: var(--mud-palette-primary-text)}
.gaia-chat-filled-secondary {color:var(--mud-palette-secondary-text);font-weight:500;background-color:var(--mud-palette-secondary);--mud-ripple-color: var(--mud-palette-secondary-text)}
.gaia-chat-filled-tertiary {color:var(--mud-palette-tertiary-text);font-weight:500;background-color:var(--mud-palette-tertiary);--mud-ripple-color: var(--mud-palette-tertiary-text)}
.gaia-chat-filled-info {color:var(--mud-palette-info-text);font-weight:500;background-color:var(--mud-palette-info);--mud-ripple-color: var(--mud-palette-info-text)}
.gaia-chat-filled-success {color:var(--mud-palette-success-text);font-weight:500;background-color:var(--mud-palette-success);--mud-ripple-color: var(--mud-palette-success-text)}
.gaia-chat-filled-warning {color:var(--mud-palette-warning-text);font-weight:500;background-color:var(--mud-palette-warning);--mud-ripple-color: var(--mud-palette-warning-text)}
.gaia-chat-filled-error {color:var(--mud-palette-error-text);font-weight:500;background-color:var(--mud-palette-error);--mud-ripple-color: var(--mud-palette-error-text)}
.gaia-chat-filled-dark {color:var(--mud-palette-dark-text);font-weight:500;background-color:var(--mud-palette-dark);--mud-ripple-color: var(--mud-palette-dark-text)}

/* ============================================================================
   RICONNESSIONE AL SERVER (Components/Layout/ReconnectModal.razor)

   Sostituisce la finestra inglese che Blazor disegnerebbe da solo. Le classi
   components-reconnect-* le applica blazor.web.js sul div #components-reconnect-modal;
   qui si decide solo cosa mostrare per ciascuno stato.
   Colori dalle variabili --mud-palette-*, cosi' segue chiaro/scuro come il resto.
   ============================================================================ */

/* di base la finestra non esiste proprio: nessun overlay finche' la connessione regge */
#components-reconnect-modal {
    display: none;
}

/* ogni stato in cui va mostrata */
#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-retrying,
#components-reconnect-modal.components-reconnect-paused,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-resume-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: block;
    position: fixed;
    inset: 0;
    /* MudBlazor 9 stila a sua volta #components-reconnect-modal, e lo fa con !important:
       senza !important anche qui vincerebbe il suo sfondo opaco al posto della velatura scura */
    z-index: 10000 !important;
    background-color: rgba(0, 0, 0, .55) !important;
    backdrop-filter: blur(2px);
    animation: gaia-reconnect-comparsa .25s ease-out;
}

/* riconnesso: si richiude senza lasciare traccia */
#components-reconnect-modal.components-reconnect-hide {
    display: none;
}

.gaia-reconnect-dialog {
    position: relative;
    box-sizing: border-box;
    width: min(23rem, calc(100vw - 2rem));
    margin: 18vh auto 0;
    padding: 2rem 1.75rem;
    border-radius: var(--mud-default-borderradius, 4px);
    background-color: var(--mud-palette-surface, #fff);
    color: var(--mud-palette-text-primary, #424242);
    box-shadow: 0 8px 24px 2px rgba(0, 0, 0, .35);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .75rem;
    text-align: center;
    animation: gaia-reconnect-salita .35s cubic-bezier(.05, .89, .25, 1.02);
}

.gaia-reconnect-logo {
    width: 132px;
    max-width: 60%;
    height: auto;
    margin-bottom: .25rem;
}

/* tre cerchi che pulsano: girano solo mentre si sta ritentando */
.gaia-reconnect-spinner {
    display: flex;
    gap: .4rem;
    height: .75rem;
    align-items: center;
}

.gaia-reconnect-spinner span {
    width: .55rem;
    height: .55rem;
    border-radius: 50%;
    background-color: var(--mud-palette-primary, #594ae2);
    animation: gaia-reconnect-pulsazione 1.2s ease-in-out infinite;
}

.gaia-reconnect-spinner span:nth-child(2) {
    animation-delay: .2s;
}

.gaia-reconnect-spinner span:nth-child(3) {
    animation-delay: .4s;
}

.gaia-reconnect-titolo {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 600;
    line-height: 1.4;
}

.gaia-reconnect-nota {
    margin: 0;
    font-size: .85rem;
    line-height: 1.45;
    opacity: .75;
}

.gaia-reconnect-dettaglio {
    margin: 0;
    font-size: .75rem;
    line-height: 1.3;
    opacity: .55;
    font-variant-numeric: tabular-nums;
}

.gaia-reconnect-bottone {
    margin-top: .5rem;
    padding: .5rem 1.4rem;
    border: none;
    border-radius: var(--mud-default-borderradius, 4px);
    background-color: var(--mud-palette-primary, #594ae2);
    color: var(--mud-palette-primary-text, #fff);
    font-family: inherit;
    font-size: .875rem;
    font-weight: 500;
    letter-spacing: .02em;
    cursor: pointer;
    transition: background-color .15s ease-in-out, box-shadow .15s ease-in-out;
}

.gaia-reconnect-bottone:hover {
    background-color: var(--mud-palette-primary-darken, #4f42c8);
    box-shadow: 0 2px 6px rgba(0, 0, 0, .25);
}

.gaia-reconnect-bottone:focus-visible {
    outline: 2px solid var(--mud-palette-primary-lighten, #8b7ff0);
    outline-offset: 2px;
}

/* --- quale testo si vede in quale stato ------------------------------------
   Tutti i messaggi stanno nel markup; qui se ne accende uno solo per volta. */

.gaia-reconnect-in-corso,
.gaia-reconnect-in-pausa,
.gaia-reconnect-ko,
.gaia-reconnect-scaduta,
.gaia-reconnect-bottone {
    display: none;
}

/* sta ritentando: spinner + conteggio tentativi, nessun pulsante (ci pensa da solo) */
.components-reconnect-show .gaia-reconnect-in-corso,
.components-reconnect-retrying .gaia-reconnect-in-corso {
    display: block;
}

/* circuito sospeso dal server: riprende da solo, niente conteggio */
.components-reconnect-paused .gaia-reconnect-in-pausa {
    display: block;
}

/* tentativi esauriti o ripresa fallita: l'utente deve ricaricare */
.components-reconnect-failed .gaia-reconnect-ko,
.components-reconnect-resume-failed .gaia-reconnect-ko,
.components-reconnect-failed .gaia-reconnect-bottone,
.components-reconnect-resume-failed .gaia-reconnect-bottone,
.components-reconnect-rejected .gaia-reconnect-bottone {
    display: block;
}

/* il server ha buttato via il circuito: lo stato e' perso davvero */
.components-reconnect-rejected .gaia-reconnect-scaduta {
    display: block;
}

/* a tentativi finiti i cerchi si fermano: lasciarli animati sembrerebbe che stia ancora provando */
.components-reconnect-failed .gaia-reconnect-spinner,
.components-reconnect-resume-failed .gaia-reconnect-spinner,
.components-reconnect-rejected .gaia-reconnect-spinner {
    display: none;
}

@keyframes gaia-reconnect-comparsa {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes gaia-reconnect-salita {
    from { transform: translateY(18px) scale(.97); opacity: 0; }
    to   { transform: none; opacity: 1; }
}

@keyframes gaia-reconnect-pulsazione {
    0%, 80%, 100% { transform: scale(.6); opacity: .4; }
    40%           { transform: scale(1);  opacity: 1; }
}

/* chi ha chiesto meno animazioni non si vede lampeggiare niente */
@media (prefers-reduced-motion: reduce) {
    #components-reconnect-modal.components-reconnect-show,
    #components-reconnect-modal.components-reconnect-retrying,
    #components-reconnect-modal.components-reconnect-paused,
    #components-reconnect-modal.components-reconnect-failed,
    #components-reconnect-modal.components-reconnect-resume-failed,
    #components-reconnect-modal.components-reconnect-rejected {
        animation: none;
    }

    .gaia-reconnect-dialog { animation: none; }
    .gaia-reconnect-spinner span { animation: none; opacity: .7; transform: none; }
}


/* ============================================================================
   ICONE DEL MENU LATERALE

   Le icone sono un supporto alla lettura, non il contenuto: con il colore
   primario "gridavano" piu' delle etichette e, a cassetto chiuso, la striscia
   diventava un muro di colore. Qui restano neutre (il grigio di sistema, che
   segue da solo tema chiaro e scuro) e un po' piu' grandi, perche' a menu
   chiuso sono l'UNICA cosa leggibile.

   Il colore arriva da qui e non dal parametro IconColor: in NavItemComp le voci
   usano Color.Inherit proprio per lasciare la decisione a un punto solo.

   La voce ATTIVA fa eccezione e prende il primario: e' l'unico segnale di "dove
   sono" che sopravvive quando le etichette sono nascoste.
   ============================================================================ */

/* ============================================================================
   FOOTER A TRE ZONE

   Fila flex al posto di MudGrid: la griglia porta con se' margini negativi e
   riempimenti pensati per il contenuto di pagina, che dentro una barra alta
   40px sfalsavano l'allineamento verticale.
   Le due zone laterali crescono allo stesso modo, quindi le social restano
   centrate rispetto alla barra e non rispetto allo spazio che avanza.
   ============================================================================ */

.gaia-footer {
    display: flex;
    align-items: center;
    width: 100%;
    gap: 12px;
    min-width: 0;
}

.gaia-footer-lato {
    display: flex;
    align-items: center;
    flex: 1 1 0;
    min-width: 0; /* senza, il contenuto lungo impedisce alla zona di restringersi */
}
.gaia-footer-destra {
    justify-content: flex-end;
    margin-right: 40px; /* Approssimazione comune per 1 cm su schermi standard */
}


.gaia-footer-centro {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
}

/* ============================================================================
   INFO DEL TICKET SU TELEFONO (AddTicket, blocco "Mostra solo su Mobile")

   I dati del cliente e del ticket erano campi di testo in sola lettura dentro
   una griglia pensata per il desktop: su uno schermo stretto ogni campo si
   prendeva tre righe per mostrare due parole, con l'etichetta che si sovrapponeva
   al valore. Qui l'impaginazione e' quella di un elenco di dati: etichetta
   piccola e smorzata sopra, valore leggibile sotto.

   Vale SOLO per il telefono: il markup sta dentro il blocco MudHidden riservato
   ai piccoli schermi, la vista da PC non usa queste classi.
   ============================================================================ */

.tk-info-mobile {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 4px 2px 8px;
}

.tk-info-voce {
    display: flex;
    flex-direction: column;
    min-width: 0; /* senza, i valori lunghi sfondano il contenitore flex invece di andare a capo */
}

.tk-info-etichetta {
    font-size: .72rem;
    line-height: 1.2;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--mud-palette-text-secondary);
}

.tk-info-valore {
    font-size: .95rem;
    line-height: 1.35;
    font-weight: 600;
    word-break: break-word; /* email e ragioni sociali lunghe non devono sfondare */
}

/* due voci corte affiancate: le versioni sprecherebbero una riga intera ciascuna */
.tk-info-coppia {
    display: flex;
    gap: 16px;
}

.tk-info-coppia > .tk-info-voce {
    flex: 1 1 0;
}

/* ============================================================================
   ELENCO TICKET A CARD (Components/Components/Ticket/TicketCardListComp.razor)

   Vale solo da telefono, dove la griglia impilata rendeva un ticket alto quanto
   lo schermo. Ogni card sta in circa 110px: numero e stato, cliente, oggetto su
   due righe, chi lo gestisce.
   ============================================================================ */

/* ============================================================================
   CARD DA TELEFONO — stile comune

   Vale per gli elenchi che da telefono lasciano la griglia e passano alle card:
   teleassistenze, rapportini, commesse. I ticket hanno le loro (tk-card-*), nate
   prima; queste sono le stesse misure ma con nomi buoni per tutti.
   ============================================================================ */

.gaia-card-elenco {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.gaia-card {
    padding: 10px 12px;
    cursor: pointer;
    border-left: 3px solid var(--mud-palette-primary);
}

.gaia-card:active {
    background-color: var(--mud-palette-action-default-hover);
}

.gaia-card-riga-alta {
    display: flex;
    align-items: center;
    gap: 6px;
    min-height: 32px;
}

.gaia-card-spazio {
    flex: 1;
}

.gaia-card-data {
    font-weight: 700;
    color: var(--mud-palette-primary);
    font-size: .85rem;
}

.gaia-card-titolo {
    font-weight: 600;
    font-size: .92rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* oggetto: due righe, poi i puntini */
.gaia-card-testo {
    font-size: .85rem;
    line-height: 1.3;
    margin-top: 2px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* note: un gradino sotto all'oggetto, cosi' si distinguono a colpo d'occhio */
.gaia-card-testo-tenue {
    font-size: .8rem;
    line-height: 1.3;
    margin-top: 2px;
    color: var(--mud-palette-text-secondary);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.gaia-card-piede {
    display: flex;
    align-items: center;
    margin-top: 4px;
    font-size: .78rem;
    color: var(--mud-palette-text-secondary);
    /* tecnico e commessa su una riga sola: la commessa e' quella che cede */
    min-width: 0;
}

.gaia-card-piede-sep {
    margin: 0 4px;
    flex: none;
}

.gaia-card-piede-commessa {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* telefono ed email in fondo alla card della rubrica: restano cliccabili, quindi vanno su righe
   loro con un po' d'aria, non schiacciati nel piede */
.gaia-card-contatti {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    margin-top: 2px;
}

/* numero del documento accanto alla data */
.gaia-card-etichetta {
    font-size: .78rem;
    color: var(--mud-palette-text-secondary);
}

/* voci dentro il menu "altre informazioni" dei tre puntini */
.gaia-card-info-voce {
    display: flex;
    flex-direction: column;
    max-width: 78vw;
    padding: 2px 0;
}

.gaia-card-info-etichetta {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--mud-palette-text-secondary);
}

.gaia-card-info-valore {
    font-size: .85rem;
    line-height: 1.35;
    /* i valori lunghi (note, oggetto) vanno a capo invece di allargare il menu */
    white-space: normal;
    word-break: break-word;
}

/* Testata richiudibile dell'ANTEPRIMA laterale del ticket (TicketAnteprimaComp): il pannello sta
   dentro una colonna stretta, quindi niente sfondo ne' rientri suoi, si deve leggere come il resto
   della testata. Il numero del ticket resta nella riga sopra, sempre visibile. */
.tk-anteprima-pannello-testata,
.tk-anteprima-pannello-testata .mud-expand-panel {
    background: transparent;
}

.tk-anteprima-pannello-testata .mud-expand-panel-header {
    padding: 2px 0;
    min-height: 0;
}

.tk-anteprima-pannello-testata .mud-expand-panel-content {
    padding: 0;
}

/* intestazione della sezione richiudibile che raccoglie le card */
.tk-card-sezioni {
    margin-bottom: 6px;
}

/* il conteggio accanto al titolo della sezione: e' un numero, non un'etichetta, quindi sta
   stretto. MudChip di suo e' alto 24px con margini laterali da tag vero e proprio. */
.tk-card-sezioni .tk-card-sezione-conteggio {
    height: 18px;
    min-width: 18px;
    padding: 0 6px;
    margin: 0;
    font-size: .7rem;
    font-weight: 600;
}

.tk-card-sezione-titolo {
    text-transform: uppercase;
    letter-spacing: .04em;
    font-weight: 600;
    /* i titoli lunghi ("TICKET DI ALTRI REPARTI") non devono spingere fuori il conteggio */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tk-card-elenco {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.tk-card {
    padding: 10px 12px;
    cursor: pointer;
    border-left: 3px solid var(--mud-palette-primary);
}

.tk-card:active {
    background-color: var(--mud-palette-action-default-hover);
}

.tk-card-riga-alta {
    display: flex;
    align-items: center;
    gap: 6px;
}

.tk-card-spazio {
    flex: 1;
}

.tk-card-id {
    font-weight: 700;
    color: var(--mud-palette-primary);
}

.tk-card-data {
    font-size: .78rem;
    color: var(--mud-palette-text-secondary);
}

.tk-card-cliente {
    font-weight: 600;
    font-size: .92rem;
    margin-top: 2px;
    /* le ragioni sociali lunghe non devono sfondare la card */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* l'oggetto e' l'unica cosa che si legge davvero: due righe, poi i puntini */
.tk-card-oggetto {
    font-size: .85rem;
    line-height: 1.3;
    margin-top: 2px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.tk-card-gestione {
    display: flex;
    align-items: center;
    margin-top: 4px;
    font-size: .78rem;
    color: var(--mud-palette-text-secondary);
}

/* divisorio con etichetta dentro il pannello "Info ticket": separa i dati di contatto dal
   resto senza costringere a un secondo pannello da aprire (era il vecchio "Altre info") */
.tk-info-separatore {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 4px;
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--mud-palette-text-secondary);
}

.tk-info-separatore::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--mud-palette-lines-default);
}

/* ============================================================================
   EVENTO DI CALENDARIO CON TICKET COMPLETATO

   Prima c'era un pallino verde in alto a destra dentro il riquadro: stava SOPRA
   il testo e nelle caselle strette copriva la fine della descrizione.
   Ora il segnale e' un bordo verde, che si vede a colpo d'occhio e non occupa
   spazio utile.
   E' un'ombra interna e non un vero border di proposito: il border, anche con
   box-sizing border-box, mangia 2px di spazio interno e fa muovere il testo,
   mentre l'ombra si disegna sopra il bordo esistente senza toccare il layout.
   Segue da sola gli angoli arrotondati dell'evento.
   ============================================================================ */

.gaia-evento-completato {
    box-shadow: inset 0 0 0 2px var(--mud-palette-success);
}

/* ============================================================================
   FLUIDITA' DEL CASSETTO

   MudBlazor anima in 225ms sia la larghezza del cassetto sia il margine del
   contenuto: due animazioni distinte che devono restare in passo, altrimenti si
   vede prima muoversi uno e poi l'altro. Qui si accorciano entrambe a 170ms con
   la stessa curva, cosi' il movimento e' unico e piu' asciutto.
   Non e' questo il motivo per cui prima il nascondere il menu ci metteva
   secondi: quello era il cambio di variante del cassetto (Mini -> Persistent),
   risolto in MainLayout tenendo sempre Mini e portando a zero la larghezza.
   Qui si rifinisce l'animazione, non si cura un blocco.
   ============================================================================ */

.mud-drawer.mud-drawer-mini,
.mud-drawer.mud-drawer-persistent.mud-drawer-pos-left,
.mud-drawer.mud-drawer-persistent.mud-drawer-pos-right {
    transition-duration: 170ms;
    transition-timing-function: cubic-bezier(.4, 0, .2, 1);
}

/* IL CONTENUTO NON SI ANIMA, SI SPOSTA E BASTA.
   Qui stava lo scatto: animare il margine del contenuto obbliga il browser a
   ricalcolare l'impaginazione dell'INTERA pagina a ogni fotogramma. Su una
   pagina leggera (la home) non si nota; su una griglia ticket con centinaia di
   righe sono decine di ricalcoli in 170ms, e si vede il blocco.
   Togliendo la transizione il ricalcolo e' UNO solo. Il movimento resta comunque
   morbido perche' a scorrere e' il cassetto, che e' piccolo e si anima da solo. */
.mud-main-content,
.mud-drawer.mud-drawer-mini ~ div:not(.mud-main-content),
.mud-drawer.mud-drawer-persistent ~ div:not(.mud-main-content) {
    transition: none !important;
}

/* chi ha chiesto meno animazioni vede il cassetto cambiare stato di colpo */
@media (prefers-reduced-motion: reduce) {
    .mud-drawer,
    .mud-main-content,
    .mud-drawer ~ div:not(.mud-main-content) {
        transition: none !important;
    }
}

/* Cassetto nascosto: la larghezza da chiuso e' gia' 0, questo assicura che non resti visibile
   nemmeno la riga del bordo e che il contenuto non sbordi mentre la larghezza si azzera. */
.gaia-drawer-nascosto {
    width: 0 !important;
    min-width: 0 !important;
    overflow: hidden !important;
    border: none !important;
}

/* ============================================================================
   CASSETTO SU TELEFONO

   Bersagli piu' grandi: il dito non e' il puntatore del mouse. 48px e' la
   misura minima consigliata per un elemento da toccare, e con un albero a tre
   livelli le voci sono tante e vicine: sbagliare voce e dover tornare indietro
   e' esattamente cio' che fa sembrare un menu macchinoso.
   ============================================================================ */

@media (max-width: 960px) {
    .gaia-drawer-telefono .mud-nav-link {
        min-height: 48px;
    }

    /* i sottolivelli rientrano meno: su schermo stretto il rientro progressivo
       mangiava la larghezza utile e i titoli lunghi andavano a capo */
    .gaia-drawer-telefono .mud-navmenu .mud-navmenu .mud-nav-link {
        padding-left: 24px;
    }
}

/* ============================================================================
   RICERCA GLOBALE (Controls/Generic/RicercaGlobale.razor)

   Il campo vive nel footer, a destra: sempre presente, sempre nello stesso
   punto, senza pulsanti flottanti che si contendono l'angolo in basso a destra
   con il pulsante del bot delle pagine ticket.
   Sul telefono il footer non viene mostrato (e' riservato al desktop): li'
   l'accesso e' un'icona nella barra in alto, stessa maschera di risultati.
   ============================================================================ */

/* Il footer e' alto 40px: il campo deve starci dentro senza allargarlo, quindi niente etichetta
   flottante e margini azzerati. Largo ma non sconfinato: e' una riga di ricerca, non un form. */
.gaia-ricerca-campo {
    max-width: 320px;
    margin-left: auto;
}

.gaia-ricerca-campo .mud-input {
    margin-top: 0;
}

/* Contenitore del campo nel footer: serve solo a dare un riferimento al pannello dei
   suggerimenti, che gli si appoggia sopra. */
.gaia-ricerca-wrap {
    position: relative;
    max-width: 320px;
    margin-left: auto;
    /* Si sta a distanza dall'angolo in basso a destra: li' c'e' il pulsante tondo
       dell'assistente GaIA, che copriva la parte finale del campo e ne rendeva
       illeggibile il testo. */
    margin-right: 88px;
}

/* Suggerimenti mentre si scrive: si aprono VERSO L'ALTO, perche' il campo e' in fondo alla
   pagina. Restano dentro al contenitore del campo, cosi' il clic su una voce non conta come
   uscita dal campo e il pannello non sparisce prima del tempo. */
.gaia-ricerca-anteprima {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 1300;
}

.gaia-ricerca-anteprima-carta {
    max-height: 60vh;
    overflow-y: auto;
    border-radius: var(--mud-default-borderradius, 4px);
}

.gaia-ricerca-anteprima-titolo {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* l'elenco dei risultati non deve far crescere il riquadro all'infinito */
.gaia-ricerca-elenco {
    max-height: 55vh;
    overflow-y: auto;
}

/* guida alla sintassi di ricerca: la colonna degli esempi sta stretta, la spiegazione prende il resto */
.gaia-ricerca-guida {
    background-color: transparent;
}

.gaia-ricerca-guida td {
    padding: 4px 8px !important;
    font-size: 0.82rem;
    vertical-align: top;
}

.gaia-ricerca-guida td:first-child {
    white-space: nowrap;
    width: 1%;
}

.gaia-ricerca-guida code {
    background-color: var(--mud-palette-background-gray);
    border-radius: 4px;
    padding: 1px 6px;
    font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
}

/* Pulsante del cassetto, stato "nascosto": serve l'hamburger con la freccia verso DESTRA, cioe'
   "riapri". Material fornisce solo MenuOpen con la freccia a sinistra, quindi la si ribalta.
   Ribaltare l'icona e non il pulsante: cosi' l'area cliccabile e l'ombra del focus restano dove
   sono e non si specchiano insieme al disegno. */
.gaia-drawer-mostra .mud-icon-root {
    transform: scaleX(-1);
}

/* logo in testa alla striscia: centrato davvero, non incolonnato con le icone delle voci */
.gaia-mini-logo {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 10px 0;
    cursor: pointer;
}

/* Il cambio esteso/mini e' solo CSS: NavMenu resta montato e l'albero delle voci non viene
   ricostruito a ogni click. Sul drawer temporaneo del telefono resta visibile la versione estesa. */
.gaia-menu-solo-mini.gaia-mini-logo {
    display: none;
}

.mud-drawer--closed.mud-drawer-mini .gaia-menu-solo-mini.gaia-mini-logo {
    display: flex;
}

.mud-drawer--closed.mud-drawer-mini .gaia-menu-solo-esteso {
    display: none !important;
}

/* stessa area a cassetto esteso: e' un comando (apri/chiudi tutto l'albero), quindi si comporta
   come una voce cliccabile e non come un'immagine qualsiasi */
.gaia-logo-menu {
    cursor: pointer;
    user-select: none;
    transition: background-color .15s ease-in;
}

.gaia-mini-logo:hover,
.gaia-logo-menu:hover {
    background-color: var(--mud-palette-action-default-hover);
}

/* ── I TRE LIVELLI ──────────────────────────────────────────────────────────
   Con icone tutte uguali la colonna non si legge: non si capisce dove finisce
   un menu e dove comincia il suo contenuto. La gerarchia si vede cosi':

     menu principali  icona piena, colore primario, 1,75rem   <- "titoli"
     sottomenu        contorno, grigio,             1,6rem
     pagine           contorno, grigio,             1,45rem e piu' tenui

   L'aggancio e' la classe di colore che MudBlazor mette sull'icona
   (mud-primary-text), non la posizione nell'albero: NavItemComp assegna il
   primario ai soli livelli 0, quindi il selettore non puo' sbagliare bersaglio
   anche se MudBlazor cambia come annida i suoi elementi.
   ──────────────────────────────────────────────────────────────────────────── */

.mud-drawer .mud-navmenu .mud-nav-link .mud-icon-root,
.mud-drawer .mud-navmenu .mud-nav-link-button .mud-icon-root {
    font-size: 1.6rem;
    transition: opacity .15s ease-in, color .15s ease-in;
}

/* sottomenu e pagine: grigio neutro. Il :not() protegge le icone dei menu
   principali, che devono restare del colore del tema */
.mud-drawer .mud-navmenu .mud-nav-link .mud-icon-root:not(.mud-primary-text),
.mud-drawer .mud-navmenu .mud-nav-link-button .mud-icon-root:not(.mud-primary-text) {
    color: var(--mud-palette-text-secondary);
    /* tratto piu' morbido: le icone non competono con il testo */
    opacity: .78;
}

/* menu principali: piene, colorate, piu' grandi */
.mud-drawer .mud-navmenu .mud-nav-link .mud-icon-root.mud-primary-text {
    font-size: 1.75rem;
    opacity: 1;
}

/* pagine: un gradino sotto ai sottomenu, cosi' l'occhio distingue il contenitore
   dal contenuto anche a colpo d'occhio */
.mud-drawer .mud-navmenu .gaia-nav-foglia .mud-icon-root {
    font-size: 1.45rem;
    opacity: .68;
}

.mud-drawer .mud-navmenu .mud-nav-link:hover .mud-icon-root,
.mud-drawer .mud-navmenu .mud-nav-link-button:hover .mud-icon-root {
    opacity: 1;
}

.mud-drawer .mud-navmenu .mud-nav-link.active .mud-icon-root {
    color: var(--mud-palette-primary);
    opacity: 1;
}

/* A cassetto chiuso l'icona e' l'unica informazione: qualche pixel in piu' a tutte, mantenendo
   pero' i tre gradini. Se qui si mettesse una misura sola, nella striscia la gerarchia sparirebbe
   proprio dove serve di piu' (senza etichette e' l'unico indizio rimasto). */
.mud-drawer--closed.mud-drawer-mini .mud-navmenu .mud-nav-link .mud-icon-root,
.mud-drawer--closed.mud-drawer-mini .mud-navmenu .mud-nav-link-button .mud-icon-root {
    font-size: 1.7rem;
    opacity: .85;
}

.mud-drawer--closed.mud-drawer-mini .mud-navmenu .mud-nav-link .mud-icon-root.mud-primary-text {
    font-size: 1.95rem;
    opacity: 1;
}

.mud-drawer--closed.mud-drawer-mini .mud-navmenu .gaia-nav-foglia .mud-icon-root {
    font-size: 1.5rem;
    opacity: .72;
}

@media (prefers-reduced-motion: reduce) {
    .mud-drawer .mud-navmenu .mud-nav-link .mud-icon-root,
    .mud-drawer .mud-navmenu .mud-nav-link-button .mud-icon-root {
        transition: none;
    }
}

/* ----------------------------------------------------------------------------
   PAGINA APERTA NEL MENU

   Le voci navigano con OnClick e non con Href (la navigazione passa da
   GaiaNavService), quindi MudBlazor non puo' riconoscere da solo la voce attiva:
   la classe la mette NavItemComp confrontando il percorso corrente.

   Fondo grigio tenue e striscia a sinistra: si capisce dove si e' senza che il
   testo cambi colore o peso al punto da far ballare la larghezza delle voci.
   I colori arrivano dalla palette, quindi valgono anche in tema scuro.

   ATTENZIONE al bersaglio dei selettori: la Class di MudNavLink NON finisce
   sull'elemento .mud-nav-link ma sul suo contenitore .mud-nav-item, che gli sta
   sopra. Scritto come ".mud-nav-link.gaia-nav-attiva" il selettore non trovava
   nulla e la pagina aperta restava senza evidenziazione, mentre il gruppo che la
   contiene si coloriva regolarmente (li' la classe sta sul .mud-nav-group, che il
   .mud-nav-link ce l'ha davvero come figlio). Da qui la forma "> .mud-nav-link"
   per entrambi.
   ---------------------------------------------------------------------------- */

.mud-drawer .mud-navmenu .gaia-nav-attiva > .mud-nav-link,
.mud-drawer .mud-navmenu .gaia-nav-gruppo-attivo > .mud-nav-link {
    background-color: var(--mud-palette-action-default-hover);
    box-shadow: inset 3px 0 0 var(--mud-palette-primary);
    font-weight: 600;
}

/* l'icona della voce aperta e' a piena intensita': nella striscia di sole icone e'
   l'unico segnale rimasto, visto che le etichette non ci sono */
.mud-drawer .mud-navmenu .gaia-nav-attiva > .mud-nav-link .mud-icon-root,
.mud-drawer .mud-navmenu .gaia-nav-gruppo-attivo > .mud-nav-link .mud-icon-root {
    color: var(--mud-palette-primary);
    opacity: 1;
}

/* ============================================================================
   GANTT DA TELEFONO (Components/Components/Agende/GanttMobile.razor)

   La vista da PC affianca 4 settimane: qui si mostra una settimana per volta e la
   riga diventa [check] [nome] [stella] [5 celle]. Le colonne dell'intestazione usano
   le stesse misure delle celle, cosi' i giorni cadono sopra il posto giusto.
   ============================================================================ */

.gantt-m {
    padding-bottom: 8px;
}

.gantt-m-testa {
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--mud-palette-surface, #fff);
    border-bottom: 1px solid var(--mud-palette-lines-default, #e0e0e0);
}

.gantt-m-barra {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 2px 4px;
}

.gantt-m-periodo {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* riga operatore: e' il nodo radice di GanttOperatoreComp in modo compatto */
.gantt-m-riga {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 1px 4px;
}

.gantt-m-riga + .gantt-m-riga {
    border-top: 1px solid var(--mud-palette-lines-default, #eeeeee);
}

/* i bottoni MudBlazor hanno un'area di tocco pensata per il mouse: qui ruberebbe
   larghezza al nome dell'operatore */
.gantt-m-riga .mud-icon-button {
    padding: 4px;
}

.gantt-m-check,
.gantt-m-stella {
    flex: 0 0 26px;
}

.gantt-m-nome {
    flex: 1 1 auto;
    min-width: 0;
    cursor: pointer;
}

/* Il nome sta su due righe dentro l'altezza della cella (34px): tagliato a una riga sola
   "Alberto Brigato" e "Alberto Tallon" diventavano tutti e due "Albert...". */
.gantt-m-nome-testo {
    font-size: .72rem;
    line-height: 1.15;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
}

/* La larghezza va data alle COLONNE, non ai figli: GanttItem si disegna con width:100%
   inline, che su una colonna di larghezza automatica collasserebbe a pochi pixel. */
.gantt-m-celle {
    flex: 0 0 auto;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 30px;
    gap: 2px;
}

.gantt-m-giorni {
    padding-bottom: 2px;
}

.gantt-m-giorno {
    display: flex;
    flex-direction: column;
    align-items: center;
    line-height: 1.05;
}

.gantt-m-giorno-nome {
    font-size: .6rem;
    opacity: .6;
}

.gantt-m-giorno-num {
    font-size: .75rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.gantt-m-giorno-oggi .gantt-m-giorno-num {
    color: var(--mud-palette-primary);
}

.gantt-m-gruppo {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 2px 4px;
    cursor: pointer;
    background: var(--mud-palette-background-gray, rgba(0, 0, 0, .04));
    border-top: 1px solid var(--mud-palette-lines-default, #e0e0e0);
}

.gantt-m-gruppo-titolo {
    flex: 1 1 auto;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.gantt-m-gruppo-conta {
    opacity: .6;
    margin-right: 2px;
}

.gantt-m-nota {
    display: block;
    padding: 8px 6px 0;
    opacity: .6;
}

/* ============================================================================
   TELEASSISTENZE (Components/Pages/Operatori/Assistenze.razor)

   Oggetto e note in griglia stanno su una riga sola e accorciati: il testo intero
   e' nel tooltip e nel pannello di dettaglio che si apre cliccando la riga.
   ============================================================================ */

.gaia-assistenze-cella {
    display: inline-block;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: middle;
}

/* il dettaglio segue la pagina: se l'elenco e' lungo resta comunque a portata d'occhio */
.gaia-assistenze-dettaglio {
    position: sticky;
    top: 88px;
    max-height: calc(100vh - 120px);
    overflow-y: auto;
}

/* oggetto e note arrivano dal gestionale con gli a capo dentro: vanno rispettati */
.gaia-assistenze-testo {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* ============================================================================
   DROPZONE ALLEGATI (Components/Components/Ticket/Allegati/TicketDropZone.razor)

   Il riquadro tratteggiato e' un MudPaper "relative": sopra ci sta l'<input
   type=file> di MudFileUpload, reso visibile (Hidden="false") e steso
   trasparente con le classi utility "absolute mud-width-full mud-height-full
   z-10". E' l'input a ricevere sia il clic sia il drop, che il browser gestisce
   da solo. Stesso schema di Components/Pages/Admin/Import.razor.
   ============================================================================ */

.gaia-dropzone-area {
    min-height: 46px;
    padding: 8px 14px;
    border-style: dashed;
    background-color: transparent;
    color: var(--mud-palette-text-secondary);
    cursor: pointer;
    transition: border-color .2s ease, background-color .2s ease, color .2s ease;
}

.gaia-dropzone-area:hover {
    border-color: var(--mud-palette-primary);
    background-color: var(--mud-palette-action-default-hover);
    color: var(--mud-palette-primary);
}

/* variante bassa per le barre senza spazio verticale (footer dei commenti) */
.gaia-dropzone-area-compatta {
    min-height: 38px;
    padding: 4px 10px;
}

/* file in arrivo sopra l'area: bordo pieno, cosi' si vede dove si sta lasciando */
.gaia-dropzone-attiva {
    border-style: solid;
    background-color: var(--mud-palette-action-default-hover);
    color: var(--mud-palette-primary);
}

.gaia-dropzone-testo {
    font-size: .8125rem;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.gaia-dropzone-area-compatta .gaia-dropzone-testo {
    font-size: .75rem;
}

.gaia-dropzone-nota {
    display: inline-flex;
    align-items: center;
    margin-top: 4px;
    line-height: 1.3;
}

@media (max-width: 600px) {
    .gaia-dropzone-area {
        min-height: 42px;
        padding: 6px 10px;
    }
}

/* ============================================================================
   AVANZAMENTO CARICAMENTO ALLEGATI
   (Components/Components/Ticket/Allegati/TicketUploadProgress.razor)

   Riquadro in basso a destra, deliberatamente NON modale: mentre un allegato
   pesante sale, la form del ticket deve restare utilizzabile.
   ============================================================================ */

.gaia-upload-progress {
    position: fixed;
    right: 16px;
    bottom: 16px;
    z-index: 1400;
    width: 320px;
    max-width: calc(100vw - 32px);
    padding: 12px 14px;
    border-radius: var(--mud-default-borderradius);
}

.gaia-upload-progress-riga + .gaia-upload-progress-riga {
    margin-top: 10px;
}

.gaia-upload-progress-nome {
    max-width: 190px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

@media (max-width: 600px) {
    .gaia-upload-progress {
        left: 16px;
        width: auto;
    }

    .gaia-upload-progress-nome {
        max-width: 55vw;
    }
}

/* ============================================================================
   DOCUMENTI CLIENTE
   Upload  -> Components/Pages/Admin/Upload.razor        (l'admin carica)
   Download-> Components/Pages/Azienda/AltriDocumenti.razor (il cliente scarica)
   ============================================================================ */

/* le due colonne del caricamento restano alte uguali anche con contenuti diversi */
.gaia-upload-passo {
    height: 100%;
}

.gaia-upload-nomefile {
    max-width: 320px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* tessera di una cartella: tutta l'area e' cliccabile, non solo il nome */
.gaia-doc-cartella {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    height: 100%;
    cursor: pointer;
    transition: border-color .2s ease, background-color .2s ease;
}

.gaia-doc-cartella:hover {
    border-color: var(--mud-palette-primary);
    background-color: var(--mud-palette-action-default-hover);
}

.gaia-doc-cartella-testo {
    flex: 1 1 auto;
    min-width: 0; /* senza questo il nome lungo sfonda la tessera invece di troncarsi */
}

.gaia-doc-nome {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    display: block;
}

.gaia-doc-elenco {
    max-height: 60vh;
    overflow: auto;
}

.gaia-doc-riga {
    cursor: pointer;
}

/* il riassunto sotto il nome serve solo dove le colonne di dettaglio non ci stanno */
.gaia-doc-sottotitolo {
    display: none;
    font-size: .75rem;
    padding-left: 28px;
}

@media (max-width: 960px) {
    .gaia-doc-col-secondaria {
        display: none;
    }

    .gaia-doc-sottotitolo {
        display: block;
    }

    .gaia-upload-nomefile {
        max-width: 45vw;
    }
}

/* riferimento a un altro ticket dentro il testo (vedi Services/TicketLinkHelper.cs):
   si deve capire che e' cliccabile senza stonare col resto del commento */
.gaia-link-ticket {
    color: var(--mud-palette-primary);
    text-decoration: underline;
    text-underline-offset: 2px;
    font-weight: 500;
}

.gaia-link-ticket:hover {
    background-color: var(--mud-palette-action-default-hover);
    border-radius: 3px;
}

/* ============================================================================
   TOOLTIP: SOLO SU DISPOSITIVI CON PUNTATORE

   Su telefono e tablet il tooltip non ha modo di comparire "al passaggio":
   si apre al tap, copre proprio quello che si e' appena toccato e va chiuso
   con un secondo tocco. Qui viene nascosto sui dispositivi senza hover, cosi'
   vale per tutte le pagine senza dover toccare un MudTooltip alla volta.

   Si usa (hover: none) e non la larghezza: e' la condizione giusta, un portatile
   con finestra stretta il puntatore ce l'ha e il tooltip gli serve.
   ============================================================================ */

@media (hover: none) {
    .mud-tooltip,
    .mud-popover.mud-tooltip,
    .mud-tooltip-root > .mud-popover {
        display: none !important;
    }
}

/* ============================================================================
   ANTEPRIMA LATERALE DEL TICKET (colonna congelata + pannello a destra)

   Componenti: Components/Ticket/TicketsGridComp.razor (colonna) e
   Components/Ticket/TicketAnteprimaComp.razor (pannello). La colonna si vede
   solo se l'operatore ha acceso la spunta nel menu a tre puntini della pagina.

   Le griglie e il pannello stanno affiancati in una riga flex: le griglie si
   restringono e il pannello NON copre nulla, cosi' la lista resta leggibile e
   non si perdono filtri, ordinamento o pagina.
   ============================================================================ */

.tk-con-anteprima {
    display: flex;
    align-items: flex-start;
    gap: 12px;
}

.tk-con-anteprima > .tk-griglie-area {
    /* min-width:0 e' obbligatorio: senza, una griglia larga impedisce alla propria
       colonna flex di restringersi e il pannello finisce fuori schermo */
    flex: 1 1 auto;
    min-width: 0;
}

.tk-anteprima-lato {
    flex: 0 0 420px;
    max-width: 420px;
    /* resta a vista mentre si scorre l'elenco: si passa da un ticket all'altro senza
       dover risalire ogni volta in cima alla pagina */
    position: sticky;
    top: 72px;
}

.tk-anteprima-pannello {
    display: flex;
    flex-direction: column;
    /* sotto l'app bar e sopra il footer: il pannello si scorre dentro, la pagina resta ferma */
    max-height: calc(100vh - 140px);
    overflow: hidden;
}

.tk-anteprima-testata {
    padding: 10px 12px;
    border-bottom: 1px solid var(--mud-palette-divider);
    flex: 0 0 auto;
}

.tk-anteprima-oggetto {
    margin-top: 2px;
    font-weight: 600;
    /* l'oggetto puo' essere lungo: due righe e poi taglia, senza spingere giu' il contenuto */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Come in una chat: la testata (ticket, cliente, richiesta) resta ferma e scorrono solo i
   messaggi, cosi' leggendo uno scambio lungo non si perde di vista di chi si sta parlando. */
.tk-anteprima-corpo {
    padding: 10px 12px 16px;
    overflow-y: auto;
    flex: 1 1 auto;
}

/* La richiesta sta nella parte ferma, ma con un tetto e uno scorrimento proprio: una
   descrizione lunga tenuta fissa per intero non lascerebbe spazio ai messaggi. */
.tk-anteprima-richiesta {
    max-height: 22vh;
    overflow-y: auto;
}

.tk-anteprima-dati {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.tk-anteprima-voce {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.tk-anteprima-etichetta {
    font-size: .7rem;
    line-height: 1.2;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--mud-palette-text-secondary);
}

.tk-anteprima-valore {
    font-size: .9rem;
    line-height: 1.3;
    font-weight: 600;
    word-break: break-word;
}

.tk-anteprima-titoletto {
    display: block;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--mud-palette-text-secondary);
    margin-bottom: 4px;
}

.tk-anteprima-testo {
    font-size: .88rem;
    line-height: 1.4;
    /* il testo arriva dall'editor: puo' contenere tabelle e immagini piu' larghe del pannello */
    overflow-wrap: anywhere;
}

.tk-anteprima-testo img,
.tk-anteprima-testo table {
    max-width: 100%;
    height: auto;
}

/* Lo sfondo lo decide ColoriChatTicket, lo stesso della scheda completa: verde il proprio lato,
   blu-grigio la controparte, giallino i commenti interni.
   Il testo va tenuto SCURO a prescindere dal tema: quegli sfondi sono pastelli chiari in entrambi,
   e col testo chiaro del tema scuro il messaggio diventerebbe illeggibile (in AddTicket si ottiene
   lo stesso risultato imponendo il colore della palette chiara). */
.tk-anteprima-msg {
    border: 1px solid var(--mud-palette-divider);
    border-radius: 6px;
    padding: 8px;
    margin-top: 8px;
    color: var(--mud-palette-dark);
}

.tk-anteprima-msg .tk-anteprima-msg-data,
.tk-anteprima-msg .tk-anteprima-msg-autore {
    color: inherit;
}

/* commento visibile solo all'assistenza: si deve distinguere a colpo d'occhio da una
   risposta che il cliente ha gia' letto (stessa logica della fascia in AddTicket) */
.tk-anteprima-msg-interno {
    border-color: var(--mud-palette-warning);
}

/* Commento trovato dalla ricerca nella chat: bordo che lampeggia per qualche istante e poi
   resta acceso. Il lampeggio serve a farsi trovare in uno scambio lungo; se continuasse
   all'infinito diventerebbe solo fastidioso mentre si legge. */
.tk-anteprima-msg-trovato {
    border-color: var(--mud-palette-warning);
    box-shadow: 0 0 0 2px var(--mud-palette-warning);
    animation: tk-msg-lampeggio .8s ease-in-out 4;
}

@keyframes tk-msg-lampeggio {
    0%, 100% {
        box-shadow: 0 0 0 2px transparent;
    }

    50% {
        box-shadow: 0 0 0 3px var(--mud-palette-warning);
    }
}

/* chi ha chiesto meno animazioni tiene il bordo, senza il lampeggio */
@media (prefers-reduced-motion: reduce) {
    .tk-anteprima-msg-trovato {
        animation: none;
    }
}

.tk-anteprima-msg-testata {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 4px;
    min-width: 0;
}

.tk-anteprima-msg-autore {
    font-weight: 600;
    font-size: .82rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tk-anteprima-msg-data {
    margin-left: auto;
    font-size: .72rem;
    white-space: nowrap;
    color: var(--mud-palette-text-secondary);
}

.tk-anteprima-msg-etichetta {
    display: flex;
    align-items: center;
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .03em;
    color: var(--mud-palette-warning-text);
    background-color: var(--mud-palette-warning);
    border-radius: 4px;
    padding: 1px 6px;
    margin-bottom: 4px;
    width: fit-content;
}

/* Colonna congelata: stretta quanto il pulsante e senza riempimenti, altrimenti si porta
   via spazio utile a ogni riga. Il bordo a sinistra la stacca dalle colonne che le
   scorrono sotto quando l'elenco e' piu' largo dello schermo. */
.tk-col-anteprima {
    width: 44px;
    padding: 0 !important;
    text-align: center;
    border-left: 1px solid var(--mud-palette-divider);
}

/* La colonna congelata deve COPRIRE le celle che le passano sotto, non lasciarle trasparire:
   fondo PIENO e z-index sopra il resto della riga. Senza, scorrendo l'elenco in orizzontale il
   testo dei ticket finiva a video sopra il pulsante del dettaglio. */
.mud-data-grid .mud-table-cell.tk-col-anteprima,
.mud-data-grid .mud-table-head .mud-table-cell.sticky-right {
    background-color: var(--mud-palette-surface);
    z-index: 2;
}

.tk-anteprima-cella {
    display: flex;
    justify-content: center;
    align-items: center;
}

/* Voce del menu della ricerca nella chat: titolo su una riga e, sotto, il pezzo di
   conversazione trovato. Il frammento non deve allargare il menu, quindi va troncato. */
.tk-chat-voce {
    min-width: 0;
    max-width: 100%;
}

.tk-chat-voce-titolo,
.tk-chat-voce-frammento {
    display: block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.tk-chat-voce-titolo {
    font-weight: 600;
}

/* Riga del ticket aperto in anteprima: tinta soffusa SOTTO il testo, che resta quello di
   sempre e perfettamente leggibile (niente testo bianco su chiaro). Il colore arriva dalla
   palette, quindi funziona anche in scuro. La striscia a sinistra fa capire dove si e'
   anche con l'elenco scorso in orizzontale.
   !important e' necessario: MudDataGrid con Striped assegna lo sfondo alle righe alterne. */
/* Tinta OPACA e non una velatura: le celle congelate devono restare coprenti, e con un colore
   semitrasparente il testo delle colonne che ci scorrono sotto si vedeva in trasparenza.
   color-mix tiene comunque il colore legato alla palette, quindi funziona anche in tema scuro. */
.mud-table-row.tk-riga-anteprima > td {
    /* ripiego per i browser senza color-mix: sempre meglio una tinta neutra ma COPRENTE */
    background-color: var(--mud-palette-background-gray) !important;
    background-color: color-mix(in srgb, var(--mud-palette-primary) 12%, var(--mud-palette-surface)) !important;
}

.mud-table-row.tk-riga-anteprima > td:first-child {
    box-shadow: inset 3px 0 0 var(--mud-palette-primary);
}

/* Da telefono la colonna e il pannello non si mostrano proprio (vedi AnteprimaVisibile in
   TicketsComponent). Questa regola e' la rete di sicurezza per il caso in cui la misura della
   finestra non sia ancora arrivata: invece di un pannello schiacciato accanto alla lista, si
   ottiene un pannello sotto, a tutta larghezza. */
@media (max-width: 1279px) {
    .tk-con-anteprima {
        flex-direction: column;
    }

    .tk-anteprima-lato {
        flex: 1 1 auto;
        max-width: 100%;
        width: 100%;
        position: static;
    }

    .tk-anteprima-pannello {
        max-height: 70vh;
    }
}

/* ============================================================================
   ATTESA DELLA MISURA DELLA FINESTRA

   La classe gaia-attesa-layout la mette lo script in testa ad App.razor quando
   il browser e' piu' stretto della soglia: in quel caso la prima videata
   disegnata dal server e' quella da PC (footer compreso) e va tenuta nascosta,
   altrimenti si vede comparire e sparire. La toglie gaiaSvelaLayout, chiamata
   da MainLayout appena ha ricevuto la larghezza vera e ridisegnato.

   Al posto del contenuto restano lo sfondo e una barra di avanzamento sottile
   in alto: nessuna videata bianca, e si capisce che si sta caricando.
   ============================================================================ */

.mud-layout {
    transition: opacity .28s ease;
}

html.gaia-attesa-layout .mud-layout {
    opacity: 0;
    /* quello che si vede non e' ancora definitivo: meglio non farci cliccare sopra */
    pointer-events: none;
}

html.gaia-attesa-layout::before {
    content: "";
    position: fixed;
    top: 0;
    left: 0;
    height: 3px;
    width: 40%;
    z-index: 3000;
    background: var(--mud-palette-primary, #42a5f5);
    animation: gaia-attesa-barra 1.1s ease-in-out infinite;
}

@keyframes gaia-attesa-barra {
    0% {
        transform: translateX(-100%);
    }

    100% {
        transform: translateX(250%);
    }
}
