/* ============================================================
   SOS BOLLETTE — CRM MOBILE LAYER  (Fase 1: fondamenta globali)
   ------------------------------------------------------------
   Caricato per ULTIMO nel <head> di tutte le pagine backend.
   Target: Samsung Galaxy Z Fold
     - cover  (chiuso)  ~344-420px  -> drawer + densità massima
     - inner  (aperto)  ~690-900px  -> rail 76px + griglie compattate
     - inner  landscape ~900-1100px -> rail 76px + 3-4 colonne

   REGOLA FERREA DI NON-REGRESSIONE
   Ogni regola di questo file vive dentro una @media che NON può
   attivarsi su un desktop con mouse:
       @media (max-width: 1199.98px)          — o più stretta
       @media (hover: none)                   — solo touch
   Non esiste una sola regola "nuda" a livello di file.
   Sopra 1200px con un mouse questo file è inerte. Per verificarlo
   basta guardare l'indentazione: nulla parte da colonna 0 tranne
   i blocchi @media e le custom properties qui sotto.

   Le custom properties in :root non producono alcun effetto
   visivo: definiscono soltanto valori usati dentro le @media.
   ============================================================ */

:root {
    --sb-rail-w:    76px;          /* larghezza del rail a icone      */
    --sb-drawer-w:  min(284px, 84vw);
    --sb-header-h:  64px;          /* topbar compatta su mobile       */
    --sb-touch:     44px;          /* target minimo per il dito       */
    --sa-b: env(safe-area-inset-bottom, 0px);
    --sa-t: env(safe-area-inset-top, 0px);
    --sb-m-ease: cubic-bezier(0.16, 1, 0.3, 1);
}


/* ============================================================
   1. SHELL — tutto ciò che vale sotto i 1200px
   ============================================================ */
@media (max-width: 1199.98px) {

    /* Topbar più bassa: recupera 8px di altezza utile.
       !important perché crm-redesign.css (height:72px) è iniettato
       da topbar.php, quindi DOPO questo file nella cascata. */
    .app-header { height: var(--sb-header-h) !important; }
    .app-header .container-fluid { padding: 0 12px !important; }

    /* Il padding-top deve seguire l'altezza reale della topbar. */
    .content-wrapper {
        padding-top: calc(var(--sb-header-h) + 14px) !important;
        padding-bottom: calc(20px + var(--sa-b)) !important;
    }

    /* 100vh su Android salta quando la barra URL si ritrae: dvh no. */
    .left-sidebar { height: 100dvh; }

    /* Overlay del drawer/rail espanso.
       Va appeso a <body> (fuori da .body-wrapper, che ha z-index:1
       e lo intrappolerebbe). Ci pensa crm-mobile.js. */
    .sb-overlay {
        position: fixed;
        inset: 0;
        z-index: 1005;              /* sotto .left-sidebar (1010) */
        background: rgba(15, 23, 42, 0.5);
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.25s var(--sb-m-ease);
        -webkit-tap-highlight-color: transparent;
    }
    body.sb-nav-open .sb-overlay {
        opacity: 1;
        pointer-events: auto;
    }

    /* ---- MAI transizioni su proprietà di layout sotto i 1200px ----
       Misurato in un browser vero: sia `width` su .left-sidebar sia
       `margin-left` su .body-wrapper (backend.css:35) restano bloccate
       in stato "running" all'infinito quando il cambio è innescato da
       una media query. Risultato osservato: sidebar ferma a 270px in
       modalità rail, e contenuto con margin-left:76px a 1050px, cioè
       sovrapposto per 194px alla sidebar piena.

       Indipendentemente dal bug, animare width/margin-left obbliga il
       browser a rifare il layout dell'INTERA pagina a ogni frame.
       Sul Fold il cambio di fascia avviene aprendo il telefono — un
       resize da ~420 a ~900px — cioè nel momento in cui il dispositivo
       sta già ridisegnando tutto. È il momento peggiore per aggiungere
       300ms di relayout continuo.

       Resta `transform`, che è gestito dal compositor: costo zero in
       layout ed è esattamente ciò che serve al drawer. */
    .left-sidebar {
        transition: transform 0.28s var(--sb-m-ease) !important;
    }
    .body-wrapper {
        transition: none !important;
    }

    /* La sidebar è un contenitore fisso: il suo contenuto scorre,
       lei no. Senza questo il rail espanso non arriva in fondo. */
    .left-sidebar .sidebar-nav { overscroll-behavior: contain; }
}


/* ============================================================
   2. RAIL A ICONE — 600 … 991.98px
   ------------------------------------------------------------
   È LA FASCIA DELLO SCHERMO INTERNO DEL FOLD (~690px) e oggi
   non esiste: backend.css:631 qui nasconde la sidebar e basta.
   Con il rail la navigazione resta SEMPRE visibile e si perdono
   solo 76px invece di 270px.

   Limite superiore 991.98 e non 1199.98: tra 992 e 1199 la
   sidebar piena oggi funziona già (backend.css:631 non si
   applica), e degradarla a rail sarebbe una regressione per chi
   lavora col browser a metà schermo su un 1366px.
   ============================================================ */
@media (min-width: 600px) and (max-width: 991.98px) {

    .left-sidebar {
        transform: none !important;         /* annulla il translateX(-270px) di backend.css */
        width: var(--sb-rail-w) !important;
    }
    .body-wrapper { margin-left: var(--sb-rail-w) !important; }
    .app-header   { left: var(--sb-rail-w) !important; }

    /* Il banner scala da solo (600x164): a 64px utili resta
       riconoscibile. Nessuna immagine nuova da caricare. */
    .left-sidebar .brand-logo { padding: 10px 6px !important; }

    .left-sidebar .sidebar-nav { padding: 0 4px !important; }

    /* Voce di menu: icona sopra, microlabel sotto. */
    .left-sidebar .sidebar-item { margin-bottom: 1px !important; }
    .left-sidebar .sidebar-item .sidebar-link {
        flex-direction: column !important;
        justify-content: center !important;
        gap: 3px !important;
        padding: 7px 2px !important;
        margin: 0 !important;
        text-align: center;
        border-radius: 12px !important;
    }
    .left-sidebar .sidebar-item .sidebar-link:hover { transform: none !important; }

    /* Le dimensioni del quadratino icona sono inline nel markup
       (style="width:38px..."), quindi servono gli !important. */
    .left-sidebar .sidebar-item .sidebar-link > span:first-child {
        width: 34px !important;
        height: 34px !important;
        min-width: 34px !important;
    }
    .left-sidebar .sidebar-item .sidebar-link > span:first-child i {
        font-size: 1rem !important;
    }
    /* L'etichetta è OGNI span dopo il quadratino icona, non
       :last-child. La voce "Messaggi" ha un terzo span (il contatore
       dei non letti, sidebar.php:60-62): con :last-child il selettore
       colpiva il badge e lasciava l'etichetta al suo font-size inline
       di 0.92rem, che sfondava il rail da 76px. Verificato a schermo. */
    .left-sidebar .sidebar-item .sidebar-link > span:first-child ~ span {
        font-size: 9px !important;
        line-height: 1.15 !important;
        font-weight: 600 !important;
        letter-spacing: -0.01em;
        width: 100%;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        margin: 0 !important;   /* annulla ms-auto del badge */
    }
    /* Il contatore numerico non entra in 76px: nascosto SOLO a rail
       chiuso. Il segnale non si perde — updateMessaggiBadge()
       (sidebar.php:354) accende anche il pallino rosso sull'icona.

       La condizione body:not(.sb-nav-open) è deliberata: da espanso
       nessuna regola si applica e il badge torna a essere governato
       dal `display` inline che scrive il JS. Forzarlo visibile con un
       !important mostrerebbe una pillola rossa VUOTA anche con zero
       messaggi non letti, perché il JS lo tiene a display:none. */
    body:not(.sb-nav-open) .left-sidebar #sidebarMessaggiBadge {
        display: none !important;
    }

    /* Le intestazioni di sezione diventano un filetto separatore. */
    .left-sidebar .nav-small-cap {
        height: 1px !important;
        padding: 0 !important;
        margin: 9px 12px 7px !important;
        background: rgba(15, 23, 42, 0.10);
        overflow: hidden;
    }
    .left-sidebar .nav-small-cap span,
    .left-sidebar .nav-small-cap i { display: none !important; }

    /* Nel rail chiuso non c'è spazio: il profilo sta nel dropdown
       della topbar, la X serve solo da espanso. */
    .left-sidebar .user-profile-fixed { display: none !important; }
    .left-sidebar .close-btn          { display: none !important; }

    /* ---- Rail espanso (tap sull'hamburger): overlay a 270px ----
       Il contenuto NON si sposta: si sovrappone e si chiude. */
    body.sb-nav-open .left-sidebar {
        width: 270px !important;
        box-shadow: 8px 0 40px rgba(15, 23, 42, 0.18) !important;
    }
    body.sb-nav-open .left-sidebar .sidebar-item .sidebar-link {
        flex-direction: row !important;
        justify-content: flex-start !important;
        gap: 8px !important;
        padding: 9px 12px !important;
        text-align: left;
    }
    body.sb-nav-open .left-sidebar .sidebar-item .sidebar-link > span:first-child {
        width: 36px !important;
        height: 36px !important;
        min-width: 36px !important;
    }
    body.sb-nav-open .left-sidebar .sidebar-item .sidebar-link > span:first-child i {
        font-size: 1.15rem !important;
    }
    body.sb-nav-open .left-sidebar .sidebar-item .sidebar-link > span:first-child ~ span {
        font-size: 0.9rem !important;
        line-height: 1.3 !important;
        white-space: normal;
        width: auto;
        text-overflow: clip;
    }
    /* Da espanso il contatore torna sotto il controllo del JS (vedi
       sopra). Qui gli ridiamo solo la geometria giusta, senza toccare
       il `display`. */
    body.sb-nav-open .left-sidebar #sidebarMessaggiBadge {
        font-size: 0.7rem !important;
        width: auto;
        margin-left: auto !important;
    }
    body.sb-nav-open .left-sidebar .nav-small-cap {
        height: auto !important;
        background: none !important;
        padding: 0 0 0 12px !important;
        margin: 12px 0 6px !important;
        overflow: visible;
    }
    body.sb-nav-open .left-sidebar .nav-small-cap span { display: inline !important; }
    body.sb-nav-open .left-sidebar .user-profile-fixed { display: block !important; }
    body.sb-nav-open .left-sidebar .close-btn          { display: block !important; }
}


/* ============================================================
   3. DRAWER — ≤ 599.98px (schermo esterno / cover)
   ============================================================ */
@media (max-width: 599.98px) {

    .left-sidebar {
        width: var(--sb-drawer-w) !important;
        transform: translateX(-102%) !important;
        border-right: none !important;
    }
    body.sb-nav-open .left-sidebar {
        transform: none !important;
        box-shadow: 8px 0 40px rgba(15, 23, 42, 0.28) !important;
    }

    /* Blocca lo scorrimento della pagina dietro al menu aperto. */
    body.sb-nav-open { overflow: hidden !important; }

    .body-wrapper { margin-left: 0 !important; }
    .app-header   { left: 0 !important; }

    .content-wrapper { padding-left: 12px !important; padding-right: 12px !important; }

    /* Topbar: la barra di ricerca diventa un bottone da 44px.
       Il contenitore resta il trigger del modal (role="button"). */
    .app-header .search-wrapper  { margin-right: 8px !important; }
    .app-header .search-input    { display: none !important; }
    .app-header .search-container {
        width: var(--sb-touch);
        height: var(--sb-touch);
    }
    .app-header .search-btn {
        position: static !important;
        inset: auto !important;
        width: var(--sb-touch) !important;
        height: var(--sb-touch) !important;
    }
    .app-header .d-flex.align-items-center.gap-3 { gap: 8px !important; }
}


/* ============================================================
   4. ZONA 992 … 1199.98px
   ------------------------------------------------------------
   Qui la sidebar piena funziona già. L'unico difetto è
   l'hamburger (.d-xl-none, quindi visibile fino a 1199.98) che
   non ha alcuna regola CSS associata: è un bottone morto.
   Lo nascondiamo invece di inventare un comportamento.
   ============================================================ */
@media (min-width: 992px) and (max-width: 1199.98px) {
    .sb-nav-toggle-wrap { display: none !important; }
}


/* ============================================================
   5. RIMAPPA col-md-*  — 600 … 767.98px
   ------------------------------------------------------------
   IL CUORE DELLA RICHIESTA. Il backend usa 185 col-md-* e ZERO
   col-sm-/col-lg-/col-xl-: sotto 768px ogni griglia collassa a
   colonna singola. Lo schermo interno del Fold è ~690px, cioè
   dentro questo buco: un display da mini-tablet riceve un
   layout da telefono.

   Queste 12 regole rimettono in colonna 185 punti di markup
   senza toccarne nemmeno uno. Mappatura prudente: le colonne
   più strette salgono di taglia per non scendere sotto ~150px
   di larghezza utile, e le coppie 4+8 / 3+9 restano allineate.
   ============================================================ */
@media (min-width: 600px) and (max-width: 767.98px) {

    .row > .col-md-1,
    .row > .col-md-2  { flex: 0 0 auto; width: 25%; }

    .row > .col-md-3,
    .row > .col-md-4  { flex: 0 0 auto; width: 33.333333%; }

    .row > .col-md-5,
    .row > .col-md-6  { flex: 0 0 auto; width: 50%; }

    .row > .col-md-7  { flex: 0 0 auto; width: 58.333333%; }

    .row > .col-md-8,
    .row > .col-md-9  { flex: 0 0 auto; width: 66.666667%; }

    .row > .col-md-10,
    .row > .col-md-11,
    .row > .col-md-12 { flex: 0 0 auto; width: 100%; }

    /* Via di fuga: dove due colonne non funzionano (label lunghe,
       Select2, campi indirizzo) basta aggiungere questa classe
       alla .row nel markup e la riga torna a colonna singola. */
    .row.sb-no-split > [class*="col-md-"] { width: 100% !important; }

    /* Compattazione che accompagna la rimappa: senza questa, due
       colonne a 690px risultano strette. */
    .row { --bs-gutter-x: 0.85rem; }
    .form-label { font-size: 0.8rem; margin-bottom: 4px; }
    .content-wrapper .card-body { padding: 14px 16px; }
}


/* ============================================================
   6. SBLOCCO DEGLI SFONDAMENTI
   ------------------------------------------------------------
   body{overflow-x:hidden} (backend.css:19) e gli overflow:hidden
   sui contenitori non risolvono gli sfondamenti: li AMPUTANO.
   Il pulsante "Nuovo Cliente" e i bottoni di paginazione non
   escono con uno scroll — spariscono.

   La correzione giusta non è sbloccare il clipping (farebbe
   comparire scroll orizzontali ovunque) ma far ANDARE A CAPO le
   barre che oggi non lo fanno. Il contenuto rientra e nulla
   viene più tagliato.
   ============================================================ */
@media (max-width: 1199.98px) {

    /* ---- LA CAUSA RADICE, trovata misurando in un browser vero ----
       .page-wrapper è un flex container e .body-wrapper è il suo
       flex item (flex:1). Un flex item ha min-width:auto per
       default: si RIFIUTA di scendere sotto la larghezza minima del
       proprio contenuto. La tabella clienti, con white-space:nowrap
       sugli <th> e le email per esteso, ha un min-content di ~1164px
       — quindi .body-wrapper resta larga 1164px anche dentro un
       viewport da 360px.

       Conseguenza a catena: .table-responsive dichiara
       overflow-x:auto ma è largo quanto la tabella, quindi non
       scorre MAI; e tutto ciò che eccede finisce semplicemente
       tagliato da body{overflow-x:hidden}.

       min-width:0 restituisce al flex item il permesso di
       restringersi. Solo allora .table-responsive diventa un vero
       contenitore scorrevole e la tabella scorre al suo interno
       invece di trascinarsi dietro l'intera pagina. Senza questa
       riga nessuna delle regole qui sotto avrebbe effetto. */
    .body-wrapper    { min-width: 0 !important; }
    .content-wrapper { min-width: 0; max-width: 100%; }
    .content-wrapper > * { min-width: 0; }

    /* Stessa trappola dentro i .row di Bootstrap: le colonne sono
       flex item e un campo lungo (email, IBAN, indirizzo) le
       gonfierebbe oltre la riga. */
    .row > [class*="col-"] { min-width: 0; }

    /* Barra ricerca + Esporta + Nuovo (9 pagine lista).
       Il markup è .search-bar.d-flex.justify-content-between,
       e .d-flex di Bootstrap non manda a capo. */
    .search-bar {
        flex-wrap: wrap !important;
        gap: 12px;
    }
    .search-bar > .filter-search { flex: 1 1 220px; min-width: 0; }
    .search-bar .filter-search input { width: 100% !important; }

    /* Paginazione: è DENTRO .clients-table-card{overflow:hidden}
       (table-style.css:271), quindi ciò che sfonda è invisibile. */
    .pagination-wrapper {
        flex-wrap: wrap !important;
        gap: 12px;
        justify-content: center !important;
        padding: 16px !important;
    }
    .pagination-controls { flex-wrap: wrap; justify-content: center; gap: 12px !important; }
    .pagination-buttons  { flex-wrap: wrap; justify-content: center; }

    /* Le stat card sono bloccate a repeat(3,1fr): a 360px
       diventano tre colonne da 100px. */
    .stats-cards {
        grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)) !important;
        gap: 12px !important;
    }

    /* Intestazioni di pagina: titolo + bottoni in flex senza wrap. */
    .page-title-card,
    .page-header { flex-wrap: wrap; gap: 10px; }
}

@media (max-width: 599.98px) {
    .stats-cards { grid-template-columns: repeat(2, 1fr) !important; }
    .stat-card   { padding: 14px !important; }
    .stat-icon   { width: 40px !important; height: 40px !important; font-size: 19px !important; }
    .stat-value  { font-size: 22px !important; }
    .stat-label  { font-size: 10px !important; letter-spacing: 0.4px !important; }
    .page-title  { font-size: 20px !important; }
    .page-title-card, .search-card { padding: 14px 16px !important; }

    /* I bottoni d'azione occupano metà riga ciascuno invece di
       uscire dallo schermo. */
    .search-bar .btn-export,
    .search-bar .btn-new-client,
    .search-bar .btn-add-client { flex: 1 1 calc(50% - 6px); justify-content: center; }
}


/* ============================================================
   7. LAYER TOUCH — target da 44px
   ------------------------------------------------------------
   La guardia di larghezza è obbligatoria: un laptop Windows
   touchscreen o un Surface riportano pointer:coarse a 1920px e
   senza `and (max-width:1199.98px)` ingrasserebbero il desktop.
   ============================================================ */
@media (pointer: coarse) and (max-width: 1199.98px) {

    .hamburger-btn,
    .action-icon-btn {
        min-width: var(--sb-touch) !important;
        min-height: var(--sb-touch) !important;
    }

    .pagination-btn {
        min-width: var(--sb-touch) !important;
        min-height: var(--sb-touch) !important;
    }
    .pagination-btn.nav-btn { min-width: auto !important; padding: 0 14px !important; }

    .action-btn,
    .table .btn-sm,
    .modern-table .btn-sm {
        min-width: 38px;
        min-height: 38px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* Checkbox: 18px è metà del minimo. Ingrandiamo il box e
       allarghiamo l'area sensibile della cella. */
    .custom-checkbox,
    .select-all-checkbox { width: 22px !important; height: 22px !important; }
    .checkbox-cell { min-width: 46px !important; }

    /* La X dei modal è il bersaglio più mancato di tutti. */
    .modal .btn-close {
        min-width: var(--sb-touch);
        min-height: var(--sb-touch);
        background-size: 14px;
    }

    /* font-size < 16px su un input fa ZOOMARE la pagina al focus
       su Chrome/Safari mobile, e il layout non torna più a posto.
       Questa è la singola regola che più spesso fa sembrare
       "rotto" un form su telefono. */
    input[type="text"],
    input[type="email"],
    input[type="tel"],
    input[type="url"],
    input[type="number"],
    input[type="password"],
    input[type="search"],
    input[type="date"],
    input[type="datetime-local"],
    input[type="time"],
    textarea,
    select,
    .form-control,
    .form-select,
    .search-input,
    .filter-search input { font-size: 16px !important; }
}


/* ============================================================
   8. LAYER HOVER — niente azioni invisibili sul dito
   ------------------------------------------------------------
   Senza guardia di larghezza: rendere visibile un pulsante non
   cambia la geometria e non rompe nulla, nemmeno su un
   touchscreen grande.

   I 5 pattern qui sotto vengono da un grep esaustivo di
   `opacity:0` + `:hover` su backend/. Su Android oggi queste
   funzioni NON ESISTONO: non sono scomode, sono irraggiungibili.
   ============================================================ */
@media (hover: none) {

    .kcard-actions,                 /* dashboard.php:1165 + todolist.php:617 — modifica/archivia/elimina to-do */
    .doc-card .doc-actions,         /* documenti.php:89     — rinomina/elimina documento                       */
    .chat-conv-item .chat-conv-delete {  /* chat_widget.php:285 — elimina conversazione                        */
        opacity: 1 !important;
        visibility: visible !important;
    }

    /* marketing.php:512 — l'anteprima del documento si apre solo
       in hover: su touch il picker è cieco. */
    .doc-picker-item .doc-pick-preview { display: flex !important; }

    /* contabilita.php:849 — l'unica affordance della modifica
       inline è un :hover. Senza segnale visivo, la funzione è
       invisibile: la marchiamo con un tratteggio. */
    .inline-value {
        border-bottom: 1px dashed rgba(22, 91, 236, 0.45);
        padding-bottom: 1px;
    }

    /* Neutralizza gli effetti hover che su touch restano
       "appiccicati" dopo il tap finché non si tocca altrove. */
    .sidebar-item .sidebar-link:hover { transform: none !important; }
    .quick-btn:hover,
    .card:hover,
    .stat-card:hover,
    .kanban-card:hover { transform: none !important; }
}


/* ============================================================
   9. OVERLAY FLOTTANTI — scala z-index sanificata
   ------------------------------------------------------------
   Situazione attuale: la chat è figlia diretta di <body> a
   z-index 9999, quindi galleggia SOPRA ogni modal e copre
   proprio l'angolo dove stanno Salva / Esporta / Invia.
   Il toaster dichiara 10050 ma è incluso da topbar.php, cioè
   dentro .body-wrapper{z-index:1}: vale 1 ed è intrappolato.
   (crm-mobile.js lo rialloca su <body>.)

   Riferimento Bootstrap 5: backdrop 1050, modal 1055.
   Il FAB va SOTTO il backdrop, non sopra.
   ============================================================ */
@media (max-width: 1199.98px) {

    .chat-widget { z-index: 1040 !important; }

    /* Cintura di sicurezza: Bootstrap mette .modal-open sul body
       ad ogni modal aperto. Vale anche per i modal futuri. */
    body.modal-open .chat-widget { display: none !important; }

    #notifToastContainer {
        z-index: 1045 !important;
        left: 12px;
        right: 12px;
        bottom: calc(12px + var(--sa-b)) !important;
        max-height: 42dvh;
        overflow-y: auto;
        overscroll-behavior: contain;
    }

    /* Il drawer aperto deve coprire chat e toast. */
    body.sb-nav-open .chat-widget,
    body.sb-nav-open #notifToastContainer { display: none !important; }
}

@media (max-width: 599.98px) {
    /* I modal a schermo pieno sotto i 600px: su un cover da 360px
       un modal centrato lascia 20px di margine inutile per lato e
       taglia i pulsanti in fondo. */
    .modal-dialog:not(.modal-fullscreen) {
        margin: 0 !important;
        max-width: 100% !important;
        min-height: 100dvh;
    }
    .modal-content {
        border-radius: 0 !important;
        min-height: 100dvh;
    }
    .modal-body { padding: 16px !important; }
    .modal-footer {
        padding: 12px 16px calc(12px + var(--sa-b)) !important;
        position: sticky;
        bottom: 0;
        background: #fff;
    }
    .modal-footer .btn { flex: 1 1 auto; }
}


/* ============================================================
   11. LISTE E TABELLE  (Fase 2)
   ------------------------------------------------------------
   Tutte e 10 le pagine-lista usano `.modern-table`: un solo
   selettore le raggiunge tutte. Il contenitore invece è
   `.clients-table-card` ovunque TRANNE referenti.php, che usa
   `.table-card` — da qui i selettori doppi.

   Strategia decisa: tabella DENSA, mai card impilate. A 690px la
   maggior parte delle liste entra quasi per intero; dove non
   entra si scorre dentro `.table-responsive` con la colonna
   identità ancorata a sinistra e le azioni ancorate a destra,
   così non si perde mai il riferimento della riga.
   ============================================================ */
@media (max-width: 1199.98px) {

    /* ---- Densità ----
       L'intestazione passa da padding 20/28 a 10/10 e soprattutto
       da white-space:nowrap a normal: i titoli lunghi ("Codice
       Fiscale / P.IVA", "Tipologia Contratto") vanno su due righe
       invece di allargare la colonna. È la singola modifica che
       restringe di più la tabella. */
    .modern-table thead th {
        padding: 10px !important;
        font-size: 10.5px !important;
        letter-spacing: 0.3px !important;
        white-space: normal !important;
        line-height: 1.2;
        vertical-align: middle;
    }
    .modern-table tbody td {
        padding: 9px 10px !important;
        font-size: 12.5px;
        vertical-align: middle;
    }

    .client-name     { font-size: 12.5px; font-weight: 700; line-height: 1.25; }
    .client-subtitle { font-size: 10px; line-height: 1.2; }
    code.cf-piva     { font-size: 11px !important; letter-spacing: 0 !important; }
    .client-badge    { padding: 3px 7px !important; font-size: 9px !important; }
    .client-badge-sm { padding: 2px 6px !important; font-size: 8.5px !important; }
    .ranking-text    { font-size: 11px; }

    /* Email e telefoni: troncati con ellissi invece di mandare la
       riga a capo. Su mobile conta vedere più righe; il dato
       completo è a un tap di distanza nella scheda. */
    .modern-table tbody td .contact-link {
        padding: 3px 6px !important;
        font-size: 11.5px;
        gap: 3px;
        max-width: 150px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap !important;
        vertical-align: middle;
    }

    .action-btn-group, .action-buttons { gap: 4px !important; }

    /* La variante a 4 colonne di contabilita.php, che il blocco
       generico delle stat-card non intercetta. */
    .stats-cards-4 {
        grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)) !important;
        gap: 12px !important;
    }
}


/* ---- Colonne ancorate ----
   Attive solo dove la tabella non entra: sopra i 900px le liste
   ci stanno quasi tutte e ancorare sarebbe solo rumore visivo.
   Le classi sb-col-id / sb-col-act le assegna crm-mobile.js
   leggendo le intestazioni, perché la colonna identità NON è
   sempre nella stessa posizione: 3ª in clienti e contratti, 2ª in
   aziende/agenti/agenzie/referenti, 1ª in prospect e contabilità. */
@media (max-width: 899.98px) {

    .modern-table td.sb-col-id,
    .modern-table td.sb-col-act {
        position: sticky;
        z-index: 2;
        /* Lo sfondo zebrato è dichiarato sul <tr>: senza `inherit`
           la cella ancorata sarebbe trasparente e le altre le
           scorrerebbero visibilmente sotto. */
        background: inherit;
    }
    .modern-table td.sb-col-id  { left: 0; }
    .modern-table td.sb-col-act { right: 0; }

    /* In <thead> lo sfondo sta sul thead, non sul tr: `inherit`
       darebbe trasparente. Serve un colore pieno. */
    .modern-table th.sb-col-id,
    .modern-table th.sb-col-act {
        position: sticky;
        z-index: 3;
        background: #eef0f3;
    }
    .modern-table th.sb-col-id  { left: 0; }
    .modern-table th.sb-col-act { right: 0; }

    /* Un filo d'ombra segnala che sotto la cella ancorata sta
       scorrendo dell'altro contenuto. */
    .modern-table td.sb-col-id, .modern-table th.sb-col-id  { box-shadow: 6px 0 8px -8px rgba(15,23,42,.45); }
    .modern-table td.sb-col-act, .modern-table th.sb-col-act { box-shadow: -6px 0 8px -8px rgba(15,23,42,.45); }

    .modern-table td.sb-col-id { max-width: 160px; }
}


/* ---- Priorità colonne sul cover ----
   Sotto i 600px restano identità, un paio di colonne utili e le
   azioni. data-sb-prio="3" lo assegna crm-mobile.js in base al
   testo dell'intestazione. */
@media (max-width: 599.98px) {
    .modern-table th[data-sb-prio="3"],
    .modern-table td[data-sb-prio="3"] { display: none !important; }

    .modern-table thead th { padding: 8px 7px !important; font-size: 10px !important; }
    .modern-table tbody td { padding: 8px 7px !important; font-size: 12px; }
    .modern-table tbody td .contact-link { max-width: 118px; }
    .modern-table td.sb-col-id { max-width: 130px; }
}


/* ---- Riga interamente toccabile ----
   `.modern-table tbody tr` ha già cursor:pointer (table-style.css:549)
   ma NESSUN handler: il record si apre solo centrando il chevron
   nell'ultima colonna, che su una tabella da 1164px è fuori
   schermo. crm-mobile.js aggiunge il click di riga e marca la
   riga con .sb-row-tap. */
@media (max-width: 1199.98px) {
    .modern-table tbody tr.sb-row-tap { -webkit-tap-highlight-color: rgba(22, 91, 236, 0.10); }
    .modern-table tbody tr.sb-row-tap:active > td { background: rgba(22, 91, 236, 0.07); }

    /* La casella di selezione deve restare un bersaglio suo,
       distinto dal tap che apre la scheda. */
    .modern-table td.checkbox-cell { position: relative; }
}


/* ============================================================
   12. DASHBOARD  (Fase 3)
   ------------------------------------------------------------
   `.dashboard-layout` è una griglia 1fr/380px che sotto i 1200px
   collassa a una colonna sola. Il problema non è il collasso: è
   l'ORDINE. Tutta `.dashboard-side` (chat + "Eventi di oggi" +
   grafico produzione) finisce DOPO l'intera `.dashboard-main`,
   cioè dopo le azioni rapide e tutta la board delle to-do. Da
   telefono "Eventi di oggi" — la cosa che si apre la mattina per
   sapere cosa si fa — sta a un paio di migliaia di pixel di
   scroll.

   `display: contents` scioglie i due contenitori: i loro figli
   diventano elementi diretti della griglia e possono essere
   riordinati singolarmente, senza toccare il markup PHP.
   ============================================================ */
@media (max-width: 1199.98px) {

    /* !important obbligatorio: il <style> di dashboard.php sta a
       riga 928, cioè nel <body>, quindi DOPO questo file. La sua
       regola `.dashboard-side { display: flex }` vincerebbe.
       Stessa situazione in todolist.php (485) e grafico.php (816);
       calendario.php invece ha il suo <style> nell'head. */
    .dashboard-main,
    .dashboard-side { display: contents !important; }

    /* Ordine su telefono: prima cosa si fa oggi, poi le attività,
       poi le scorciatoie, la chat per ultima (si apre dal FAB). */
    .dashboard-side .dash-side-card:first-of-type { order: 1; }  /* Eventi di oggi */
    .quick-actions                                { order: 2; }
    .todo-section                                 { order: 3; }
    .dashboard-side .dash-side-card:last-of-type  { order: 4; }  /* Produzione mese */
    .dash-chat-card                               { order: 5; }

    /* Sciolti da `contents`, i figli perdono il gap del flex della
       colonna destra: lo riprende la griglia. */
    .dashboard-layout { gap: 16px !important; }
    .quick-actions    { margin-bottom: 0 !important; }
}

@media (max-width: 599.98px) {
    /* Le azioni rapide occupavano mezza schermata prima di
       arrivare al contenuto vero.

       Il prefisso `body` non è decorativo: crm-redesign.css è
       iniettato da topbar.php, quindi dal <body>, e quindi DOPO
       questo file. Su `.quick-actions{padding}`, `.quick-btn{padding}`
       e `.quick-btn-icon{width/height}` usa a sua volta !important:
       a parità di specificità vincerebbe lui perché caricato dopo.
       Alzare la specificità è l'unico modo per avere la meglio.
       Sono le uniche 4 collisioni fra i due file — verificate
       confrontandoli proprietà per proprietà. */
    body .quick-actions   { padding: 14px 16px !important; }
    body .quick-btn       { padding: 12px 8px !important; min-height: 74px; }
    body .quick-btn-icon  { width: 36px !important; height: 36px !important; margin-bottom: 6px; }
    .quick-btn-icon i     { font-size: 17px; }
    .quick-btn-text       { font-size: 11px; }
}


/* ============================================================
   13. KANBAN TO-DO  (dashboard.php + todolist.php)
   ------------------------------------------------------------
   Oggi la board passa da 3 colonne a UNA sola sotto i 900px
   (dashboard) e sotto i 1100px (todolist). Sullo schermo interno
   del Fold significa impilare tre colonne in verticale proprio
   dove lo spazio per affiancarle ci sarebbe: l'opposto di quello
   che serve.
   ============================================================ */
@media (min-width: 600px) and (max-width: 1199.98px) {
    /* Tre colonne compattate invece di una impilata. */
    .kanban-board {
        grid-template-columns: repeat(3, 1fr) !important;
        gap: 10px !important;
    }
    .kanban-column     { min-height: 140px !important; }
    .kanban-col-header { padding: 10px 11px !important; }
    .kanban-col-title  { font-size: 12px !important; }
    .kanban-card       { padding: 10px !important; }
}

@media (max-width: 599.98px) {
    /* Sul cover tre colonne non entrano: diventano un carosello
       che scorre di lato con aggancio, invece di una colonna sola
       lunga tre schermate. Le tre liste restano confrontabili. */
    .kanban-board {
        grid-template-columns: none !important;
        display: flex !important;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        gap: 10px !important;
        padding-bottom: 8px;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
    }
    .kanban-column {
        flex: 0 0 86%;          /* si intravede la colonna dopo: suggerisce lo scorrimento */
        scroll-snap-align: start;
        min-height: 120px !important;
    }
}

@media (pointer: coarse) and (max-width: 1199.98px) {
    /* Il selettore di esito è il comando più usato della board. */
    .kcard-esito-select { min-height: var(--sb-touch) !important; font-size: 16px !important; }
    .kcard-actions button { min-width: 36px; min-height: 36px; }
}


/* ============================================================
   14. CALENDARIO  (Fase 3)
   ------------------------------------------------------------
   La vista mensile a 360px rende le celle illeggibili: sotto i
   600px crm-mobile.js passa a `listWeek` (agenda), e torna a
   `dayGridMonth` riaprendo il telefono. Qui resta la geometria.
   ============================================================ */
@media (max-width: 1199.98px) {

    /* `min-height: calc(100vh - 130px)` su Android salta quando la
       barra URL si ritrae; e 750px fissi obbligano a scorrere
       anche quando il mese è corto. */
    .calendar-container,
    .day-detail-sidebar { min-height: 0 !important; }
    .fc { min-height: 0 !important; }

    /* Titolo + bottoni in flex senza wrap: ~577px di larghezza
       minima, quindi sfondava già sul cover. */
    .page-header .header-content { flex-wrap: wrap; gap: 12px !important; }
    .page-header { margin-bottom: 16px !important; }
    .header-left h2 { font-size: 21px !important; gap: 8px !important; }

    .fc .fc-toolbar { flex-wrap: wrap; gap: 8px; }
    .fc .fc-toolbar-title { font-size: 1.05rem !important; }
    .fc .fc-button { padding: 6px 10px !important; }
}

@media (max-width: 899.98px) {
    /* Il pannello del giorno da colonna laterale diventa un
       foglio che sale dal basso: a 690px una colonna da 320px si
       mangerebbe metà del calendario. */
    .calendar-grid { flex-direction: column; }
    .calendar-grid.show-sidebar .calendar-container { flex: 1 1 auto !important; }
    .calendar-grid.show-sidebar .day-detail-sidebar {
        flex: 1 1 auto !important;
        width: auto !important;
        order: -1;                      /* sopra il calendario: è ciò che hai appena toccato */
        max-height: 60dvh;
        overflow-y: auto;
        overscroll-behavior: contain;
    }
}

@media (max-width: 599.98px) {
    /* `position: fixed; min-width: 320px` con la posizione
       calcolata una volta sola e senza clamping: su un cover da
       344px il selettore del mese usciva sempre dallo schermo.
       Diventa un foglio ancorato in basso, dove la posizione non
       va più calcolata. */
    .month-picker-dropdown {
        position: fixed !important;
        left: 0 !important;
        right: 0 !important;
        top: auto !important;
        bottom: 0 !important;
        min-width: 0 !important;
        width: auto !important;
        max-height: 80dvh;
        overflow-y: auto;
        border-radius: 18px 18px 0 0 !important;
        padding: 16px 16px calc(16px + var(--sa-b)) !important;
        transform: none !important;
    }
    .fc .fc-daygrid-day-number { font-size: 11px; }
    .fc .fc-col-header-cell-cushion { font-size: 10px; }
}


/* ============================================================
   15. GRAFICO  (Fase 3)
   ------------------------------------------------------------
   grafico.php non ha NESSUNA media query e le sue griglie sono
   dichiarate a colonna singola: resta a una colonna a qualsiasi
   larghezza, desktop compreso. Qui lo spazio dello schermo
   interno viene usato — due colonne fra 600 e 1200px.
   (Il difetto speculare sul desktop resta: correggerlo vorrebbe
   dire scrivere regole sopra i 1200px, fuori dal contratto di
   non-regressione di questo file.)
   ============================================================ */
@media (min-width: 600px) and (max-width: 1199.98px) {
    .gr-kpis { grid-template-columns: repeat(2, 1fr) !important; }
    .gr-grid { grid-template-columns: repeat(2, 1fr) !important; }
    .gr-chart-trend-card { grid-column: 1 / -1; }
}

@media (max-width: 599.98px) {
    /* Le altezze dei grafici le scrive il JS inline
       (grafico.php:349, 390, 466, 533): senza !important nessuna
       media query potrebbe correggerle. */
    .gr-chart       { height: 240px !important; }
    .gr-chart-trend { height: 220px !important; }
    .gr-kpi         { padding: 12px !important; gap: 10px !important; }
    .gr-kpi-value   { font-size: 1.25rem !important; }
    .gr-kpi-label   { font-size: 10px !important; }
    .gr-rank-name   { font-size: 11.5px; }
    .gr-head-title h2 { font-size: 1.15rem !important; }
    .gr-controls    { gap: 8px !important; }
    .gr-select      { flex: 1 1 100%; }
}


/* ============================================================
   10. UTILITY
   ============================================================ */
@media (max-width: 1199.98px) {
    /* Da applicare a QUALSIASI elemento ancorato al fondo dello
       schermo, altrimenti finisce sotto la gesture bar Android.
       Obbligatoria per le action-bar sticky della Fase 4. */
    .sb-bottom-safe { padding-bottom: calc(12px + var(--sa-b)) !important; }

    /* Rete di sicurezza diagnostica: evidenzia in rosso gli
       elementi che sfondano il viewport. Si attiva aggiungendo
       la classe sb-debug-overflow a <body> dalla console. */
    body.sb-debug-overflow * { outline: 1px solid rgba(255, 0, 0, 0.25); }
}
