/* ============================================================================
   CUSTOM THEME v2 — rinfrescata UI (overlay su app.min.css, caricato per ultimo)
   Strategia: ridefinire le VARIABILI del tema (sidebar/topbar) invece di
   sovrascrivere le regole — così la modalità compressa (sm), il flyout al
   hover e il centraggio icone restano quelli nativi del tema.
   - Bottoni: colori ORIGINALI (#43b3ae / #2e7b78), solo rifiniture di forma
   - Niente card inglobante: nessun bordo/sfondo sul contenitore di pagina
   - Colori status chiamate (call_row_*): NON toccati
   ============================================================================ */

:root {
    /* — token propri — */
    --id2-teal:      #43b3ae;                 /* identitario (bs-officina), invariato */
    --id2-teal-deep: #2e7b78;
    --id2-dark:      #14343d;                 /* petrolio BLU per le superfici scure */
    --id2-dark-2:    #0f2830;
    --id2-ring:      rgba(67, 179, 174, .25); /* focus ring sul teal identitario */
    --id2-line:      #e9e9ef;                 /* border color originale del tema */
    --id2-radius:    8px;
    --id2-radius-lg: 12px;

    /* — variabili DEL TEMA ridefinite: sidebar scura nativa (flyout incluso) — */
    --bs-sidebar-bg: var(--id2-dark);
    --bs-sidebar-menu-item-color: #9db7be;
    --bs-sidebar-menu-sub-item-color: #9db7be;
    --bs-sidebar-menu-item-icon-color: #9db7be;
    --bs-sidebar-menu-item-hover-color: #6fd6cf;   /* teal chiaro leggibile sul fondo scuro */
    --bs-sidebar-menu-item-active-color: #6fd6cf;
    --bs-sidebar-menu-item-active-bg-color: rgba(255, 255, 255, .07);
    --bs-sidebar-border-color: rgba(255, 255, 255, .06);

    /* — topbar scura coordinata — */
    --bs-header-bg: var(--id2-dark);
    --bs-header-item-color: #cfe0e4;
}

/* ---------------------------------------------------- icone Phosphor (assaggio) */
/* webfont @phosphor-icons peso LIGHT (tratto sottile nativo, niente trucchi):
   classi "ph-light ph-<nome>". Convive con FA Pro durante la migrazione. */
.ph-light {
    display: inline-block;
    vertical-align: -0.12em;
}
#sidebar-menu ul li a i.ph-light { font-size: 1.4rem; }
/* modificatori equivalenti alle utility FA usate nel markup migrato */
.ph-2x { font-size: 2em; }
.ph-fw { width: 1.25em; text-align: center; }
.ph-spin { animation: ph-spin 1s linear infinite; }
@keyframes ph-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

/* ------------------------------------------------------------------- topbar */
#page-topbar {
    border-bottom: 1px solid rgba(255, 255, 255, .07);
    box-shadow: none;
}
#page-topbar .navbar-header { box-shadow: none; }
/* chip chiaro dietro il logo: i loghi dei tenant sono pensati su fondo chiaro */
#page-topbar .navbar-brand-box {
    background: #ffffff;
    border-right: none;
    box-shadow: none;
}
#page-topbar .navbar-header .lead,
#page-topbar .navbar-header .text-muted { color: #9db7be !important; }
#page-topbar #vertical-menu-btn { color: #cfe0e4; }

/* sul desktop la topbar è larga quanto il box del logo (70x70): la prima riga
   della pagina vive ACCANTO a quel quadrato, non sotto. Centriamola sulla sua
   stessa banda (16px + 38px di bottone = centro a 35px, come il logo) e diamo
   respiro a sinistra: il tema partiva da 3px e i bottoni toccavano la sidebar */
@media (min-width: 993px) {
    .page-content {
        padding-top: 16px;
        padding-left: 24px;
        padding-right: 24px;
    }
}
@media (max-width: 992px) {
    .page-content {
        padding-left: 14px;
        padding-right: 14px;
    }
}
/* Profilo ed Esci: cerchio con le iniziali nell'angolo in alto a destra
   (markup in head.inc). Sul desktop la topbar non c'è oltre il logo, quindi
   il cerchio si appoggia sulla prima riga della pagina, centrato sulla stessa
   banda dei bottoni (top 16px + 38px) e scorre via con lei; la prima riga di
   ogni pagina gli lascia il posto a destra. Sul telefono la topbar è a tutta
   larghezza e fissa: il cerchio sta dentro di lei e resta fermo con lei. */
.topbar-user {
    position: absolute;
    top: 16px;
    right: 24px;
    z-index: 1001;
}
.topbar-user-btn {
    width: 38px;
    height: 38px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--id2-teal);
    color: #fff;
    font-size: .9rem;
    font-weight: 400;
    letter-spacing: .02em;
    box-shadow: 0 1px 2px rgba(20, 52, 61, .18);
    transition: background-color .15s ease, box-shadow .15s ease;
}
.topbar-user-btn:hover,
.topbar-user-btn[aria-expanded="true"] { background: var(--id2-teal-deep); }
.topbar-user-btn:focus-visible { outline: none; box-shadow: 0 0 0 .2rem var(--id2-ring); }
.topbar-user-btn { overflow: hidden; }
.topbar-user-btn img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* foto del profilo nella scheda utente (actionsUsers, solo sulla propria):
   lo stesso cerchio della topbar, più grande */
.avatar-edit-preview {
    flex: 0 0 auto;
    width: 88px;
    height: 88px;
    border-radius: 50%;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--id2-teal);
    color: #fff;
    font-size: 1.8rem;
    font-weight: 300;
    box-shadow: 0 1px 3px rgba(20, 52, 61, .18);
}
.avatar-edit-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.avatar-edit.is-busy .avatar-edit-preview { opacity: .5; }
.topbar-user .dropdown-menu { min-width: 220px; }
.topbar-user-head { padding: .5rem 1.2rem .25rem; }
.topbar-user-name { font-weight: 400; color: var(--bs-body-color); }
.topbar-user-company { font-size: .8rem; color: var(--bs-secondary-color, #74788d); }
@media (min-width: 993px) {
    .page-content > .container-fluid > .row:first-child .page-title-box,
    .page-content > .dash-header,
    #lista-commesse .comm-header-bar { padding-right: 54px; }
}
@media (max-width: 992px) {
    .topbar-user {
        position: fixed;
        right: 14px;
        z-index: 1003; /* sopra la topbar (1002), sotto le modali */
    }
    /* il nome dell'azienda nella topbar non deve finire sotto al cerchio */
    #page-topbar .navbar-header { padding-right: 60px; }
}

/* summary vuoto (<p class="lead"></p>): senza questo resta 1rem di margine
   fantasma che sfasa in basso tutta la prima riga */
.page-title-box .lead:empty { display: none; }

/* ------------------------------------------------------------------ sidebar */
/* niente regole strutturali: layout, centraggio icone e flyout restano nativi.
   Solo un'elevazione al flyout così stacca bene dal contenuto chiaro. */
body[data-sidebar-size="sm"] .vertical-menu #sidebar-menu > ul > li:hover > a {
    box-shadow: 0 6px 18px rgba(0, 0, 0, .28);
    border-radius: 0 6px 6px 0;
}
.vertical-menu { box-shadow: none; }
/* badge notifiche ben leggibile sul fondo scuro */
.vertical-menu .badge { background-color: #fd625e; color: #fff; }

/* ------------------------------------------------------------------ bottoni */
/* look "pro": flat con bordo netto un filo più scuro, micro-ombra, hover con
   profondità, active premuto. Teal identitario invariato. */
.btn {
    border-radius: var(--id2-radius);
    font-weight: 300; /* Roboto Slab: 300 = Medium reale */
    transition: background-color .15s ease, border-color .15s ease,
                box-shadow .15s ease, color .15s ease, transform .05s ease;
}
.btn:active { transform: translateY(.5px); }
.btn:focus, .btn:focus-visible { box-shadow: 0 0 0 .2rem var(--id2-ring); }

.btn-primary {
    background: linear-gradient(180deg, #4abcb6, #3ea59f);
    border: 1px solid #348f8a;
    box-shadow: 0 1px 2px rgba(15, 40, 48, .14), inset 0 1px 0 rgba(255, 255, 255, .14);
}
.btn-primary:hover, .btn-primary:focus {
    background: linear-gradient(180deg, #43b3ae, #37918c);
    border-color: var(--id2-teal-deep);
    box-shadow: 0 2px 8px rgba(46, 123, 120, .28), inset 0 1px 0 rgba(255, 255, 255, .12);
}
.btn-primary:active, .btn-primary.active {
    background: var(--id2-teal-deep) !important;
    border-color: var(--id2-teal-deep) !important;
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, .18);
}

/* secondary moderno = outline neutro su bianco (Sincro, Chiudi, export...) */
.btn-secondary {
    background: #ffffff;
    border: 1px solid #d5dde0;
    color: #3d4a52;
    box-shadow: 0 1px 2px rgba(15, 40, 48, .06);
}
.btn-secondary:hover, .btn-secondary:focus {
    background: #f3f7f7;
    border-color: #b9c6ca;
    color: #26333a;
}
.btn-secondary:active, .btn-secondary.active {
    background: #e9f0f0 !important;
    border-color: #b9c6ca !important;
    color: #26333a !important;
}
/* residuo bootstrap: il split-toggle secondary aveva un grigio scuro dedicato */
.btn-secondary.dropdown-toggle-split {
    background: #ffffff;
    border-color: #d5dde0;
    color: #3d4a52;
}

.btn-light {
    background: #ffffff;
    border: 1px solid var(--id2-line);
    color: #4a565e;
    box-shadow: 0 1px 2px rgba(15, 40, 48, .05);
}
.btn-light:hover { background: #f3f7f7; border-color: #c9d4d8; }

.btn-danger {
    background: linear-gradient(180deg, #fe716d, #f4554f);
    border: 1px solid #dd4a45;
    box-shadow: 0 1px 2px rgba(15, 40, 48, .14), inset 0 1px 0 rgba(255, 255, 255, .16);
}
.btn-danger:hover {
    background: linear-gradient(180deg, #fd625e, #e04c47);
    border-color: #c94743;
    box-shadow: 0 2px 8px rgba(221, 74, 69, .28);
}

/* bottone Allegati: identità propria (violetto) con lo stesso linguaggio pro */
.btn-attach {
    color: #5a44a6;
    background: #f5f1fd;
    border: 1px solid #d9ccf3;
    box-shadow: 0 1px 2px rgba(15, 40, 48, .05);
}
.btn-attach:hover, .btn-attach:focus {
    color: #48348c;
    background: #ece4fb;
    border-color: #c6b3ee;
}
.btn-attach i { color: #7c5cd6; }
/* il conteggio: chip nella stessa hue (bg-danger di bootstrap è !important,
   per questo il badge porta una classe dedicata invece di bg-*) */
.btn-attach .attach-count {
    background: rgba(124, 92, 214, .15);
    border: 1px solid rgba(124, 92, 214, .38);
    color: #5a44a6;
    border-radius: 999px;
    font-weight: 500;
}

/* bottone Mappa: bordo arcobaleno stile Google (la regola del tema veniva
   schiacciata dal nostro override su .btn-light: riaffermata qui, rifinita) */
.btn.google-border-btn {
    border: 2px solid transparent;
    border-radius: 999px;
    color: #3d4a52;
    background:
        linear-gradient(#fff, #fff) padding-box,
        linear-gradient(90deg, #4285f4, #ea4335, #fbbc05, #34a853) border-box;
    box-shadow: 0 1px 2px rgba(15, 40, 48, .08);
    transition: transform .15s ease, box-shadow .15s ease;
}
.btn.google-border-btn:hover {
    transform: translateY(-1px);
    color: #1e2b29;
    background:
        linear-gradient(#fff, #fff) padding-box,
        linear-gradient(90deg, #4285f4, #ea4335, #fbbc05, #34a853) border-box;
    box-shadow: 0 3px 10px rgba(15, 40, 48, .16);
}
.btn.google-border-btn i { color: #4285f4; }

/* pill dei filtri stato: tre tonalità nella stessa hue della legenda,
   SOLO sui bottoni filtro (.btns-status) — le celle stato nelle righe
   restano piene. Compatte, bordo 1px, pallino di stato prima della label;
   l'attivo è la classe .filter-active (toggolata dal JS). */
.btns-status .btn.rounded-pill {
    display: inline-flex;
    align-items: center;
    border: 1px solid transparent;
    font-weight: 500;
    font-size: .78rem;
    line-height: 1;
    padding: .45rem .9rem !important; /* batte la utility px-3 del markup */
}
.btns-status .btn.rounded-pill::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin-right: .45em;
    background: #8a97a0; /* default (TUTTE) */
    flex: 0 0 auto;
}
.btns-status .btn.call_row_open::before      { background: #a6b8bf; }
.btns-status .btn.call_row_toassign::before  { background: #aca084; }
.btns-status .btn.call_row_defined::before   { background: #54a5cb; }
.btns-status .btn.call_row_toapprove::before { background: #ac74f9; }
.btns-status .btn.call_row_closed::before    { background: #41b96e; }
.btns-status .btn.call_row_forced::before    { background: #67676e; }
.btns-status .btn.call_row_draft::before     { background: #f0aa5a; }
.btns-status .btn.filter-active {
    border-color: #d33933 !important;
    box-shadow: 0 0 0 1px #d33933;
}

/* celle stato nelle righe: stesso linguaggio tre-tonalità dei badge
   (sfondo tenue, bordino interno nella hue, testo scuro nella hue) */
.table > tbody > tr > td.call_row_open      { background-color: rgba(166, 184, 191, .18) !important; color: #4f6a74 !important; box-shadow: inset 0 0 0 1px rgba(166, 184, 191, .55); }
.table > tbody > tr > td.call_row_toassign  { background-color: rgba(172, 160, 132, .18) !important; color: #5b5037 !important; outline: 1px dashed rgba(172, 160, 132, .85); outline-offset: -1px; }
.table > tbody > tr > td.call_row_defined   { background-color: rgba(84, 165, 203, .15) !important;  color: #2a7ba3 !important; box-shadow: inset 0 0 0 1px rgba(84, 165, 203, .55); }
.table > tbody > tr > td.call_row_toapprove { background-color: rgba(172, 116, 249, .14) !important; color: #7a3fe0 !important; box-shadow: inset 0 0 0 1px rgba(172, 116, 249, .50); }
.table > tbody > tr > td.call_row_closed    { background-color: rgba(65, 185, 110, .14) !important;  color: #278a4e !important; box-shadow: inset 0 0 0 1px rgba(65, 185, 110, .50); }
.table > tbody > tr > td.call_row_forced    { background-color: rgba(103, 103, 110, .14) !important; color: #4a4a52 !important; box-shadow: inset 0 0 0 1px rgba(103, 103, 110, .50); }
.table > tbody > tr > td.call_row_draft     { background-color: rgba(255, 214, 165, .25) !important; color: #b5763a !important; box-shadow: inset 0 0 0 1px rgba(240, 170, 90, .55); }
/* errore CH: la classe è sul tr (JS), ma coloriamo SOLO la cella Cliente (3ª) */
.table > tbody > tr.call_row_error > td:nth-child(3) { background-color: rgba(145, 11, 24, .12) !important; color: #910b18 !important; box-shadow: inset 0 0 0 1px rgba(145, 11, 24, .45); }
.btns-status .btn.call_row_open      { background: rgba(166, 184, 191, .18) !important; border-color: rgba(166, 184, 191, .55); color: #4f6a74 !important; }
.btns-status .btn.call_row_toassign  { background: rgba(172, 160, 132, .18) !important; border-color: rgba(172, 160, 132, .85); border-style: dashed; color: #5b5037 !important; }
.btns-status .btn.call_row_defined   { background: rgba(84, 165, 203, .15) !important;  border-color: rgba(84, 165, 203, .55);  color: #2a7ba3 !important; }
.btns-status .btn.call_row_toapprove { background: rgba(172, 116, 249, .14) !important; border-color: rgba(172, 116, 249, .50); color: #7a3fe0 !important; }
.btns-status .btn.call_row_closed    { background: rgba(65, 185, 110, .14) !important;  border-color: rgba(65, 185, 110, .50);  color: #278a4e !important; }
.btns-status .btn.call_row_forced    { background: rgba(103, 103, 110, .14) !important; border-color: rgba(103, 103, 110, .50); color: #4a4a52 !important; }
.btns-status .btn.call_row_draft     { background: rgba(255, 214, 165, .25) !important; border-color: rgba(240, 170, 90, .55);  color: #b5763a !important; }
.btns-status .btn.btn-dark           { background: #eef1f3 !important; border-color: #c6d0d5; color: #2b3940 !important; }

/* ---- azioni nelle tabelle: gruppo segmentato "ghost" ---- */
/* icone mute su superficie bianca con divisori; il colore appare al hover
   (teal per le azioni, rosso per l'eliminazione). Zero cambi di markup. */
.table .btn-group {
    background: #fff;
    border: 1px solid #dfe6e8;
    border-radius: var(--id2-radius);
    /* NIENTE overflow:hidden — il .dropdown-menu vive dentro il gruppo e verrebbe tagliato */
    box-shadow: 0 1px 1px rgba(15, 40, 48, .04);
}
.table .btn-group > .btn:first-child { border-radius: calc(var(--id2-radius) - 1px) 0 0 calc(var(--id2-radius) - 1px) !important; }
.table .btn-group > button.btn:last-of-type { border-radius: 0 calc(var(--id2-radius) - 1px) calc(var(--id2-radius) - 1px) 0 !important; }
.table .btn-group > .btn:first-child:last-of-type { border-radius: calc(var(--id2-radius) - 1px) !important; }
.table .btn-group .btn {
    background: transparent !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    color: #5b6770;
    padding: .3rem .55rem;
}
.table .btn-group .btn + .btn { border-left: 1px solid #e8eef0 !important; }
.table .btn-group .btn:hover, .table .btn-group .btn:focus {
    background: rgba(67, 179, 174, .13) !important;
    color: var(--id2-teal-deep);
}
.table .btn-group .btn-danger:hover, .table .btn-group .btn-danger:focus {
    background: rgba(253, 98, 94, .12) !important;
    color: #d4423e;
}
.table .btn-group .btn.disabled, .table .btn-group .btn:disabled {
    color: #c3ccd1;
    background: transparent !important;
}
/* bottoni singoli dentro le celle (es. "Assegna"): ghost compatto coerente */
.table td > .btn {
    background: #fff !important;
    border: 1px solid #dfe6e8 !important;
    color: #5b6770 !important;
    box-shadow: 0 1px 1px rgba(15, 40, 48, .04) !important;
    padding: .3rem .6rem;
    font-size: .75rem;
    border-radius: var(--id2-radius) !important;
}
.table td > .btn:hover, .table td > .btn:focus {
    background: rgba(67, 179, 174, .13) !important;
    border-color: rgba(67, 179, 174, .5) !important;
    color: var(--id2-teal-deep) !important;
}
/* Bottone d'azione che chiede attenzione dentro una cella (oggi: l'accesso
   del portale da spostare sull'indirizzo nuovo di Vision). Serve una classe
   sua perche' qui sopra i .btn dentro un <td> sono forzati a bianco e grigio
   con !important: un btn-warning di Bootstrap non si vedrebbe mai, e l'avviso
   in cima alla scheda parlerebbe di un "bottone giallo" che non esiste. */
.table td > .btn.btn-attenzione {
    background: #fff4d6 !important;
    border-color: #e6b455 !important;
    color: #8a6100 !important;
}
.table td > .btn.btn-attenzione:hover,
.table td > .btn.btn-attenzione:focus {
    background: #ffe9b0 !important;
    border-color: #d9a13c !important;
    color: #6f4e00 !important;
}
/* stessi colori fuori da una cella: servono alla legenda, che il bottone lo
   fa VEDERE invece di descriverlo a parole. Dentro il <td> vince comunque la
   regola qui sopra, che ha gli stessi colori e l'!important. */
.btn.btn-attenzione {
    background: #fff4d6;
    border-color: #e6b455;
    color: #8a6100;
}


/* ------------------------------------------------------------------ tabelle */
.table thead th {
    background-color: #f4f6f8;
    color: #3d4a52;
    font-weight: 500;
}
.table-hover > tbody > tr:hover > * {
    background-color: rgba(67, 179, 174, .07);
}
.dataTables_wrapper .dataTables_length select,
.dataTables_wrapper .dataTables_filter input {
    border-radius: var(--id2-radius);
    border: 1px solid var(--id2-line);
}
.page-item.active .page-link {
    background-color: var(--id2-teal);
    border-color: var(--id2-teal);
}
.page-link { color: var(--id2-teal-deep); }

/* --------------------------------------------------------------------- form */
.form-control, .form-select { border-radius: var(--id2-radius); }
.form-control:focus, .form-select:focus {
    border-color: var(--id2-teal);
    box-shadow: 0 0 0 .2rem var(--id2-ring);
}

/* ---- occhietto "mostra password" (pagine di autenticazione) ----
   Non è un bottone d'azione ma il pezzo destro della casella: quindi stesso
   bordo e stesso fondo, e l'unica cosa colorata resta il testo che si scrive.
   Il colore è la STESSA variabile della .form-control qui sopra, non un grigio
   scritto a mano, se no a tema scuro il bottone resterebbe chiaro accanto a
   una casella scura. Un btn-outline-secondary del tema qui usciva arancione. */
.btn-toggle-password {
    background-color: var(--bs-input-bg);
    border: 1px solid var(--bs-input-border);
    color: #74788d;
}
.btn-toggle-password:hover {
    background-color: #f1f4f6;
    border-color: var(--bs-input-border);
    color: var(--id2-teal-deep);
}
.btn-toggle-password:focus {
    border-color: var(--id2-teal);
    box-shadow: 0 0 0 .2rem var(--id2-ring);
    color: var(--id2-teal-deep);
}
.form-check-input:checked {
    background-color: var(--id2-teal);
    border-color: var(--id2-teal);
}

/* ---- switch: stesso linguaggio dei badge soft ----
   fondo tenue + bordo medio nella hue + pallino scuro nella hue, invece del
   pieno teal con pallino bianco. Vale per tutti gli switch dell'app.
   Le due regole :checked che seguono devono stare DOPO .form-check-input:checked
   qui sopra, altrimenti vince il fondo pieno. */
.form-switch .form-check-input {
    background-color: #f1f4f6;
    border: 1px solid #d8e0e4;
    /* pallino grigio: stesso SVG di Bootstrap, solo il fill cambia */
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23aeb9c0'/%3e%3c/svg%3e");
    box-shadow: none;
}
.form-switch .form-check-input:focus {
    border-color: rgba(67, 179, 174, .55);
    box-shadow: 0 0 0 .2rem var(--id2-ring);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23aeb9c0'/%3e%3c/svg%3e");
}
.form-switch .form-check-input:checked {
    background-color: rgba(67, 179, 174, .16);
    border-color: rgba(67, 179, 174, .55);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%232e7b78'/%3e%3c/svg%3e");
}
.form-switch .form-check-input:checked:focus {
    box-shadow: 0 0 0 .2rem var(--id2-ring);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%232e7b78'/%3e%3c/svg%3e");
}
.form-switch .form-check-input:disabled {
    opacity: .5;
}

/* ------------------------------------------------------------------- modali */
.modal-content {
    border: none;
    border-radius: var(--id2-radius-lg);
    box-shadow: 0 12px 40px rgba(15, 40, 48, .18);
}
/* header: niente fasce colorate. Fondo bianco, gerarchia tutta tipografica e
   un solo segno di brand — un trattino teal appoggiato sulla hairline, sotto
   il titolo, come l'indicatore di un tab. Padding orizzontale identico a
   quello del body così testo e contenuto restano incolonnati. */
.modal-header {
    background: #ffffff;
    border-bottom: 1px solid var(--id2-line);
    border-top-left-radius: var(--id2-radius-lg);
    border-top-right-radius: var(--id2-radius-lg);
    padding: .95rem 1rem .8rem;
    position: relative;
}
.modal-header::after {
    content: "";
    position: absolute;
    left: 1rem;
    bottom: -1px;
    width: 44px;
    height: 2px;
    border-radius: 2px;
    background: var(--id2-teal);
}
/* azioni delicate (annullamento CH forzato): tinta calda appena accennata e
   trattino in hue di allerta — l'unica modale che deve mettere in guardia */
#closech-modal .modal-header {
    background: #fff7f6;
    border-bottom-color: #f6dedd;
}
#closech-modal .modal-header::after { background: #fd625e; }
/* backdrop tinto nel petrolio brand (solo colore: lo stacking resta al JS) */
.modal-backdrop { background-color: #0f2830; }
/* titoli modali: taglia unica contenuta, peso medio, inchiostro scuro —
   uniforma gli h3/h4 misti (che col remap pesi del Roboto Slab uscivano
   in ExtraBold/Black giganti) */
.modal-header h3, .modal-header h4, .modal-header h5, .modal-header .modal-title {
    font-size: 1.03rem;
    font-weight: 300; /* Roboto Slab: 300 = Medium reale */
    color: #17282c;
    letter-spacing: -.005em;
    margin: 0;
    display: flex;
    align-items: center;
    gap: .5em;
    line-height: 1.3;
}
.modal-header h3 i, .modal-header h4 i, .modal-header h5 i, .modal-header .modal-title i {
    color: var(--id2-teal);
    font-size: 1.05em;
}
#closech-modal .modal-header h3 i, #closech-modal .modal-header h4 i,
#closech-modal .modal-header h5 i, #closech-modal .modal-header .modal-title i { color: #e2534e; }
/* chiusura: disco fantasma invece della X nuda — bersaglio vero da 30px */
.modal-header .btn-close {
    box-sizing: border-box;
    width: 30px;
    height: 30px;
    padding: 0;
    border-radius: 50%;
    background-size: 11px auto;
    background-position: center;
    opacity: .45;
    transition: background-color .15s ease, opacity .15s ease;
}
.modal-header .btn-close:hover {
    background-color: #eef2f3;
    opacity: .95;
}
#closech-modal .modal-header .btn-close:hover { background-color: #fbe6e5; }

/* ----------------------------------------------------------------- dropdown */
.dropdown-menu {
    border: 1px solid var(--id2-line);
    border-radius: var(--id2-radius);
    box-shadow: 0 8px 24px rgba(15, 40, 48, .12);
    padding: .35rem;
}
.dropdown-item { border-radius: 6px; }
.dropdown-item:hover, .dropdown-item:focus {
    background-color: rgba(67, 179, 174, .10);
}

/* ------------------------------------------------------------------ select2 */
.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
    border-radius: var(--id2-radius);
}
.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--focus .select2-selection--multiple,
.select2-container--default.select2-container--open .select2-selection--single,
.select2-container--default.select2-container--open .select2-selection--multiple {
    border-color: var(--id2-teal);
    box-shadow: 0 0 0 .2rem var(--id2-ring);
}
.select2-dropdown {
    border: 1px solid var(--id2-line);
    border-radius: var(--id2-radius);
    box-shadow: 0 8px 24px rgba(15, 40, 48, .12);
}
.select2-container--default .select2-results__option--highlighted[aria-selected],
.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
    background-color: var(--id2-teal);
}
.select2-container--default .select2-results__option[aria-selected="true"] {
    background-color: rgba(67, 179, 174, .15);
    color: inherit;
}

/* ----------------------------------------------------------- daterangepicker */
.daterangepicker {
    border: 1px solid var(--id2-line);
    border-radius: var(--id2-radius);
    box-shadow: 0 8px 24px rgba(15, 40, 48, .12);
}
.daterangepicker td.active, .daterangepicker td.active:hover {
    background-color: var(--id2-teal);
}
.daterangepicker td.in-range { background-color: rgba(67, 179, 174, .12); }
.daterangepicker .ranges li.active { background-color: var(--id2-teal); }

/* --------------------------------------------------------------- sweetalert2 */
/* bottoni con lo stesso linguaggio "pro" dei .btn dell'app (i !important
   servono anche a vincere sui colori inline che swal imposta via JS) */
.swal2-popup { border-radius: var(--id2-radius-lg); }
.swal2-styled {
    border-radius: var(--id2-radius) !important;
    font-weight: 300;
    padding: .5em 1.2em;
}
.swal2-styled.swal2-confirm {
    background: linear-gradient(180deg, #4abcb6, #3ea59f) !important;
    border: 1px solid #348f8a !important;
    box-shadow: 0 1px 2px rgba(15, 40, 48, .14), inset 0 1px 0 rgba(255, 255, 255, .14) !important;
}
.swal2-styled.swal2-confirm:hover {
    background: linear-gradient(180deg, #43b3ae, #37918c) !important;
    border-color: var(--id2-teal-deep) !important;
    box-shadow: 0 2px 8px rgba(46, 123, 120, .28), inset 0 1px 0 rgba(255, 255, 255, .12) !important;
}
.swal2-styled.swal2-confirm:focus { box-shadow: 0 0 0 .2rem var(--id2-ring) !important; }
.swal2-styled.swal2-cancel {
    background: #ffffff !important;
    border: 1px solid #d5dde0 !important;
    color: #3d4a52 !important;
    box-shadow: 0 1px 2px rgba(15, 40, 48, .06) !important;
}
.swal2-styled.swal2-cancel:hover {
    background: #f3f7f7 !important;
    border-color: #b9c6ca !important;
    color: #26333a !important;
}
.swal2-styled.swal2-deny {
    background: linear-gradient(180deg, #fe716d, #f4554f) !important;
    border: 1px solid #dd4a45 !important;
    box-shadow: 0 1px 2px rgba(15, 40, 48, .14), inset 0 1px 0 rgba(255, 255, 255, .16) !important;
}

/* ------------------------------------------------------- pagine auth (login) */
/* scoping via :has sui form: zero modifiche al markup delle .tpl */
body:has(#login-form), body:has(#forgot-password-form), body:has(#reset-password-form) {
    background-color: #f2f6f6;
}
body:has(#login-form) .container > .w-md-50,
body:has(#forgot-password-form) .container > .w-md-50,
body:has(#reset-password-form) .container > .w-md-50 {
    background: #ffffff;
    border: 1px solid var(--id2-line);
    border-radius: var(--id2-radius-lg);
    box-shadow: 0 10px 30px rgba(15, 40, 48, .08);
    max-width: 480px;
    padding: 2rem !important;
    margin-top: 4rem;
}
/* copyright dentro la card, in coda al form: prende il posto della barra
   .footer del tema (absolute con left:250px — senza sidebar restava una
   striscia storta appesa in fondo alla pagina). Vedi views/_auth_foot.inc. */
.auth-credit {
    margin-top: 1.5rem;
    padding-top: .9rem;
    border-top: 1px solid var(--id2-line);
    text-align: center;
    font-size: .75rem;
    color: #9aa4ad;
}

/* -------------------------------------------------------------- alert soft */
/* avvisi in-modale nel linguaggio tre-tonalità */
.alert-soft {
    border: 1px solid;
    border-radius: var(--id2-radius);
    padding: .8rem 1rem;
}
.alert-soft-success { background: rgba(42, 181, 125, .10);  border-color: rgba(42, 181, 125, .35);  color: #1f8f62; }
.alert-soft-danger  { background: rgba(253, 98, 94, .09);   border-color: rgba(253, 98, 94, .35);   color: #d4423e; }
.alert-soft-warning { background: rgba(255, 176, 66, .13);  border-color: rgba(240, 150, 40, .40);  color: #b06a14; }
/* info: informativo, non un problema — es. "manca, ma lo crea un aggiornamento in coda" */
.alert-soft-info    { background: rgba(67, 179, 174, .10);  border-color: rgba(67, 179, 174, .35);  color: #2b8480; }
/* neutro: non è uno stato, è un "manca un dato per dirti qualcosa" */
.alert-soft-neutral { background: #f1f4f6;                   border-color: #d8e0e4;                  color: #5b6770; }
.alert-soft .text-muted { color: inherit !important; opacity: .75; }

/* --------------------------------- scheda utente: la password a mano
   È una card che si apre, ma un <details> senza aiuto sembra testo: niente
   dice che ci si può cliccare sopra. Qui la riga diventa una barra con hover e
   una freccia che ruota, cioè le due cose che si guardano per capirlo. */

/* overflow invece di ricalcolare i raggi: la barra grigia è un rettangolo, e
   sopra una card arrotondata gli angoli le sbordano fuori. Così viene ritagliata
   dal raggio della card qualunque esso sia, aperta o chiusa. */
#password-exception { overflow: hidden; }

#password-exception > summary {
  cursor: pointer;
  list-style: none;                 /* via il triangolino di serie: ne mettiamo uno nostro */
  margin: 0;
  transition: background-color .15s ease;
}
#password-exception > summary::-webkit-details-marker { display: none; }
#password-exception > summary:hover  { background-color: rgba(0, 0, 0, .03); }
#password-exception[open] > summary  { background-color: rgba(0, 0, 0, .02); }

/* la freccia non deve stringersi quando il testo accanto va a capo */
#password-exception > summary [data-role="chevron"] {
  flex: 0 0 auto;
  transition: transform .15s ease;
}
#password-exception[open] > summary [data-role="chevron"] { transform: rotate(90deg); }

/* l'ultimo campo del blocco porta il suo margine fino al bordo: senza questo
   il fondo della card ha il doppio dello spazio degli altri lati */
#password-exception #password-section > .row:last-child .mb-3:last-child { margin-bottom: 0 !important; }

/* --------------------------------- modali storico (rapportini + CH) */
.hist-label {
    font-size: .66rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: #74788d;
}
.hist-value { color: #1e2b29; font-weight: 300; }
.hist-section {
    font-size: .95rem;
    font-weight: 400; /* Bold reale */
    color: #1e2b29;
    display: flex;
    align-items: center;
    gap: .5em;
    margin: 0 0 .6rem;
    padding-bottom: .45rem;
    border-bottom: 1px solid var(--id2-line);
}
.hist-section i { color: var(--id2-teal); }
.hist-table td { vertical-align: middle; padding-top: .55rem; padding-bottom: .55rem; }
.hist-table .hist-date { color: #74788d; font-size: .74rem; margin-left: .35em; }
.hist-table tr.hist-current > td {
    background-color: rgba(67, 179, 174, .09);
}
.hist-table tr.hist-current > td:first-child {
    box-shadow: inset 3px 0 0 var(--id2-teal);
}
/* accordion dello storico CH (le regole inline del case sono state rimosse) */
.expandable-row { cursor: pointer; }
.expandable-row:hover > td { background-color: rgba(67, 179, 174, .07); }
.expand-icon { font-size: 1rem; color: #74788d; }
.detail-row { display: none; }
/* Gestione Clienti apre le righe con questa classe invece che con uno style
   inline: .show() di jQuery su un <tr> rimette display:'' e la regola qui
   sopra lo rinasconderebbe. */
.detail-row.is-open { display: table-row; }
.detail-row > td { background: #f7fafa; }
/* la tabella per-utente dentro una riga aperta: sfondo del pannello, non
   bianco a strisce come una griglia a sé */
.detail-content > .table { background: transparent; }
.detail-content > .table > thead th {
    border-top: 0;
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .02em;
    color: #74788d;
}
.detail-content {
    padding: 12px 14px;
    border-left: 3px solid var(--id2-teal);
    border-radius: 0 6px 6px 0;
}
.hist-desc-row > td { background: #fbfdfd; padding: .5rem .75rem .8rem; }
.hist-desc { color: #384250; }
.hist-counter {
    background: #fff;
    border: 1px solid var(--id2-line);
    border-radius: var(--id2-radius);
    padding: 8px 10px;
    height: 100%;
}
.hist-counter-value {
    font-weight: 400; /* Bold reale */
    color: #1e2b29;
    font-size: 1.05rem;
    font-variant-numeric: tabular-nums;
}

/* separatore-giorni nelle tabelle chiamate: banda sottile, niente hover */
.table tr.separator > td {
    background-color: #e3eaec !important;
    height: 5px !important;
    padding: 0 !important;
    border: 0 !important;
    font-size: 0 !important;
    line-height: 0 !important;
}
.table-hover tr.separator:hover > td { background-color: #e3eaec !important; }

/* -------------------------------------------------------------- badge soft */
/* linguaggio unico per gli stati: pillola con la stessa hue in tre tonalità
   (sfondo tenue, bordo medio, testo scuro) — stile moderno */
.badge-soft {
    display: inline-flex;
    align-items: center;
    gap: .35em;
    padding: .35em .7em;
    border-radius: 999px;
    border: 1px solid transparent;
    font-size: .72rem;
    font-weight: 300;
    line-height: 1;
    white-space: nowrap;
}
.badge-soft-success { background: rgba(42, 181, 125, .12);  border-color: rgba(42, 181, 125, .40);  color: #1f8f62; }
.badge-soft-danger  { background: #fff;                     border-color: rgba(198, 40, 40, .60);  color: #c62828; }
.badge-soft-warning { background: rgba(255, 176, 66, .16);  border-color: rgba(240, 150, 40, .45);  color: #b06a14; }
.badge-soft-info    { background: rgba(75, 166, 239, .12);  border-color: rgba(75, 166, 239, .40);  color: #2f7fc4; }
.badge-soft-teal    { background: rgba(67, 179, 174, .12);  border-color: rgba(67, 179, 174, .45);  color: #2e7b78; }
.badge-soft-neutral { background: #f1f4f6;                  border-color: #d8e0e4;                  color: #5b6770; }
/* dettaglio approvazione: righe etichetta/valore separate da una linea, tranne
   l'ultima — una riga di chiusura sul fondo sembra una tabella troncata */
.appr-detail-row { border-bottom: 1px solid var(--id2-line, #e6ecef); }
.appr-detail-row:last-child { border-bottom: 0; }
/* approvazione in corso: viola perché non è né un esito buono né uno cattivo,
   è un'attesa — e le altre pillole dello Storico Rapportini quei due colori
   se li sono già presi (verde approvato, rosso rimandato indietro) */
.badge-soft-purple  { background: rgba(124, 92, 214, .12);  border-color: rgba(124, 92, 214, .40);  color: #6244bd; }
.badge-soft-dark    { background: #e9edf0;                  border-color: #c9d2d7;                  color: #37424a; }
/* scadenza contratto: giallo e rosso non sono della stessa hue apposta — è la
   sola pillola che segnala una data addosso al cliente, non uno stato interno */
.badge-soft-scadenza { background: #fdf4bf;                 border-color: #ecd98a;                  color: #d4423e; font-weight: 500; }
/* taglia grande per i contatori sopra le tabelle */
.badge-soft-lg { font-size: .82rem; padding: .5em .95em; }
/* pillola che è un bottone: stessa faccia delle altre (un <button> si porta
   dietro font e bordi suoi), ma si vede che ci si può cliccare */
.badge-soft-btn {
    font-family: inherit;
    cursor: pointer;
    transition: filter .12s ease;
}
.badge-soft-btn:hover  { filter: brightness(.95); }
.badge-soft-btn:active { filter: brightness(.9); }
.badge-soft-btn i { opacity: .7; }

/* --------------------------------------------- legenda "Legenda & regole" */
/* Le voci mostrano le pillole VERE della pagina (badge-soft, icone comprese):
   una legenda con pillole di un altro colore fa indovinare a quale etichetta
   si riferisce. Qui serve solo l'aria per staccare una voce dall'altra e un
   campione statico per i bottoni che il testo cita. */
.legend-list li { margin-bottom: .5rem; line-height: 1.55; }
.legend-list li:last-child { margin-bottom: 0; }
.legend-list .badge-soft { margin-right: .4rem; }
.legend-btn {
    pointer-events: none;
    padding: .12rem .42rem;
    font-size: .8rem;
    vertical-align: middle;
}

/* ------------------------------------------------- vista tecnico a card */
/* card chiamata: superficie bianca, barra accent sinistra nella hue dello
   status (stesse hue di pill e celle), label allineate. Markup intatto. */
#calls-container .call {
    background: #fff !important;
    border: 1px solid var(--id2-line) !important;
    border-left: 4px solid #a6b8bf !important; /* default: aperta */
    border-radius: var(--id2-radius-lg);
    padding: 14px 16px;
    box-shadow: 0 1px 2px rgba(15, 40, 48, .05);
    transition: box-shadow .15s ease;
}
#calls-container .call:hover { box-shadow: 0 4px 14px rgba(15, 40, 48, .10); }
/* barra accent + gradiente diagonale: la hue dello stato sfuma nel bianco */
#calls-container .call.call_row_open      { border-left-color: #a6b8bf !important; background: linear-gradient(135deg, rgba(166, 184, 191, .20) 0%, rgba(255, 255, 255, 0) 45%) #fff !important; }
#calls-container .call.call_row_draft     { border-left-color: #f0aa5a !important; background: linear-gradient(135deg, rgba(240, 170, 90, .18) 0%,  rgba(255, 255, 255, 0) 45%) #fff !important; }
#calls-container .call.call_row_defined   { border-left-color: #54a5cb !important; background: linear-gradient(135deg, rgba(84, 165, 203, .17) 0%,  rgba(255, 255, 255, 0) 45%) #fff !important; }
#calls-container .call.call_row_toapprove { border-left-color: #ac74f9 !important; background: linear-gradient(135deg, rgba(172, 116, 249, .15) 0%, rgba(255, 255, 255, 0) 45%) #fff !important; }
#calls-container .call.call_row_closed    { border-left-color: #41b96e !important; background: linear-gradient(135deg, rgba(65, 185, 110, .15) 0%,  rgba(255, 255, 255, 0) 45%) #fff !important; }
#calls-container .call.call_row_forced    { border-left-color: #67676e !important; background: linear-gradient(135deg, rgba(103, 103, 110, .15) 0%, rgba(255, 255, 255, 0) 45%) #fff !important; }
/* righe label/valore allineate */
#calls-container .call .card-label {
    display: flex;
    gap: .6em;
    padding: .16rem 0;
    color: #1e2b29;
}
#calls-container .call .card-label > span:first-child {
    flex: 0 0 5.2rem;
    color: #74788d;
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    padding-top: .15em;
}
/* pillola di stato in alto a destra (nome dello stato, non solo colore) */
#calls-container .call { position: relative; }
#calls-container .call::after {
    position: absolute;
    top: 12px;
    right: 14px;
    font-size: .66rem;
    font-weight: 500;
    letter-spacing: .03em;
    text-transform: uppercase;
    padding: .35em .75em;
    border-radius: 999px;
    border: 1px solid;
    line-height: 1;
}
#calls-container .call.call_row_open::after      { content: "Da fare";         background: rgba(166, 184, 191, .18); border-color: rgba(166, 184, 191, .55); color: #4f6a74; }
#calls-container .call.call_row_draft::after     { content: "Bozza";           background: rgba(255, 214, 165, .25); border-color: rgba(240, 170, 90, .55);  color: #b5763a; }
#calls-container .call.call_row_defined::after   { content: "Da definire";     background: rgba(84, 165, 203, .15);  border-color: rgba(84, 165, 203, .55);  color: #2a7ba3; }
#calls-container .call.call_row_toapprove::after { content: "In approvazione"; background: rgba(172, 116, 249, .14); border-color: rgba(172, 116, 249, .50); color: #7a3fe0; }
#calls-container .call.call_row_closed::after    { content: "Chiusa";          background: rgba(65, 185, 110, .14);  border-color: rgba(65, 185, 110, .50);  color: #278a4e; }
#calls-container .call.call_row_forced::after    { content: "Annullata";       background: rgba(103, 103, 110, .14); border-color: rgba(103, 103, 110, .50); color: #4a4a52; }
/* zona bottoni separata da un divisore */
#calls-container .call > .d-flex {
    border-top: 1px solid #eef1f3;
    padding-top: 12px;
    margin-top: 10px;
}
/* gerarchia bottoni: Dettagli resta primario, Last Rapp. e Azioni neutri outline */
#calls-container .call .btn-info,
#calls-container .call .btn-secondary {
    background: #ffffff !important;
    border: 1px solid #d5dde0 !important;
    color: #3d4a52 !important;
    box-shadow: 0 1px 2px rgba(15, 40, 48, .06) !important;
}
#calls-container .call .btn-info:hover,
#calls-container .call .btn-secondary:hover {
    background: #f3f7f7 !important;
    border-color: #b9c6ca !important;
}
#calls-container .call .btn-info.disabled { color: #b6c0c6 !important; }

/* ---------------------------------------------------------------- dashboard */
/* il canvas tinto NON è più esclusivo della dashboard: sta nella classe
   .page-canvas (sezione "CANVAS TINTO" più sotto), che dashboard e viste
   con DataTable condividono. Qui restano solo le rifiniture della dashboard. */
#dashboard .dash-header h4 {
    font-size: 1.4rem;
    font-weight: 400; /* Bold reale nel remap Roboto Slab */
    color: #1e2b29;
}
#dashboard .dash-subtitle { color: #74788d; font-size: .82rem; }
#dashboard .kpi-card,
#dashboard .dash-card {
    border-color: #e3eae8;
    box-shadow: 0 1px 3px rgba(15, 40, 48, .07);
}

/* stat tile: numero in inchiostro, lo stato lo dice il chip (stessi colori
   della legenda chiamate) */
#dashboard .kpi-card {
    background: #fff;
    border: 1px solid var(--id2-line);
    border-radius: var(--id2-radius-lg);
    padding: 14px 16px;
    height: 100%;
    box-shadow: 0 1px 2px rgba(15, 40, 48, .04);
}
#dashboard .kpi-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
}
#dashboard .kpi-label {
    font-size: .66rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: #74788d;
    font-weight: 300;
    line-height: 1.25;
}
#dashboard .kpi-chip {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: .95rem;
    flex: 0 0 auto;
}
/* tinte chip: hue della legenda al ~15%, icona nella stessa hue scurita */
#dashboard .kpi-chip-neutral   { background: #f0f3f5;                 color: #74788d; }
#dashboard .kpi-chip-dafare    { background: rgba(166, 184, 191, .20); color: #5f7a84; }
#dashboard .kpi-chip-assegnare { background: rgba(172, 160, 132, .18); color: #5b5037; border: 1px dashed rgba(172, 160, 132, .85); }
#dashboard .kpi-chip-definire  { background: rgba(84, 165, 203, .15);  color: #2a7ba3; }
#dashboard .kpi-chip-success   { background: rgba(42, 181, 125, .14);  color: #1f8f62; }
#dashboard .kpi-chip-info      { background: rgba(75, 166, 239, .14);  color: #2f7fc4; }
#dashboard .kpi-value {
    font-size: 1.65rem;
    font-weight: 400; /* Roboto Slab: 400 mappa sul Bold reale */
    color: #1e2b29;
    margin-top: 6px;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

/* action card (riga "da fare adesso") */
#dashboard .dash-action {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px;
}
#dashboard .dash-action .kpi-chip { width: 40px; height: 40px; font-size: 1.1rem; }
#dashboard .kpi-chip-toapprove { background: rgba(172, 116, 249, .14); color: #7a3fe0; }
#dashboard .dash-action .kpi-value { margin-top: 0; }
#dashboard .dash-action-label { color: #74788d; font-size: .78rem; line-height: 1.35; }

/* card contenuto (grafico, liste) */
#dashboard .dash-card {
    background: #fff;
    border: 1px solid var(--id2-line);
    border-radius: var(--id2-radius-lg);
    box-shadow: 0 1px 2px rgba(15, 40, 48, .04);
    overflow: hidden;
}
#dashboard .dash-card-header { padding: 14px 16px 4px; }
#dashboard .dash-card-header h6 { margin: 0; font-weight: 400; color: #1e2b29; }
#dashboard .dash-card-header small { color: #74788d; }
#dashboard .dash-card-body { padding: 8px 12px 12px; }
#dashboard .dash-card-body.p-0 { padding: 0 0 6px; }

/* liste classifica: niente medaglie colorate, magnitudine = barra teal */
#dashboard .dash-list td {
    border: 0;
    padding: .5rem 1rem;
    vertical-align: middle;
}
#dashboard .dash-list .dash-rank {
    width: 30px;
    padding-right: 0;
    color: #9aa4ad;
    font-size: .72rem;
    text-align: center;
}
#dashboard .dash-name { color: #384250; }
#dashboard .dash-count {
    font-weight: 400; /* Bold reale */
    color: #1e2b29;
    font-size: .82rem;
    font-variant-numeric: tabular-nums;
}
#dashboard .dash-bar {
    height: 4px;
    background: #eef1f3;
    border-radius: 2px;
    overflow: hidden;
    margin-top: 3px;
}
#dashboard .dash-bar-fill {
    height: 100%;
    background: var(--id2-teal);
    border-radius: 2px;
}

/* header di card con un'azione a destra (oggi: «Vedi tutti» di Top clienti) */
#dashboard .dash-card-header-split {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .5rem;
}
/* link d'azione della card: e' un <button> (apre una modale, non e' un
   indirizzo), quindi il bottone va spogliato del suo aspetto di bottone */
#dashboard .dash-card-link {
    background: none;
    border: 0;
    padding: 0;
    white-space: nowrap;
    font-size: .76rem;
    color: var(--id2-teal);
    line-height: 1.4;
}
#dashboard .dash-card-link:hover { text-decoration: underline; }
#dashboard .dash-card-link i { font-size: .8rem; vertical-align: -1px; }

/* ── MODALE «tutti i clienti» ──────────────────────────────────────────────
   Le stesse tre classi del riquadro (nome, numero, barra di magnitudine): la
   modale e' lo stesso elenco piu' lungo, non un'altra tabella. Sono ripetute e
   non aggiunte al selettore #dashboard perche' modal-stacking.js sposta ogni
   modale sotto <body> appena si apre, cioe' FUORI da #dashboard: una regola
   scoped li' smetterebbe di applicarsi proprio quando la modale si vede. */
#all-customers-modal .dash-name { color: #384250; }
#all-customers-modal .dash-count {
    font-weight: 400;
    color: #1e2b29;
    font-size: .85rem;
    font-variant-numeric: tabular-nums;
}
#all-customers-modal .dash-bar {
    height: 4px;
    background: #eef1f3;
    border-radius: 2px;
    overflow: hidden;
    margin-top: 3px;
}
#all-customers-modal .dash-bar-fill {
    height: 100%;
    background: var(--id2-teal);
    border-radius: 2px;
}
/* la riga sotto il nome (codice cliente) e la quota accanto al totale */
#all-customers-modal .dash-sub {
    font-size: .7rem;
    color: #9aa4ad;
    font-variant-numeric: tabular-nums;
}
#all-customers-modal .modal-header { align-items: flex-start; }

/* ========================================================================== */
/* EDITOR EMAIL DI SISTEMA — accordion in scheda azienda + modale impostazioni */
/* -------------------------------------------------------------------------- */
/* L'accordion di Bootstrap aperto si tinge di giallo/arancio (variabili del   */
/* tema): fuori dal linguaggio dell'app. Qui l'aperto è bianco con un trattino */
/* teal a sinistra — lo stesso segno degli header delle modali.                */
/* Tutto scoped su .sysemails-accordion / .sysemail-*: gli altri accordion del */
/* tema non c'entrano.                                                         */
/* ========================================================================== */
.sysemails-accordion { border: 1px solid var(--id2-line); border-radius: var(--id2-radius-lg); overflow: hidden; }
.sysemails-accordion .accordion-item { border: 0; border-bottom: 1px solid var(--id2-line); background: #fff; }
.sysemails-accordion .accordion-item:last-child { border-bottom: 0; }
.sysemails-accordion .accordion-button {
    background: #fff;
    box-shadow: none;
    padding: .85rem 1rem;
    position: relative;
}
.sysemails-accordion .accordion-button:not(.collapsed) {
    background: #fff;
    color: inherit;
    box-shadow: inset 0 -1px 0 var(--id2-line);
}
/* il segno dell'aperto: trattino teal a sinistra, come i modal header */
.sysemails-accordion .accordion-button:not(.collapsed)::before {
    content: "";
    position: absolute;
    left: 0;
    top: .8rem;
    bottom: .8rem;
    width: 3px;
    border-radius: 0 2px 2px 0;
    background: var(--id2-teal);
}
.sysemails-accordion .accordion-button:focus { box-shadow: none; border-color: transparent; }
.sysemails-accordion .accordion-button::after { filter: grayscale(1) opacity(.5); }
.sysemails-accordion .accordion-body { padding: 1rem; background: #fbfcfd; }

.sysemail-head { display: flex; flex-direction: column; gap: .25rem; }
.sysemail-head-top { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.sysemail-type { font-weight: 500; color: #1e2b29; }
.sysemail-when { font-size: .78rem; color: #74788d; font-weight: 300; }

/* ---- aggiornamenti (migrazioni DB), tab del pannello Impostazioni ---- */
.migration-item {
    background: #fff;
    border: 1px solid #e9edf0;
    border-radius: var(--id2-radius);
    padding: .8rem 1rem;
    margin-bottom: .6rem;
}
.migration-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}
.migration-head.js-migration-toggle { cursor: pointer; }
.migration-title { font-weight: 500; color: #1e2b29; }
.migration-caret { color: #9aa4ad; font-size: .9em; }
.migration-name { font-size: .72rem; color: #9aa4ad; font-family: monospace; }
.migration-detail { margin-top: .6rem; }
/* elenco dei file da caricare via FTP: è la ragione per cui si apre la riga,
   quindi sta in cima. Le modifiche al DB vengono dopo, come contorno. */
.migration-files-box {
    margin-top: .6rem;
    padding-top: .6rem;
    border-top: 1px dashed #e3eae8;
}
.migration-files-title {
    font-size: .72rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #74788d;
    margin-bottom: .35rem;
}
.migration-todo-box { margin-top: .8rem; }

/* ---- guida al deploy (modale del tab Aggiornamenti) ---- */
.deploy-guide { color: #37424a; }
.deploy-guide p { margin-bottom: .4rem; }
.deploy-steps {
    list-style: none;
    counter-reset: deploy;
    padding: 0;
    margin: 0 0 1.5rem;
}
.deploy-steps > li {
    counter-increment: deploy;
    position: relative;
    padding: 0 0 1rem 2.6rem;
    border-left: 1px solid var(--id2-line);
    margin-left: .9rem;
}
.deploy-steps > li:last-child { border-left-color: transparent; padding-bottom: 0; }
/* pallino numerato sulla linea verticale: la sequenza si legge a colpo d'occhio */
.deploy-steps > li::before {
    content: counter(deploy);
    position: absolute;
    left: -.9rem;
    top: -.15rem;
    width: 1.8rem;
    height: 1.8rem;
    border-radius: 50%;
    background: var(--id2-teal);
    color: #fff;
    font-size: .8rem;
    font-weight: 500;
    display: flex;
    align-items: center;
    justify-content: center;
}
.deploy-steps > li > strong { color: #1e2b29; }
/* Il comando del deploy: si legge e si copia, quindi niente a capo automatici
   (una riga di comando spezzata a meta' si incolla sbagliata) e scorrimento
   orizzontale se la finestra e' stretta. */
.deploy-cmd {
    margin: .5rem 0 .6rem;
    padding: .7rem .9rem;
    background: #1e2b29;
    color: #e7efec;
    border-radius: .4rem;
    font-size: .82rem;
    line-height: 1.7;
    overflow-x: auto;
    white-space: pre;
}
.deploy-cmd code { color: inherit; background: none; padding: 0; }
.deploy-cmd-note { color: #8aa39c; }
.deploy-h {
    margin-top: 1.2rem;
    padding-top: .8rem;
    border-top: 1px solid var(--id2-line);
    font-weight: 500;
    color: #1e2b29;
}
.deploy-guide code {
    background: #f7fafa;
    padding: .1rem .35rem;
    border-radius: 4px;
    color: #37424a;
}

/* ---- pubblica online (deploy automatico, solo nel sito locale) ---- */
.deploy-shell {
    background: #fff;
    border: 1px solid rgba(67, 179, 174, .45);
    border-radius: var(--id2-radius);
    padding: 1rem 1.1rem;
}
.deploy-eyebrow {
    font-size: .7rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--id2-teal);
}
.deploy-min0 { min-width: 0; }
.deploy-break { overflow-wrap: anywhere; word-break: break-word; }
.deploy-target {
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: .6rem;
    padding: .8rem .9rem;
    border: 1px solid #e9edf0;
    border-radius: var(--id2-radius);
    transition: border-color .15s;
}
.deploy-target:hover { border-color: #b9c4ca; }
.deploy-target-name { font-weight: 500; color: #1e2b29; }
.deploy-key { font-family: monospace; font-size: .72rem; color: #9aa4ad; }
.deploy-details > summary { cursor: pointer; color: #37424a; }
.deploy-box { border: 1px solid #e9edf0; border-radius: var(--id2-radius); padding: .5rem .75rem; }
.deploy-filelist {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 18rem;
    overflow-y: auto;
    font-family: monospace;
    font-size: .74rem;
}
.deploy-why { width: 3.8rem; flex-shrink: 0; }
.deploy-why.is-nuovo { color: #1f8f62; }
.deploy-why.is-diverso { color: #2f7fc4; }
.deploy-table { font-size: .8rem; }
.deploy-tile { height: 100%; border: 1px solid #e9edf0; border-radius: var(--id2-radius); padding: .6rem .75rem; }
.deploy-tile-num { font-size: 1.25rem; font-weight: 500; color: #1e2b29; }
.deploy-option { padding-top: .45rem; padding-bottom: .45rem; margin-bottom: 0; border-bottom: 1px solid #f1f4f6; }
.deploy-option:last-child { border-bottom: 0; }
/* barra di avanzamento: verde finché va, rossa se si ferma, ambra con avvisi */
.deploy-bar { height: .5rem; border-radius: 999px; background: #e9edf0; overflow: hidden; }
.deploy-bar > span { display: block; height: 100%; border-radius: inherit; background: #2ab57d; transition: width .4s ease; }
.deploy-bar.is-failed > span { background: #fd625e; }
.deploy-bar.is-warning > span { background: #f0a030; }
.deploy-bar-sm { height: .3rem; max-width: 16rem; }
.deploy-phases {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(12.5rem, 1fr));
    gap: .5rem;
    list-style: none;
    margin: 0;
    padding: 0;
}
.deploy-phase { display: flex; gap: .6rem; align-items: flex-start; padding: .55rem .7rem; border: 1px solid #e9edf0; border-radius: var(--id2-radius); background: #fff; color: #37424a; }
.deploy-phase-label { font-size: .85rem; font-weight: 500; }
.deploy-phase.is-pending { color: #9aa4ad; background: #f9fbfb; }
.deploy-phase.is-running { border-color: rgba(42, 181, 125, .55); box-shadow: 0 0 0 3px rgba(42, 181, 125, .10); }
.deploy-phase.is-failed { border-color: rgba(253, 98, 94, .45); background: rgba(253, 98, 94, .06); }
.deploy-phase.is-warning { border-color: rgba(240, 150, 40, .45); background: rgba(255, 176, 66, .08); }
.deploy-phase.is-skipped { color: #9aa4ad; }
.deploy-dot { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 1.25rem; height: 1.25rem; margin-top: .05rem; border-radius: 50%; font-size: .7rem; font-weight: 700; line-height: 1; }
.deploy-dot-pending { border: 2px solid #cfd8dc; }
.deploy-dot-done { background: #2ab57d; color: #fff; }
.deploy-dot-skipped { background: #e9edf0; color: #74788d; }
.deploy-dot-warning { background: #f0a030; color: #fff; }
.deploy-dot-failed { background: #fd625e; color: #fff; }
.deploy-phase-spinner { flex: none; font-size: 1.25rem; line-height: 1; color: #2ab57d; }
/* il registro: scuro come i comandi della guida, a righe colorate per livello */
.deploy-log { height: 20rem; overflow-y: auto; padding: .6rem .75rem; border-radius: .4rem; background: #1e2b29; color: #cfdcd8; font: .74rem/1.5 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }
.deploy-log-line { display: flex; gap: .5rem; white-space: pre-wrap; overflow-wrap: anywhere; }
.deploy-log-time { flex: none; color: #7c948d; }
.deploy-log-mark { flex: none; width: .8rem; text-align: center; }
.deploy-log-line.is-phase { margin-top: .35rem; color: #7fd3cf; font-weight: 700; }
.deploy-log-line.is-ok { color: #7fe0b0; }
.deploy-log-line.is-warn { color: #ffd27a; }
.deploy-log-line.is-error { color: #ff9e9b; font-weight: 600; }
.deploy-log-line.is-detail { color: #8aa39c; padding-left: 1.3rem; }
.deploy-log.hide-details .deploy-log-line.is-detail { display: none; }

/* confronto struttura database (campi/template attesi vs presenti) */
.schema-group { margin-bottom: .8rem; }
.schema-group-title {
    font-size: .78rem;
    font-weight: 500;
    color: #37424a;
    margin-bottom: .3rem;
}
.schema-items {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem .8rem;
    font-size: .78rem;
}
.schema-items code {
    background: #f7fafa;
    padding: .1rem .4rem;
    border-radius: 4px;
    color: #37424a;
}
.migration-files { list-style: none; margin: 0; padding: 0; }
.migration-files li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    padding: .3rem 0;
    border-bottom: 1px solid #f2f5f7;
    font-size: .78rem;
}
.migration-files li:last-child { border-bottom: 0; }
.migration-files code {
    color: #37424a;
    background: #f7fafa;
    padding: .1rem .4rem;
    border-radius: 4px;
    word-break: break-all;
}
.migration-file-date { color: #9aa4ad; font-size: .72rem; }
.migration-file-why { flex: 1 1 100%; color: #74788d; font-size: .72rem; }
.migration-item .migration-log {
    background: #f7fafa;
    border-radius: 6px;
    padding: .5rem .7rem;
    color: #37424a;
    font-family: monospace;
    font-size: .75rem;
    max-height: 220px;
    overflow: auto;
}

/* ---- cron (tab Cron del pannello Impostazioni) ---- */
.cron-box {
    background: #f7fafa;
    border: 1px solid #e9edf0;
    border-radius: var(--id2-radius);
    padding: 1rem;
}
.cron-url-row { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.cron-url {
    flex: 1 1 320px;
    background: #fff;
    border: 1px solid #e3eae8;
    border-radius: 6px;
    padding: .45rem .6rem;
    color: #1e2b29;
    font-size: .82rem;
    word-break: break-all;
}
.cron-kv {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: .22rem 0;
    border-bottom: 1px dashed #e3eae8;
    font-size: .82rem;
}
.cron-kv:last-child { border-bottom: 0; }
.cron-kv span { color: #74788d; }
.cron-steps { padding-left: 1.1rem; margin-bottom: .4rem; }
.cron-steps li, .cron-rules li { margin-bottom: .45rem; font-size: .85rem; color: #37424a; }
.cron-rules { padding-left: 1.1rem; margin-bottom: 0; }
.cron-params td { font-size: .82rem; vertical-align: middle; }
.cron-legacy { list-style: none; padding: 0; margin: 0; }
.cron-legacy li { padding: .25rem 0; font-size: .82rem; border-bottom: 1px solid #f2f5f7; }
.cron-legacy li:last-child { border-bottom: 0; }
.cron-runs-table td { font-size: .8rem; }
.cron-run-icon { width: 28px; }
.cron-run-ok .cron-run-icon   { color: #3aa17e; }
.cron-run-skip .cron-run-icon { color: #c99a2e; }
.cron-run-err .cron-run-icon  { color: #d15b5b; }
.cron-run-date { color: #9aa4ad; font-size: .75rem; }
.cron-run-text { font-family: monospace; color: #37424a; word-break: break-word; }
.cron-chan-table td, .cron-chan-table th { font-size: .8rem; }
.cron-chan-name { font-size: .72rem; color: #9aa4ad; font-family: monospace; }
.cron-chan-last {
    font-family: monospace;
    font-size: .72rem;
    max-width: 320px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ---- etichette (tab del pannello Impostazioni) ----
   Le etichette sono raggruppate per SEZIONE dell'app (vedi _labels.php): il
   blocco deve leggersi come "questa schermata", non come una tabella unica di
   caselle numerate. */
.label-jump { display: flex; flex-wrap: wrap; gap: .4rem; }
.label-jump-btn {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    cursor: pointer;
    font-family: inherit;
}
.label-jump-btn:hover { border-color: var(--id2-teal); color: var(--id2-teal-deep); }
.label-jump-count {
    background: #fff;
    border-radius: 20px;
    padding: 0 .35rem;
    font-size: .68rem;
    color: #74788d;
}
.label-section {
    border: 1px solid var(--id2-line);
    border-radius: var(--id2-radius);
    padding: .9rem 1rem .2rem;
    margin-bottom: 1rem;
    scroll-margin-top: 1rem;
}
.label-section-head {
    display: flex;
    align-items: flex-start;
    gap: .7rem;
    margin-bottom: .6rem;
}
.label-section-icon {
    flex: 0 0 auto;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: rgba(67, 179, 174, .12);
    color: var(--id2-teal-deep);
    display: flex;
    align-items: center;
    justify-content: center;
}
.label-section-title { font-weight: 500; color: #1e2b29; }
.label-section-where { font-size: .78rem; color: #74788d; }
.label-table th {
    font-size: .72rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #74788d;
}
.label-mod-code { font-size: .66rem; color: #9aa4ad; font-family: monospace; text-transform: none; }
.label-what { font-size: .85rem; color: #37424a; }
.label-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem;
    margin-top: .15rem;
}
.label-meta code { font-size: .7rem; color: #9aa4ad; background: #f7fafa; padding: .05rem .3rem; border-radius: 4px; }
.label-meta .badge-soft { font-size: .66rem; }
/* lo specchio di una chiave condivisa: stesso testo, ma si vede che è un
   riflesso e non un secondo valore indipendente */
.label-mirror { background: #fbfdfd; }

/* ---- licenze in tabella aziende: un riquadro solo ---- */
/* quante ne sono in uso, quanto margine resta e fino a quando valgono: erano
   tre informazioni sparse su due colonne, e da sole non rispondevano alla
   domanda vera (dieci licenze scadute sono zero licenze) */
.lic-card {
    display: inline-flex;
    flex-direction: column;
    gap: .3rem;
    min-width: 9.5rem;
    padding: .45rem .6rem;
    border: 1px solid var(--id2-line, #dfe7ea);
    border-radius: 8px;
    background: #fbfdfd;
}
.lic-top { display: flex; align-items: baseline; gap: .3rem; line-height: 1; }
.lic-count { font-size: 1.05rem; color: #37424a; font-variant-numeric: tabular-nums; }
.lic-count strong { font-size: 1.25rem; font-weight: 600; }
.lic-sep { color: #b3bfc6; margin: 0 .1rem; }
.lic-word { font-size: .7rem; color: #8a959d; text-transform: uppercase; letter-spacing: .03em; }
.lic-bar { height: 4px; border-radius: 999px; background: #e6edf0; overflow: hidden; }
.lic-bar > span { display: block; height: 100%; border-radius: 999px; }
.lic-bar-ok      > span { background: #2ab57d; }
.lic-bar-warning > span { background: #f0961e; }
.lic-bar-danger  > span { background: #fd625e; }
.lic-card-empty { background: transparent; border-style: dashed; }
.lic-none { font-size: .75rem; color: #9aa4ad; }

/* ---- tab Brand della scheda azienda: i due slot logo ---- */
/* l'anteprima sta su una scacchiera chiara: i loghi sono quasi sempre PNG o SVG
   con lo sfondo trasparente, e su bianco pieno non si capisce dove finiscono */
.logo-slot {
    border: 1px solid var(--id2-line, #dfe7ea);
    border-radius: 8px;
    padding: .75rem;
    height: 100%;
}
/* riquadro della modalità manutenzione (Impostazioni → Generali): stessa
   cornice dei logo-slot. Non una .card annidata: dentro la card della pagina
   il tema le toglie il padding e il contenuto finiva attaccato al bordo */
.maintenance-box {
    border: 1px solid var(--id2-line, #dfe7ea);
    border-radius: 8px;
    padding: 1rem 1.25rem;
}
.logo-slot-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    margin-bottom: .5rem;
}
.logo-slot-preview {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 110px;
    margin-bottom: .5rem;
    border-radius: 6px;
    background-color: #fbfdfd;
    background-image:
        linear-gradient(45deg, #eef3f5 25%, transparent 25%, transparent 75%, #eef3f5 75%),
        linear-gradient(45deg, #eef3f5 25%, transparent 25%, transparent 75%, #eef3f5 75%);
    background-size: 16px 16px;
    background-position: 0 0, 8px 8px;
}
.logo-slot-preview img { max-width: 100%; max-height: 110px; }
.logo-slot-empty { color: #9aa4ad; font-size: .8rem; }
/* durante il caricamento lo slot resta lì ma non si può ricliccare */
.logo-slot-busy { opacity: .5; pointer-events: none; }

/* ---- versione del programma (footer dashboard) ---- */
.app-version {
    display: inline-block;
    background: #eaf3f0;
    border: 1px solid #cfe3dc;
    color: #2f6b58;
    border-radius: 999px;
    padding: .12rem .6rem;
    font-size: .72rem;
    font-weight: 500;
    letter-spacing: .02em;
    font-variant-numeric: tabular-nums;
    cursor: default;
}

/* ---- utenti di sistema (tab del pannello Impostazioni) ---- */
.sysusers-table td { font-size: .85rem; }
.sysuser-sub { font-size: .75rem; color: #9aa4ad; }
.sysuser-problems { font-size: .72rem; color: #d15b5b; margin-top: .15rem; }
.sysuser-cred { font-family: monospace; font-size: .78rem; color: #37424a; white-space: nowrap; }
.sysuser-pass-value { letter-spacing: .08em; }
.sysuser-pass-clear { cursor: pointer; letter-spacing: 0; color: #1e2b29; background: #f7fafa; padding: .05rem .35rem; border-radius: 4px; }
.sysuser-created code { background: #f7fafa; padding: .1rem .35rem; border-radius: 4px; }

/* ---- anteprima a tutto schermo ----
   overlay proprio, NON una modale Bootstrap: si apre sopra la modale della
   scheda azienda e una modale annidata romperebbe backdrop e stacking.
   z-index sopra .modal (1055) e .modal-backdrop (1050) del tema. */
.email-preview-overlay {
    position: fixed;
    inset: 0;
    z-index: 1080;
    background: rgba(15, 40, 48, .55);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}
.email-preview-dialog {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 760px;
    height: 100%;
    max-height: 88vh;
    background: #fff;
    border-radius: var(--id2-radius-lg);
    box-shadow: 0 12px 40px rgba(15, 40, 48, .28);
    overflow: hidden;
}
.email-preview-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .8rem 1rem;
    border-bottom: 1px solid var(--id2-line);
}
.email-preview-title { font-weight: 500; color: #17282c; }
/* l'iframe viene ricreato a ogni apertura (vedi email-preview.js): il corpo
   è il contenitore che ne tiene il posto nel layout */
.email-preview-body {
    flex: 1 1 auto;
    display: flex;
    min-height: 0;
    background: #f2f6f5;
}
.email-preview-body iframe {
    flex: 1 1 auto;
    width: 100%;
    border: 0;
    background: #f2f6f5;
}
@media (max-width: 575.98px) {
    .email-preview-overlay { padding: 10px; }
    .email-preview-dialog { max-height: 94vh; }
}

/* ---- pannello segnaposto: chip cliccabili con descrizione ---- */
.sysemail-ph {
    background: #fff;
    border: 1px solid var(--id2-line);
    border-radius: var(--id2-radius);
    padding: .7rem .8rem;
}
.sysemail-ph-title { font-size: .78rem; font-weight: 500; color: #3d4a52; margin-bottom: .5rem; }
.sysemail-ph-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: .3rem; }
.sysemail-chip {
    display: flex;
    align-items: baseline;
    gap: .45em;
    text-align: left;
    padding: .3rem .5rem;
    border: 1px solid transparent;
    border-radius: var(--id2-radius);
    background: transparent;
    line-height: 1.3;
}
.sysemail-chip:hover { background: rgba(67, 179, 174, .10); border-color: rgba(67, 179, 174, .35); }
.sysemail-chip code {
    color: #2e7b78;
    background: rgba(67, 179, 174, .10);
    border-radius: 4px;
    padding: .1em .35em;
    font-size: .76rem;
    white-space: nowrap;
}
.sysemail-chip-desc { font-size: .72rem; color: #74788d; }
/* il corpo è codice: leggibile, non microscopico */
.sysemail-body { font-family: ui-monospace, Consolas, "Courier New", monospace; font-size: .82rem; line-height: 1.5; }
.sysemail-warn code { color: inherit; background: rgba(255, 255, 255, .5); border-radius: 4px; padding: .05em .3em; }

/* ========================================================================== */
/* CANVAS TINTO — classe OPT-IN .page-canvas sul .page-content                 */
/* -------------------------------------------------------------------------- */
/* Stessa impostazione della dashboard: fondo tenue sotto, card bianche che ci  */
/* staccano sopra. Attiva su dashboard + tutte le viste con DataTable          */
/* (chiamate, lavorazioni, utenti, approvazioni, rapportini, eventi, aziende). */
/* NON è globale di proposito: commesse, impostazioni e le pagine con head     */
/* proprio (report_doc/report_new/rap_history) restano bianche piatte.         */
/* Per attivarla su una vista: <div class="page-content page-canvas">.         */
/* ========================================================================== */
.page-content.page-canvas {
    background: #f2f6f5;
    min-height: 100vh;
}
/* rientro identico alla dashboard: lì il contenuto sta DIRETTAMENTE dentro
   .page-content (padding 24px), nelle altre viste è avvolto in un
   .container-fluid che aggiunge i suoi .75rem. Azzerandolo, tutte le pagine
   partono dalla stessa verticale. Le .row interne hanno margini negativi che
   il padding di .page-content assorbe: nessuno sborda. */
.page-canvas > .container-fluid {
    padding-left: 0;
    padding-right: 0;
}

/* ---- la tabella scorre, la pagina no ----
   Una tabella più larga della finestra deve produrre una barra di scorrimento
   DENTRO la card, non spingere fuori la pagina. Perché accada, ogni
   contenitore fra la pagina e la tabella deve poter diventare più stretto del
   proprio contenuto: in flexbox il default è min-width:auto, che glielo
   impedisce, e la colonna si allarga finché il .main-content del tema
   (overflow:hidden) taglia via il resto — è così che le colonne di destra
   sparivano restringendo la finestra.
   Lo scorrimento vero ce l'hanno già .table-responsive e .dataTables_scrollBody. */
.page-canvas .container-fluid,
.page-canvas .row > [class*="col-"],
.page-canvas .card {
    min-width: 0;
    max-width: 100%;
}
/* TUTTI i figli diretti della card, non solo .card-body: la .card è un flex
   container e in gestione chiamate, lavorazioni e approvazioni il
   .table-responsive le sta appeso direttamente. Da flex item con
   min-width:auto si allargava fino alla larghezza della tabella, annullando
   il proprio overflow-x — la barra non compariva e le colonne finivano sotto
   il taglio del .main-content.
   Solo min-width qui: un max-width su tutti i figli stringerebbe anche le
   .row, che hanno margini negativi e devono poter sbordare di quei 12px. */
.page-canvas .card > * { min-width: 0; }
.page-canvas .card > .table-responsive,
.page-canvas .card > .card-body { max-width: 100%; }
/* le .card diventano LE superfici che portano il contenuto: bianche, cornice
   tenue e micro-ombra — gli stessi valori di .kpi-card/.dash-card in dashboard.
   Vale anche per .table-modern (che qui prende ombra e bordo condivisi). */
.page-canvas .card {
    background: #fff;
    border: 1px solid #e3eae8;
    border-radius: var(--id2-radius-lg);
    box-shadow: 0 1px 3px rgba(15, 40, 48, .07);
}
/* eccezione: il contenitore che avvolge SOLO le card chiamata (vista tecnico e
   ramo card di approvazioni/lavorazioni) non deve incorniciare altre cornici —
   sparisce, e le card galleggiano sul fondo tinto come i tile della dashboard */
.page-canvas .card.card-flush {
    background: transparent;
    border: 0;
    box-shadow: none;
}
/* la .card-body del contenitore flush non deve rientrare il contenuto: le card
   chiamata devono allinearsi ai filtri sopra di loro */
.page-canvas .card.card-flush > .card-body { padding: 0; }

/* ========================================================================== */
/* TABELLE MODERNE — classe OPT-IN .table-modern sul contenitore               */
/* -------------------------------------------------------------------------- */
/* Attiva su TUTTE le viste con DataTable: chiamate, utenti, approvazioni,     */
/* lavorazioni, rapportini, eventi, aziende. NON è globale di proposito —      */
/* commesse e impostazioni usano un'altra impaginazione.                       */
/* STRUTTURA UNICA — vale per tutte le tabelle dell'app:                       */
/*                                                                            */
/*   <div class="card table-modern">                                          */
/*       <div class="row card-filters"> ...filtri... </div>   (se servono)    */
/*       <div class="table-responsive">                                       */
/*           <table class="table table-sm table-hover" id="datatable-x">      */
/*                                                                            */
/* NIENTE .card-body: non aggiungeva nulla (il CSS le azzerava il padding) ed  */
/* essendo un flex item in più con min-width:auto impediva alla tabella larga  */
/* di scorrere. Prima metà delle viste ce l'aveva e metà no, e il difetto si   */
/* manifestava solo su quelle senza. Sulla <table> niente .table-bordered, e   */
/* .dt-controls sulle righe della stringa dom del DataTable.                   */
/*                                                                            */
/* NOTA DataTables scrollX: con scrollX:true DataTables SPEZZA la tabella in   */
/* due (.dataTables_scrollHead con il thead + .dataTables_scrollBody con il    */
/* tbody). Per questo gli angoli arrotondati stanno sul WRAPPER e non sulla    */
/* <table>, e le regole di header targettano anche .dataTables_scrollHead.     */
/* ========================================================================== */
/* ATTENZIONE — niente overflow:hidden sul contenitore: le celle azioni hanno   */
/* .btn-group.dropup con .dropdown-menu dentro, verrebbero tagliati (è la      */
/* stessa trappola annotata su .table .btn-group più sopra). Gli angoli        */
/* arrotondati si ottengono quindi arrotondando le CELLE d'angolo.             */
.table-modern {
    background: #fff;
    border: 1px solid #e9edf0;
    border-radius: var(--id2-radius-lg);
    padding: 0 0 .25rem;
    /* il box non deve MAI allargare la pagina: a scorrere è il contenitore
       interno della tabella, non il documento (min-width:0 serve perché la
       .card è un flex container e i suoi figli altrimenti non si stringono) */
    max-width: 100%;
    min-width: 0;
}
/* garantisce la barra di scorrimento orizzontale sulla tabella. Con scrollX
   DataTables scrolla .dataTables_scrollBody; senza, scrolla .table-responsive.
   Le teniamo entrambe esplicite: dipende dalla vista quale delle due è attiva.

   !important perché il tema (app.min.css) forza
       .table-responsive { overflow: visible !important }
   per non far tagliare i dropdown delle azioni, e lo rimette a auto solo sotto
   i 992px. Risultato: sopra quella soglia la tabella larga non scorreva, usciva
   dalla card e finiva sotto il taglio del .main-content — mentre restringendo
   oltre il breakpoint tornava a funzionare.
   Il clipping dei dropdown è risolto altrove e meglio: i menu delle azioni sono
   posizionati in fixed (strategy Popper, vedi datatables-fit.js), quindi
   nessun overflow li tocca. */
.table-modern .table-responsive,
.table-modern .dataTables_scrollBody { overflow-x: auto !important; }
/* barra spenta quando non scorre nulla: la mette datatables-fit.js dopo aver
   misurato (bastano due pixel di arrotondamento a farla comparire a vuoto) */
.table-modern .no-x-scroll { overflow-x: hidden !important; }
/* !important perché DataTables scrive width INLINE su questi contenitori
   (larghezza misurata all'avvio): senza, restringendo la finestra restano
   larghi come prima e la tabella esce dalla card invece di scorrere.
   Il ricalcolo vero lo fa datatables-fit.js con columns.adjust(); questo è il
   contenimento che regge nel frattempo. */
.table-modern .dataTables_wrapper,
.table-modern .dataTables_scroll,
.table-modern .dataTables_scrollHead,
.table-modern .dataTables_scrollBody { max-width: 100% !important; min-width: 0; }
/* la tabella perde bordo esterno e griglia: restano solo i divisori di riga */
.table-modern table.table {
    margin-bottom: 0;
    border: 0;
    border-collapse: separate;
    border-spacing: 0;
}
.table-modern table.table > :not(caption) > * > * { border-width: 0; }
/* angoli: prima/ultima cella dell'header seguono il raggio del contenitore */
.table-modern table.table > thead > tr > th:first-child { border-top-left-radius: var(--id2-radius-lg); }
.table-modern table.table > thead > tr > th:last-child  { border-top-right-radius: var(--id2-radius-lg); }
/* Respiro dai bordi della card per TUTTO ciò che non è la tabella: filtri di
   pagina, controlli DataTables (ricerca/paginazione), contatori.
   Le .row hanno margini negativi e le colonne .75rem di gutter: azzerando il
   margine (e senza aggiungere padding orizzontale) il contenuto si allinea a
   .75rem dal bordo, in linea col padding di th/td.
   Selettori discendenti di proposito: con scrollX il wrapper è annidato dentro
   .table-responsive, quindi il figlio diretto non è garantito. */
.table-modern .row.card-filters { padding: .9rem 0 .35rem; margin: 0; }
/* .dt-controls è messa dalla stringa dom dei due DataTable: classe esplicita
   invece di :first-child/:last-child, che dipendevano dall'ordine dei nodi
   generati da DataTables (fragile: bastava un div di servizio in più) */
/* Il rientro NON viene lasciato al gutter delle colonne: una .row ha margini
   negativi che lo annullano esattamente, e il contenuto finisce a filo del
   bordo. Qui azzeriamo margini E padding delle colonne e mettiamo il rientro
   sulla riga, cosi vale .7rem in modo esplicito — lo stesso padding di td. */
.table-modern .dt-controls {
    margin-left: 0 !important;
    margin-right: 0 !important;
    padding: .75rem .7rem .65rem;
}
.table-modern .dt-controls > [class*="col-"] {
    padding-left: 0;
    padding-right: 0;
    min-width: 0;   /* senza questo il contenuto non si stringe e sborda sulla colonna accanto */
}

/* ---- header: fondo chiaro, minuscolo, maiuscoletto, solo underline ---- */
.table-modern table.table > thead > tr > th,
.table-modern .dataTables_scrollHead table.table > thead > tr > th {
    background-color: #fbfcfd;
    border-bottom: 1px solid #eceff2 !important;
    color: #8a97a0;
    font-size: .6875rem;
    font-weight: 500;
    letter-spacing: .05em;
    text-transform: uppercase;
    /* padding orizzontale contenuto e NIENTE nowrap: su 15 colonne un padding
       da 1rem con header non spezzabili allargava la tabella di ~340px e
       mandava in scroll la pagina invece del contenitore */
    padding: .8rem .7rem;
    vertical-align: middle;
}
/* ---- righe: divisori hairline, respiro, ultima riga pulita ---- */
.table-modern table.table > tbody > tr > td {
    border-bottom: 1px solid #f2f5f7 !important;
    padding: .7rem;
    font-size: .8125rem;
    vertical-align: middle;
    color: #37424a;
}
.table-modern table.table > tbody > tr:last-child > td { border-bottom: 0 !important; }
/* il separatore-giorni non deve prendere il padding delle righe normali */
.table-modern table.table > tbody > tr.separator > td { padding: 0 !important; }
/* le celle di stato (call_row_*) restano a fondo pieno: ridiamo loro il
   bordino interno che il reset di sopra azzererebbe ai lati */
.table-modern table.table > tbody > tr > td[class*="call_row_"] {
    border-radius: var(--id2-radius);
}
/* CH errata (ch_error dall'import Vision): a differenza degli altri stati la
   classe sta sul <tr>, e app.min.css la dipinge TUTTA di #910b18 con testo
   bianco. Nel nuovo stile la riga tornava illeggibile, perché le celle qui
   hanno colore testo proprio. Spegniamo il fondo pieno sulla riga: il segnale
   resta sulla cella Cliente, in linguaggio soft come tutti gli altri stati
   (regola .table > tbody > tr.call_row_error > td:nth-child(3) più sopra).
   Solo dentro .table-modern: le viste non ancora migrate restano com'erano. */
.table-modern table.table > tbody > tr.call_row_error {
    background-color: transparent !important;
    color: inherit;
}
/* la cella Cliente qui non ha una classe call_row_* propria (sta sul tr),
   quindi il raggio va dato a parte per pareggiarla agli altri stati */
.table-modern table.table > tbody > tr.call_row_error > td:nth-child(3) {
    border-radius: var(--id2-radius);
}

/* ---- controlli sopra la tabella: ricerca a pillola con lente ---- */
.table-modern .dataTables_filter { margin-bottom: 0; }
.table-modern .dataTables_filter label {
    position: relative;
    margin-bottom: 0;
    display: block;
}
.table-modern .dataTables_filter label::before {
    /* ph-magnifying-glass. Phosphor e non Font Awesome: il progetto sta
       migrando a Phosphor e questa era l'unica dipendenza da FA aggiunta col
       nuovo stile tabellare. */
    content: "\e30c";
    font-family: "Phosphor-Light";
    position: absolute;
    left: .85rem;
    top: 50%;
    transform: translateY(-50%);
    color: #9aa7b0;
    font-size: .9rem;
    line-height: 1;
    pointer-events: none;
}
.table-modern .dataTables_filter input {
    border: 1px solid #e4e9ec;
    border-radius: 999px;
    background: #fff;
    padding: .45rem 1rem .45rem 2.3rem;
    min-width: 260px;
    font-size: .8125rem;
}
.table-modern .dataTables_filter input:focus {
    border-color: var(--id2-teal);
    box-shadow: 0 0 0 .2rem var(--id2-ring);
    outline: 0;
}
.table-modern .dataTables_length select {
    border-radius: 999px;
    padding: .3rem 1.6rem .3rem .8rem;
    font-size: .8125rem;
}
.table-modern .dataTables_info { color: #8a97a0; font-size: .75rem; }
/* paginazione compatta: con 8+ pagine occupava piu spazio della ricerca */
.table-modern .dataTables_paginate { margin: 0; }
.table-modern .dataTables_paginate .pagination { margin-bottom: 0; flex-wrap: wrap; }
.table-modern .dataTables_paginate .page-link {
    border: 0;
    border-radius: var(--id2-radius);
    font-size: .8125rem;
    padding: .25rem .5rem;
    min-width: 1.9rem;
    text-align: center;
}
.table-modern .dataTables_paginate .page-item.active .page-link {
    border-radius: var(--id2-radius);
}
/* i puntini non sono cliccabili: niente stile da bottone */
.table-modern .dataTables_paginate .page-item.disabled .page-link { background: transparent; }

/* ========================================================================== */
/* CONTATORI DENTRO LE PILL DI STATO (gestione chiamate)                      */
/* -------------------------------------------------------------------------- */
/* Le pill .btns-status SONO i filtri: il numero va lì dentro, non in una card */
/* KPI separata che direbbe la stessa cosa. Lo inietta calls-manager.js.       */
/* Il badge eredita il colore del testo della pill, così ogni stato resta      */
/* riconoscibile senza definire sette varianti.                                */
/* ========================================================================== */
.btns-status .btn .pill-count {
    display: inline-block;
    margin-left: .5em;
    padding: 0 .45em;
    min-width: 1.6em;
    border-radius: 999px;
    background: rgba(255, 255, 255, .75);
    box-shadow: inset 0 0 0 1px currentColor;
    font-size: .78em;
    font-weight: 600;
    line-height: 1.55;
    text-align: center;
    font-variant-numeric: tabular-nums;
    opacity: .95;
}
/* la pill TUTTE è su fondo chiaro neutro: lì il badge bianco sparirebbe */
.btns-status .btn.btn-dark .pill-count { background: rgba(255, 255, 255, .9); }

/* ========================================================================== */
/* KPI STRIP — barra informativa sopra le tabelle (usata da gestione utenti)  */
/* -------------------------------------------------------------------------- */
/* Due livelli: .kpi-tile (numeri grandi) e .kpi-chip (allerte, visibili solo  */
/* se > 0). Entrambi cliccabili: applicano un filtro o aprono una modale.      */
/* Nella gestione chiamate la strip NON c'è: i numeri stanno nelle pill.       */
/* ========================================================================== */
.kpi-strip {
    background: #fff;
    border: 1px solid #e9edf0;
    border-radius: var(--id2-radius-lg);
    padding: .35rem .25rem;
    margin-bottom: 1rem;
}
.kpi-row {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
}
.kpi-tile {
    flex: 1 1 140px;
    padding: .6rem 1.15rem;
    border: 0;
    background: transparent;
    text-align: left;
    position: relative;
    border-radius: var(--id2-radius);
    transition: background-color .15s ease;
}
/* divisore verticale sottile tra i tile (come nel riferimento) */
.kpi-tile + .kpi-tile::before {
    content: "";
    position: absolute;
    left: 0;
    top: 18%;
    height: 64%;
    width: 1px;
    background: #eceff2;
}
/* tile-FILTRO (Gestione Clienti): un <button> con la stessa faccia del tile
   informativo. Font e colore vanno detti, se no un button prende quelli dello
   user agent. L'attiva e' una card dentro la strip: fondo teal tenue e anello
   sottile, niente barre; il divisore ai suoi lati sparisce, se no si somma
   all'anello. */
button.kpi-tile { cursor: pointer; font: inherit; color: inherit; }
button.kpi-tile:hover { background-color: rgba(67, 179, 174, .07); }
.kpi-tile.is-active {
    background-color: rgba(67, 179, 174, .10);
    box-shadow: inset 0 0 0 1px rgba(67, 179, 174, .45);
}
.kpi-tile.is-active::before,
.kpi-tile.is-active + .kpi-tile::before { display: none; }
.kpi-tile.is-active .kpi-label { color: #2e7b78; }
/* con l'icona: l'icona tonda a SINISTRA, accanto al testo, nella hue dello
   stato (stessi toni dei badge-soft). A destra, su una tile larga, restava
   sperduta a mezzo metro dal numero. */
.kpi-tile.has-icon {
    display: flex;
    align-items: center;
    gap: .85rem;
    padding: .7rem 1.15rem;
}
.kpi-tile .kpi-icon {
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    background: #f1f4f6;
    color: #5b6770;
}
.kpi-tile .kpi-text { min-width: 0; }
.kpi-icon-teal    { background: rgba(67, 179, 174, .14);  color: #2e7b78; }
.kpi-icon-info    { background: rgba(75, 166, 239, .14);  color: #2f7fc4; }
.kpi-icon-warning { background: rgba(255, 176, 66, .18);  color: #b06a14; }
.kpi-icon-success { background: rgba(42, 181, 125, .14);  color: #1f8f62; }
.kpi-icon-neutral { background: #f1f4f6;                  color: #5b6770; }
/* riga delle segnalazioni con etichetta: staccata dalle tile da un filetto,
   con aria intorno e la parola che dice cosa sono. Senza, le chip stavano
   appiccicate sotto la prima tile come badge caduti li' per caso. */
.kpi-alerts-labeled {
    margin: .35rem .5rem 0;
    padding: .7rem .65rem .5rem;
    border-top: 1px solid #eef1f3;
    gap: .6rem;
}
.kpi-alerts-labeled::before {
    content: "Segnalazioni";
    font-size: .6875rem;
    font-weight: 500;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: #8a97a0;
    margin-right: .35rem;
}
.kpi-alerts-labeled .kpi-chip { font-size: .8rem; padding: .5em 1em; }
/* chip-filtro accesa: anello nel suo colore, come la pill attiva dei filtri */
button.kpi-chip.is-active { box-shadow: 0 0 0 2px currentColor; }
.kpi-label {
    display: block;
    font-size: .6875rem;
    font-weight: 500;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: #8a97a0;
    margin-bottom: .15rem;
    white-space: nowrap;
}
.kpi-value {
    display: block;
    font-size: 1.65rem;
    line-height: 1.15;
    font-weight: 600;
    color: #14343d;
    font-variant-numeric: tabular-nums;
}
.kpi-value.is-loading { color: #ccd5da; }
/* separatore nei valori a coppia (Vision/Online, licenze assegnate/acquistate) */
.kpi-sep { color: #c3ccd1; font-weight: 400; margin: 0 .1em; }

/* ---- fascia allerte: chip soft cliccabili, nascoste se il conteggio è 0 ---- */
.kpi-alerts {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    align-items: center;
    padding: .2rem 1.15rem .6rem;
}
.kpi-alerts:empty { display: none; }
button.kpi-chip {
    cursor: pointer;
    font-size: .78rem;
    padding: .42em .85em;
    transition: filter .15s ease, box-shadow .15s ease;
    /* ombra leggera sempre presente: distingue a colpo d'occhio le chip che
       APRONO qualcosa dai contatori-span piatti che stanno loro accanto */
    box-shadow: 0 1px 2px rgba(15, 40, 48, .10);
}
button.kpi-chip:hover { filter: brightness(.97); box-shadow: 0 1px 4px rgba(15, 40, 48, .16); }
.kpi-chip strong { font-weight: 600; }

/* divisore verticale nella strip sopra la griglia chiamate: a sinistra i
   contatori informativi (chiamate, LTTA scadute — span, nessuna azione),
   a destra le chip che aprono la modale contratti */
.calls_total_count .count-sep {
    width: 1px;
    align-self: stretch;
    background: #dfe6ea;
    margin: 0 .3rem;
}

/* ---- modale contratti ---- */
/* .modal-wide: più larga della modal-xl di Bootstrap (1140px), per le tabelle
   con molte colonne. Va sul .modal-dialog insieme a modal-xl (che resta a
   fare da ripiego sotto i 992px) e la vince per specificità. */
@media (min-width: 992px) {
    .modal-dialog.modal-wide { max-width: min(96vw, 1600px); }
}
.contract-row { cursor: pointer; }
/* le colonne testuali (cliente, sede, modello, contratto) vanno a capo:
   un nowrap generale su otto colonne sfonda la tabella; a restare su una
   riga sono solo le celle marcate text-nowrap (numero, scadenza, stato) */
.contract-row td { vertical-align: middle; }
/* pallino rosso = ChkCatCont da Vision ("contratto da evidenziare") */
.contract-flag {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #d4423e;
    margin-right: .45em;
    vertical-align: middle;
}
.contract-days-over { color: #d4423e; font-weight: 600; }
.contract-days-near { color: #b06a14; font-weight: 600; }

@media (max-width: 767.98px) {
    .kpi-tile { flex: 1 1 50%; padding: .55rem .85rem; }
    .kpi-tile + .kpi-tile::before { display: none; }
    .kpi-value { font-size: 1.35rem; }
    .table-modern .dataTables_filter input { min-width: 0; width: 100%; }
}

/* ----------------------------------------------------------------- dettagli */
.page-title-box .lead { color: #6b7a83; }
.table-responsive::-webkit-scrollbar,
.dataTables_scrollBody::-webkit-scrollbar { height: 8px; width: 8px; }
.table-responsive::-webkit-scrollbar-thumb,
.dataTables_scrollBody::-webkit-scrollbar-thumb {
    background: #c3cfd4;
    border-radius: 4px;
}
.table-responsive::-webkit-scrollbar-track,
.dataTables_scrollBody::-webkit-scrollbar-track { background: transparent; }

/* ---- errori PHP (tab del pannello Impostazioni) ----
   Un problema per riga, il trace chiuso dentro. Ricalca il blocco delle
   migrazioni (.migration-*): stessa gestualità — si clicca la riga e si apre
   il dettaglio — quindi stesso aspetto, per non insegnare due volte la stessa
   cosa. Il trace riusa lo stile console di .migration-log. */
.err-item {
    border: 1px solid #e3eaec;
    border-radius: 8px;
    padding: .7rem .9rem;
    margin-bottom: .55rem;
    background: #fff;
}
.err-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    cursor: pointer;
}
.err-main { min-width: 0; }
.err-msg {
    font-weight: 600;
    color: #37424a;
    font-size: .85rem;
    word-break: break-word;
}
.err-caret {
    color: #9aa4ad;
    transition: transform .15s;
}
.err-where {
    font-family: monospace;
    font-size: .74rem;
    color: #9aa4ad;
    margin-top: .2rem;
    padding-left: 1.15rem;
    word-break: break-all;
}
.err-where a { color: #5b8fa8; text-decoration: none; }
.err-where a:hover { text-decoration: underline; }

/* Il punto in cui PHP si ferma è quasi sempre dentro wire/ — filesize(), una
   query, un metodo del core — mentre la riga da correggere sta in site/, più
   in basso nello stack. Senza distinguerli si legge un elenco di file di
   ProcessWire e il proprio non si trova. Quindi: il core sbiadisce, il codice
   del progetto resta leggibile, e il file su cui andare a guardare viene
   ripescato dallo stack e messo in testa. */
.err-where-own,
.err-own {
    font-family: monospace;
    font-size: .74rem;
    padding-left: 1.15rem;
    word-break: break-all;
}
.err-own {
    color: #2f7d8c;
    font-weight: 600;
    margin-top: .15rem;
}
.err-own a { color: #2f7d8c; text-decoration: none; }
.err-own a:hover { text-decoration: underline; }
.err-where-own { color: #2f7d8c; }
.err-where-own a { color: #2f7d8c; }

.err-f-core { color: #b6bfc6; }
.err-f-own { color: #2f7d8c; font-weight: 600; }
.err-f-own a { color: #2f7d8c; text-decoration: none; }
.err-f-own a:hover { text-decoration: underline; }

.err-sub {
    font-size: .7rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #9aa4ad;
    margin: .7rem 0 .3rem;
}
.err-sub:first-child { margin-top: 0; }
.err-trace-own {
    background: #f2f8f9;
    border-left: 3px solid #2f7d8c;
    max-height: none;
}

.err-detail { padding-left: 1.15rem; margin-top: .6rem; }
.err-trace {
    background: #f7fafa;
    border-radius: 6px;
    padding: .5rem .7rem;
    color: #37424a;
    font-family: monospace;
    font-size: .74rem;
    line-height: 1.6;
    max-height: 260px;
    overflow: auto;
    word-break: break-all;
}
.err-meta {
    font-size: .74rem;
    color: #9aa4ad;
    margin-top: .5rem;
    word-break: break-all;
}
.err-meta code { font-size: .72rem; }

/* ========================================================================== */
/* PORTALE CLIENTI — data e ora nella nuova chiamata                          */
/* -------------------------------------------------------------------------- */
/* Non sono campi: le assegna il server. Come testo semplice sembravano però  */
/* un'etichetta dimenticata in cima al form — due tessere con icona dicono    */
/* "questo è un dato che ti stiamo mostrando", senza invitare a modificarlo.  */
.portal-when { display: flex; flex-wrap: wrap; gap: .6rem; }
.portal-when-item {
    display: flex;
    align-items: center;
    gap: .6rem;
    flex: 1 1 160px;
    padding: .65rem .85rem;
    border: 1px solid #e3eae8;
    border-radius: var(--id2-radius-lg);
    background: #fbfcfd;
}
.portal-when-item > i {
    font-size: 1.45rem;
    color: var(--id2-teal, #43b3ae);
    flex: 0 0 auto;
}
.portal-when-label {
    display: block;
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: #8a97a0;
    line-height: 1.2;
}
.portal-when-value {
    display: block;
    font-size: 1.05rem;
    font-weight: 600;
    color: #37424a;
    line-height: 1.3;
    font-variant-numeric: tabular-nums;
}

/* ========================================================================== */
/* PORTALE CLIENTI — tabelle-dettaglio nelle modali                           */
/* -------------------------------------------------------------------------- */
/* Il dettaglio CH e la scheda cliente usavano il .table-sm da griglia        */
/* (padding .25rem): in una modale di LETTURA le righe si soffocavano. Qui    */
/* respirano: padding pieno, etichetta distanziata dal valore, divisori       */
/* leggeri come nelle tabelle moderne.                                        */
.portal-detail-table > tbody > tr > td {
    padding: .7rem .75rem;
    vertical-align: top;
    border-bottom: 1px solid #f2f5f7 !important;
    font-size: .8125rem;
    line-height: 1.5;
}
.portal-detail-table > tbody > tr:last-child > td { border-bottom: 0 !important; }
/* la colonna etichetta (il primo td, quello grigio) si stacca dal valore */
.portal-detail-table > tbody > tr > td:first-child { padding-right: 1.5rem; }

/* ========================================================================== */
/* PORTALE CLIENTI — pill dei filtri coi COLORI DEI BADGE delle righe         */
/* -------------------------------------------------------------------------- */
/* Le pill riusavano le classi call_row_* dello staff, che hanno un'altra     */
/* semantica cromatica: "Assegnata" usciva col pallino grigio del "DA FARE"   */
/* mentre il badge in riga è azzurro. Qui le varianti del portale, con la     */
/* stessa palette dei badge-soft: pill e badge devono dire lo stesso colore.  */
.btns-status .btn.portal_row_open     { background: rgba(255, 176, 66, .16) !important; border-color: rgba(240, 150, 40, .45); color: #b06a14 !important; }
.btns-status .btn.portal_row_open::before     { background: #f09628; }
.btns-status .btn.portal_row_assigned { background: rgba(75, 166, 239, .12) !important; border-color: rgba(75, 166, 239, .40); color: #2f7fc4 !important; }
.btns-status .btn.portal_row_assigned::before { background: #4ba6ef; }
.btns-status .btn.portal_row_closed   { background: rgba(42, 181, 125, .12) !important; border-color: rgba(42, 181, 125, .40); color: #1f8f62 !important; }
.btns-status .btn.portal_row_closed::before   { background: #2ab57d; }

/* ========================================================================== */
/* PORTALE CLIENTI — file scelti per la nuova chiamata                        */
/* -------------------------------------------------------------------------- */
/* Un <input type="file"> nudo dice solo "3 file selezionati": qui ogni file  */
/* ha la sua riga con miniatura (vera, per le immagini), nome, peso e il      */
/* cestino per toglierlo. Chi supera il limite del server resta in lista      */
/* segnato in rosso, così si vede PERCHÉ non partirà.                         */
.portal-filelist { display: flex; flex-direction: column; gap: .4rem; }
.portal-file {
    display: flex;
    align-items: center;
    gap: .65rem;
    padding: .4rem .5rem;
    border: 1px solid #e9edf0;
    border-radius: var(--id2-radius);
    background: #fbfcfd;
}
.portal-file-error { border-color: #f1c9cd; background: #fdf6f6; }
.portal-file-thumb {
    width: 40px;
    height: 40px;
    border-radius: var(--id2-radius);
    object-fit: cover;          /* la miniatura riempie il quadrato senza deformarsi */
    flex: 0 0 auto;
    background: #fff;
    border: 1px solid #eceff2;
}
.portal-file-thumb-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.3rem;
    color: #8a97a0;
}
.portal-file-info { min-width: 0; flex: 1 1 auto; }   /* min-width:0 = il nome lungo può troncarsi */
.portal-file-name {
    font-size: .8125rem;
    color: #37424a;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.portal-file-meta { font-size: .72rem; color: #8a97a0; }
.portal-file-remove { padding: .1rem .35rem; line-height: 1; }

/* ========================================================================== */
/* SIDEBAR CHIUSA — l'etichetta si adatta al nome                             */
/* -------------------------------------------------------------------------- */
/* Con la sidebar ridotta a sole icone, passando sopra una voce il tema apre  */
/* di fianco un riquadro con l'etichetta, largo 260px FISSI                   */
/* (calc(190px + 70px) in app.min.css). Un nome lungo — la ragione sociale di */
/* un cliente del portale, per dire — usciva dal riquadro.                    */
/* Qui quella misura diventa il MINIMO e non più il massimo: il box cresce    */
/* col testo, che non va a capo. Il tetto è la finestra meno la barra icone,  */
/* così su schermi stretti l'etichetta non sborda dalla pagina.               */
body[data-sidebar-size="sm"] .vertical-menu #sidebar-menu > ul > li:hover > a {
    width: auto !important;
    min-width: calc(190px + 70px);
    max-width: calc(100vw - 70px);
    white-space: nowrap;
    padding-right: 1.25rem;
}
/* stessa regola per i sottomenu che si aprono di fianco */
body[data-sidebar-size="sm"] .vertical-menu #sidebar-menu > ul > li:hover > ul,
body[data-sidebar-size="sm"] .vertical-menu #sidebar-menu > ul > li:hover > ul a {
    width: auto !important;
    min-width: 190px;
    white-space: nowrap;
}


/* Popover di aiuto delle schede (bottone "Come funziona" accanto a un campo).
   Il default di Bootstrap e' 276px: un elenco puntato ci esce a colonna
   strettissima e lungo il doppio dello schermo.
   Il line-height con !important non e' un vezzo: il tema (app.min.css) mette
   `.popover { line-height: 0.4 !important }`, pensato per popover di una riga
   sola. Su un testo di piu' righe le righe si sovrappongono e diventa
   illeggibile, ed essendo !important lo si batte solo cosi'. Per lo stesso
   motivo la regola sta sul .popover, non sul solo .popover-body: l'intestazione
   sarebbe schiacciata allo stesso modo. */
.popover-wide { max-width: 380px; line-height: 1.45 !important; }
.popover-wide .popover-header { font-size: .8125rem; font-weight: 600; }
.popover-wide .popover-body { font-size: .8125rem; }
.popover-wide .popover-body ol,
.popover-wide .popover-body ul { margin-bottom: .5rem; }
.company-hint { text-decoration: underline; }

/* ------------------------------- storico intestazione: la riga IN VIGORE */
/* L'ultima riga della tabella non e' una versione storica come le altre: e' il
   presente, cioe' l'intestazione che i rapportini di oggi stampano davvero.
   Aveva addosso .table-light, che in questo tema esce come una fascia grigia
   uniforme e la faceva sembrare una riga DISATTIVATA — il contrario di quello
   che e'. Qui invece un fondo appena accennato nella hue identitaria e un
   accento sul bordo sinistro: si stacca dalle righe passate senza spegnersi.
   Il fondo sta sui td e non sul tr perche' Bootstrap dipinge le celle, non la
   riga; l'hover di .table-hover ha specificita' maggiore e continua a vincere. */
.hdr-current > td { background: rgba(67, 179, 174, .06); }
.hdr-current > td:first-child { box-shadow: inset 3px 0 0 var(--id2-teal); }

/* ------------------------------- avviso di modifica concorrente */
/* In testa alla modale di modifica CH o rapportino quando un altro utente ha
   aperto lo stesso documento (edit-lock.js). L'icona si allinea alla prima riga
   del testo, che su schermi stretti va a capo. */
.edit-lock-alert { margin-bottom: .75rem; }
.edit-lock-alert > i { font-size: 1.25rem; line-height: 1.2; flex-shrink: 0; }
