/*
 * CALYPSO GESTIONALE - App Theme
 * Tema principale e variabili colore per sezioni
 */

:root {
    --calypso-primary: #1A4B7C;
    --calypso-secondary: #2d5a8a;
    --calypso-accent: #00d4aa;
    --calypso-dark: #0d2240;
    --calypso-light: #f4f7fa;
    --calypso-success: #10b981;
    --calypso-warning: #f59e0b;
    --calypso-danger: #ef4444;
    --calypso-info: #3b82f6;
    
    /* Colori sezioni */
    --section-calypso: #1A4B7C;
    --section-prestashop: #DF0067;
    --section-amazon: #FF9900;
    --section-temu: #ff4800;
    --section-tiktok: #000000;
    --section-shipping: #17a2b8;
    --section-banking: #198754;
    --section-settings: #6c757d;
    
    /* Sidebar CHIARA */
    --sidebar-bg: #f0f4f8;
    --sidebar-text: #4a5568;
    --sidebar-hover: #e2e8f0;
    --sidebar-active: var(--calypso-primary);
    --sidebar-width: 260px;
    --sidebar-collapsed: 70px;
}

/* ===== LAYOUT BASE ===== */
body {
    background-color: var(--calypso-light);
    min-height: 100vh;
}

.app-wrapper {
    display: flex;
    min-height: 100vh;
}

.app-content {
    flex: 1;
    margin-left: var(--sidebar-width);
    transition: margin-left 0.3s ease;
    min-height: 100vh;
    display: flex;
    flex-direction: column;

    /* ⚠️ QUESTA riga e' il motivo per cui la dashboard non si adattava.
       .app-content e' un figlio di .app-wrapper, che e' `display:flex`. Un
       flex item ha `min-width: auto`, cioe' NON PUO' restringersi sotto la
       larghezza intrinseca del suo contenuto: bastava una tabella un po'
       larga dentro una card perche' .app-content si allargasse oltre lo
       schermo, e con `margin-left: 260px` in piu' il totale sfondava sempre.
       Il risultato non era una card che scorre: scorreva TUTTA la pagina in
       orizzontale, fascia blu compresa. Aggiungere overflow-x:hidden ai figli
       non serviva a niente, perche' il guaio era gia' fatto qui sopra. */
    min-width: 0;
}

.app-content.sidebar-collapsed {
    margin-left: var(--sidebar-collapsed);
}

/* ⚠️ Solo sotto i 768px il contenuto va a filo: fra 768 e 992 il menu resta
   (ristretto a icone) e il margine lo tiene la regola piu' in basso. */
@media (max-width: 767.98px) {
    .app-content {
        margin-left: 0;
    }
}

/* ===== NAVBAR TOP ===== */
.navbar-top {
    background: #fff;
    border-bottom: 1px solid rgba(0,0,0,0.08);
    padding: 0.75rem 1.5rem;
    position: sticky;
    top: 0;
    z-index: 1000;
    box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}

.navbar-brand {
    font-weight: 700;
    font-size: 1.25rem;
    color: var(--calypso-primary) !important;
}

.navbar-brand span {
    font-weight: 400;
    color: #6c757d;
}

/* ===== SIDEBAR ===== */
.sidebar {
    position: fixed;
    top: 0;
    left: 0;
    /* ⚠️ Il 260px non e' un doppione: e' la rete se la variabile non arriva.
       Senza, `width: var(--sidebar-width)` con la variabile mancante diventa
       `width: auto`, e un elemento a posizione fissa con larghezza automatica
       si stringe sul contenuto - fino a zero se il contenuto e' nascosto. */
    width: var(--sidebar-width, 260px);
    height: 100vh;
    background: var(--sidebar-bg);
    border-right: 1px solid #d1d9e6;
    overflow-y: auto;
    overflow-x: hidden;
    z-index: 1050;
    transition: width 0.3s ease, transform 0.3s ease;
    scrollbar-width: thin;
    scrollbar-color: rgba(0,0,0,0.1) transparent;
}

.sidebar::-webkit-scrollbar {
    width: 5px;
}

.sidebar::-webkit-scrollbar-track {
    background: transparent;
}

.sidebar::-webkit-scrollbar-thumb {
    background: rgba(0,0,0,0.1);
    border-radius: 3px;
}

.sidebar-header {
    padding: 1.25rem 1rem;
    border-bottom: 1px solid #d1d9e6;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: #fff;
}

/* ⚠️ IL LOGO DELLA BARRA SI VEDE INTERO.
   Prima stava in un riquadro alto 30px con `overflow:hidden` e dentro
   un'immagine alta 50 in `object-fit:cover`: un ritaglio tarato sul vecchio
   logo. Caricandone un altro se ne vedeva una fetta, tagliata a meta'.
   `contain` rimpicciolisce finche' ci sta tutta; `max-width` perche' anche un
   logo largo e basso deve rientrare, e col menu ristretto lo spazio e' quello
   di un'icona. */
.sidebar-logo-link {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    text-decoration: none;
    min-width: 0;
    flex: 1 1 auto;
}
.sidebar-logo-link img {
    max-height: 40px;
    max-width: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    display: block;
}
/* Col menu ristretto resta solo il simbolo: la scritta non ci starebbe, e
   schiacciarla la renderebbe illeggibile. */
.sidebar.collapsed .sidebar-logo-link img {
    max-height: 32px;
    max-width: 38px;
    object-position: left center;
}

.sidebar-logo {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    color: var(--calypso-primary);
    text-decoration: none;
    font-weight: 700;
    font-size: 1.2rem;
}

.sidebar-logo-icon {
    width: 40px;
    height: 40px;
    background: linear-gradient(135deg, var(--calypso-primary), var(--calypso-accent));
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 1rem;
    color: #fff;
}

.sidebar-toggle {
    background: none;
    border: none;
    color: var(--sidebar-text);
    cursor: pointer;
    padding: 0.5rem;
    border-radius: 0.375rem;
    transition: all 0.2s;
}

.sidebar-toggle:hover {
    background: var(--sidebar-hover);
    color: var(--calypso-primary);
}

/* Sidebar Menu */
.sidebar-menu {
    padding: 1rem 0;
}

.sidebar-section {
    margin-bottom: 0.5rem;
}

.sidebar-section-title {
    padding: 0.5rem 1.25rem;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #718096;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.sidebar-section-title::after {
    content: '';
    flex: 1;
    height: 1px;
    background: #d1d9e6;
}

/* ⚠️ Il titolo della sezione adesso e' un <button>: senza questo si
   porterebbe dietro sfondo, bordo e allineamento predefiniti del browser, e
   diventerebbe un rettangolo grigio in mezzo al menu. */
button.sidebar-section-title {
    width: 100%;
    background: none;
    border: 0;
    text-align: left;
    cursor: pointer;
    font-family: inherit;
}

button.sidebar-section-title:hover {
    color: #4a5568;
}

/* Il segno di apertura: gira quando il gruppo si chiude.
   ⚠️ Sta DOPO la riga di separazione (`::after` ha `flex:1`), quindi non gli
   ruba spazio e resta sempre all'estrema destra, dove lo si cerca. */
.sidebar-section-chevron {
    font-size: 0.6rem;
    opacity: 0.55;
    transition: transform 0.2s ease;
    order: 3;
}

.sidebar-section.chiusa .sidebar-section-chevron {
    transform: rotate(-90deg);
}

/* ⚠️ `display:none` e non `height:0`: una voce nascosta ma ancora nel flusso
   resta raggiungibile col TAB, e si finisce a "navigare" dentro un gruppo che
   sullo schermo e' chiuso. */
.sidebar-section.chiusa .sidebar-section-voci {
    display: none;
}

/* Col menu ristretto le sezioni non si chiudono: i titoli sono gia' nascosti,
   e un gruppo chiuso li' dentro sparirebbe senza modo di riaprirlo. */
.sidebar.collapsed .sidebar-section-chevron {
    display: none;
}

.sidebar.collapsed .sidebar-section.chiusa .sidebar-section-voci {
    display: block;
}


.sidebar-link {
    display: flex;
    align-items: center;
    padding: 0.65rem 1.25rem;
    color: var(--sidebar-text);
    text-decoration: none;
    transition: all 0.2s;
    border-left: 3px solid transparent;
    gap: 0.75rem;
    font-size: 0.9rem;
}

.sidebar-link:hover {
    background: var(--sidebar-hover);
    color: var(--calypso-primary);
    border-left-color: var(--calypso-accent);
}

.sidebar-link.active {
    background: #e2e8f0;
    color: var(--calypso-primary);
    border-left-color: var(--calypso-primary);
    font-weight: 500;
}

.sidebar-link i {
    width: 20px;
    font-size: 1.1rem;
    text-align: center;
    flex-shrink: 0;
    color: inherit; /* Eredita colore dal link parent */
}

.sidebar-link:hover i,
.sidebar-link.active i {
    color: inherit;
}

.sidebar-link-text {
    white-space: nowrap;
    overflow: hidden;
}

/* Colore di sezione nel menu: solo il filetto a sinistra.
   ⚠️ Prima queste regole coloravano anche il TESTO della voce, ognuna col
   colore del suo marketplace: passandoci sopra, la voce cambiava colore e il
   menu sembrava un arcobaleno. Le voci restano tutte dello stesso nero e si
   leggono; a dire in che sezione si e' ci pensano il titolo colorato e il
   filetto. */
.sidebar-link[data-section="calypso"]:hover,
.sidebar-link[data-section="calypso"].active { border-left-color: var(--section-calypso); }

.sidebar-link[data-section="prestashop"]:hover,
.sidebar-link[data-section="prestashop"].active { border-left-color: var(--section-prestashop); }

.sidebar-link[data-section="amazon"]:hover,
.sidebar-link[data-section="amazon"].active { border-left-color: var(--section-amazon); }

.sidebar-link[data-section="temu"]:hover,
.sidebar-link[data-section="temu"].active { border-left-color: var(--section-temu); }

.sidebar-link[data-section="tiktok"]:hover,
.sidebar-link[data-section="tiktok"].active { border-left-color: var(--section-tiktok); }

.sidebar-link[data-section="shipping"]:hover,
.sidebar-link[data-section="shipping"].active { border-left-color: var(--section-shipping); }

.sidebar-link[data-section="banking"]:hover,
.sidebar-link[data-section="banking"].active { border-left-color: var(--section-banking); }

/**
 * ⚠️ IL MENU HA UN PAVIMENTO: NON PUO' SCENDERE SOTTO LA SUA LARGHEZZA.
 *
 * Sulla scheda ordine di Matteo il menu risultava largo ZERO pixel pur avendo
 * dentro ottantasei voci, con la finestra a 1280 px e l'unica regola attiva che
 * diceva 260. Lo si e' misurato dal browser: `display:block`,
 * `visibility:visible`, `transform:none`, opacita' 1, nessuno stile in linea,
 * `--sidebar-width` a 260px, e il contenuto della pagina col suo regolare
 * `margin-left: 260px`. Tutto a posto, e il menu invisibile.
 *
 * ⚠️ La regola che lo schiaccia non l'ho trovata: qualcosa, su quella pagina,
 * porta la larghezza a zero senza nominare `.sidebar` - probabilmente una
 * regola che colpisce l'elemento per un'altra via. Non so ancora quale, e lo
 * dico invece di far finta.
 *
 * Ma il modo di guasto lo conosco: la larghezza collassa. E per quello esiste
 * uno strumento che non e' un'ipotesi - `min-width` vince su `width`,
 * qualunque regola l'abbia scritta e comunque sia stata calcolata. Da 992 px in
 * su il menu ha un pavimento, e sotto quel pavimento non ci va piu'.
 *
 * ⚠️ Non e' un cerotto sopra un difetto ignoto per pigrizia: e' un vincolo
 * giusto in se'. Un menu di navigazione largo meno della sua misura non e' mai
 * quello che si vuole, e dichiararlo rende la pagina robusta anche al prossimo
 * foglio di stile che qualcuno aggiungera'.
 */
@media (min-width: 992px) {
    .sidebar:not(.collapsed) {
        min-width: var(--sidebar-width, 260px);
    }
    .sidebar.collapsed {
        min-width: var(--sidebar-collapsed, 70px);
    }
    /* Il contenuto tiene il suo margine per la stessa ragione. */
    .app-content:not(.sidebar-collapsed) {
        margin-left: var(--sidebar-width, 260px);
    }
}

/* Sidebar Collapsed State */
.sidebar.collapsed {
    width: var(--sidebar-collapsed);
}

.sidebar.collapsed .sidebar-logo-text,
.sidebar.collapsed .sidebar-link-text,
.sidebar.collapsed .sidebar-section-title {
    display: none;
}

.sidebar.collapsed .sidebar-link {
    justify-content: center;
    padding: 0.75rem;
}

.sidebar.collapsed .sidebar-link i {
    font-size: 1.25rem;
}

/* ⚠️ FRA 768 E 992 IL MENU RESTA, RISTRETTO A ICONE.
 *
 * Prima sotto i 992px il menu spariva del tutto, come su un telefono. Ma 992px
 * non e' un telefono: e' una finestra di computer un po' stretta, o - il caso
 * di Matteo - uno schermo con la scalatura di Windows al 125/150%, dove
 * 1300 pixel veri diventano meno di 992 pixel CSS. Aprendo un ordine si
 * ritrovava senza menu, e l'unico modo per riaprirlo era il pulsante in cima
 * alla pagina: su una scheda ordine lunga tremila righe vuol dire risalire
 * fino in cima per cambiare pagina.
 *
 * In questa fascia il menu resta attaccato a sinistra a 70px, con le sole
 * icone: costa poco spazio e non ti lascia mai a piedi. Sotto i 768px -
 * quello si' un telefono - torna a scomparire dietro il pulsante.
 */
@media (min-width: 768px) and (max-width: 991.98px) {
    .sidebar {
        width: var(--sidebar-collapsed);
    }
    .sidebar .sidebar-logo-text,
    .sidebar .sidebar-link-text,
    .sidebar .sidebar-section-title,
    .sidebar .sidebar-section-chevron,
    .sidebar .sidebar-toggle {
        display: none;
    }
    /* ⚠️ I gruppi chiusi si riaprono: i titoli sono nascosti, e un gruppo
       chiuso qui dentro sparirebbe senza modo di riaprirlo. */
    .sidebar .sidebar-section.chiusa .sidebar-section-voci {
        display: block;
    }
    .sidebar .sidebar-link {
        justify-content: center;
        padding: 0.75rem;
    }
    .sidebar .sidebar-link i {
        font-size: 1.25rem;
    }
    .app-content {
        margin-left: var(--sidebar-collapsed);
    }
    /* Il pulsante del menu non serve piu': il menu c'e' gia'. */
    .mobile-sidebar-toggle,
    .sidebar-backdrop {
        display: none !important;
    }
}

/* Mobile Sidebar */
@media (max-width: 767.98px) {
    .sidebar {
        transform: translateX(-100%);
        box-shadow: 2px 0 10px rgba(0,0,0,0.1);
    }
    
    .sidebar.show {
        transform: translateX(0);
    }
    
    .sidebar-backdrop {
        display: none;
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0,0,0,0.3);
        z-index: 1040;
    }
    
    .sidebar-backdrop.show {
        display: block;
    }
}

/* ===== PAGE HEADER ===== */
.page-header {
    padding: 1.5rem;
    background: #fff;
    border-bottom: 1px solid rgba(0,0,0,0.05);
}

.page-title {
    margin: 0;
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--calypso-dark);
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.page-title i {
    color: var(--calypso-primary);
}

/* ===== MAIN CONTENT ===== */
.main-content {
    flex: 1;
    padding: 1.5rem;
    min-width: 0;
    overflow-x: hidden;
}

/* ===== CARDS ENHANCED ===== */
.card {
    border: none;
    border-radius: 0.75rem;
    box-shadow: 0 1px 3px rgba(0,0,0,0.08);
    transition: box-shadow 0.2s;
}

.card:hover {
    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

.card-header {
    background: #fff;
    border-bottom: 1px solid rgba(0,0,0,0.05);
    padding: 1rem 1.25rem;
    font-weight: 600;
    border-radius: 0.75rem 0.75rem 0 0 !important;
}

.card-header.bg-gradient {
    background: linear-gradient(135deg, var(--calypso-primary), var(--calypso-secondary)) !important;
    color: #fff;
}

/* Section colored headers */
.card-header.section-calypso { background: linear-gradient(135deg, var(--section-calypso), #2d5a8a) !important; color: #fff; }
.card-header.section-prestashop { background: linear-gradient(135deg, var(--section-prestashop), #ff1a75) !important; color: #fff; }
.card-header.section-amazon { background: linear-gradient(135deg, var(--section-amazon), #ffb84d) !important; color: #000; }
.card-header.section-temu { background: linear-gradient(135deg, var(--section-temu), #ff6633) !important; color: #fff; }
.card-header.section-tiktok { background: linear-gradient(135deg, var(--section-tiktok), #333) !important; color: #fff; }
.card-header.section-shipping { background: linear-gradient(135deg, var(--section-shipping), #20c997) !important; color: #fff; }
.card-header.section-banking { background: linear-gradient(135deg, var(--section-banking), #28a745) !important; color: #fff; }

/* ===== STATS CARDS ===== */
.stat-card {
    border-radius: 0.75rem;
    padding: 1.25rem;
    background: #fff;
    box-shadow: 0 1px 3px rgba(0,0,0,0.08);
    display: flex;
    align-items: center;
    gap: 1rem;
    transition: all 0.2s;
}

.stat-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0,0,0,0.12);
}

.stat-icon {
    width: 56px;
    height: 56px;
    border-radius: 0.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    color: #fff;
}

.stat-icon.bg-primary { background: linear-gradient(135deg, var(--calypso-primary), var(--calypso-secondary)); }
.stat-icon.bg-success { background: linear-gradient(135deg, #10b981, #34d399); }
.stat-icon.bg-warning { background: linear-gradient(135deg, #f59e0b, #fbbf24); }
.stat-icon.bg-danger { background: linear-gradient(135deg, #ef4444, #f87171); }
.stat-icon.bg-info { background: linear-gradient(135deg, #3b82f6, #60a5fa); }

/**
 * ═══ I RIQUADRI DEI TOTALI NEL COLORE DELLA SEZIONE ═══
 *
 * Matteo, il 02/09/2026: «in anagrafica articoli i 4 blocchi devono essere
 * dello stesso colore della categoria ma con gradienti differenti, come fatto
 * per le altre categorie».
 *
 * ⚠️ UNA TINTA SOLA, QUATTRO PROFONDITA'. Il colore lo da' `--section-color`,
 * che il layout imposta in base alla sezione aperta: cosi' i riquadri
 * appartengono alla pagina invece di essere quattro colori presi altrove. Le
 * quattro profondita' si ricavano dallo stesso colore — schiarito o scurito —
 * quindi restano in famiglia qualunque sezione le usi, comprese quelle che
 * non esistono ancora.
 *
 * ⚠️ E IL SIGNIFICATO ADESSO LO PORTA L'ICONA, non piu' il colore. Prima
 * «sotto scorta» era giallo ed «esauriti» rosso: si leggeva la gravita' senza
 * leggere le parole. Adesso no — la gravita' la dicono il triangolo e la croce,
 * e il numero. E' un cambio voluto, non una svista: se un giorno servisse di
 * nuovo il rosso per «esauriti», basta rimettere `bg-danger` su quel riquadro.
 *
 * ⚠️ `color-mix()` non c'e' sui browser vecchi: la riga prima e' il ripiego a
 * tinta piena. Un riquadro senza sfumatura si legge lo stesso; uno senza
 * sfondo, con l'icona bianca su bianco, no.
 */
.stat-icon[class*="tono-"] { background: var(--section-color, #1A4B7C); }
.stat-icon.tono-1 {
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--section-color, #1A4B7C) 100%, #000 0%),
        color-mix(in srgb, var(--section-color, #1A4B7C) 72%, #000 28%));
}
.stat-icon.tono-2 {
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--section-color, #1A4B7C) 88%, #fff 12%),
        color-mix(in srgb, var(--section-color, #1A4B7C) 100%, #fff 0%));
}
.stat-icon.tono-3 {
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--section-color, #1A4B7C) 70%, #fff 30%),
        color-mix(in srgb, var(--section-color, #1A4B7C) 92%, #fff 8%));
}
.stat-icon.tono-4 {
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--section-color, #1A4B7C) 52%, #fff 48%),
        color-mix(in srgb, var(--section-color, #1A4B7C) 78%, #fff 22%));
}
/* ⚠️ Il quarto tono e' chiaro: su quello il bianco non si legge piu'. Il testo
   dell'icona diventa scuro, invece di restare bianco per coerenza e sparire. */
.stat-icon.tono-4 { color: color-mix(in srgb, var(--section-color, #1A4B7C) 82%, #000 18%); }
/* Una riga di colore sul bordo sinistro lega il riquadro alla sezione anche
   quando l'icona e' fuori dallo sguardo. */
.stats-grid .stat-card { border-left: 3px solid var(--section-color, #1A4B7C); }

.stat-content h3 {
    font-size: 1.75rem;
    font-weight: 700;
    margin: 0;
    color: var(--calypso-dark);
}

.stat-content p {
    margin: 0;
    color: #6c757d;
    font-size: 0.85rem;
}

/* ===== TABLES ENHANCED ===== */
.table {
    margin-bottom: 0;
}

/**
 * ⚠️ LE INTESTAZIONI DELLE TABELLE ERANO CENTRATE, IL CONTENUTO NO.
 *
 * Non era voluto: in questa build di bootstrap.min.css manca la riga del
 * Reboot che dice `th { text-align: inherit }`. Senza quella, ogni <th>
 * ricade sul valore predefinito del BROWSER, che per le intestazioni e'
 * `center`. Risultato: su una colonna larga l'etichetta galleggiava in mezzo
 * mentre i dati stavano attaccati a sinistra, e sembrava che la colonna fosse
 * sfasata o che mancasse qualcosa.
 *
 * Vale per tutte le 110 tabelle del gestionale, non solo per quella dove si
 * e' visto.
 *
 * ⚠️ Le utility restano libere di vincere: `.text-end` e `.text-center` di
 * Bootstrap sono `!important`, quindi le colonne dei numeri continuano ad
 * andare a destra come prima.
 */
.table > thead > tr > th,
.table thead th {
    text-align: left;
}

.table thead th {
    background: #f8f9fa;
    border-bottom: 2px solid #e9ecef;
    font-weight: 600;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #495057;
    padding: 0.875rem 1rem;
    white-space: nowrap;
}

.table tbody td {
    padding: 0.875rem 1rem;
    vertical-align: middle;
    border-bottom: 1px solid #f1f3f4;
}

.table tbody tr:hover {
    background-color: rgba(26, 75, 124, 0.02);
}

.table tbody tr:last-child td {
    border-bottom: none;
}

/* ===== BUTTONS ENHANCED ===== */
.btn {
    font-weight: 500;
    border-radius: 0.5rem;
    padding: 0.5rem 1rem;
    transition: all 0.2s;
}

.btn:hover {
    transform: translateY(-1px);
}

/*
 * ⚠️ UN PULSANTE NON VA A CAPO DENTRO SE STESSO.
 *
 * Nella barra dei filtri di Giacenze il pulsante «Filtra» era alto il doppio
 * degli altri due accanto: la colonna e' stretta, e senza questa riga
 * l'etichetta andava a capo sotto la lente d'ingrandimento. Sembrava un
 * pulsante di misura diversa, ma era lo stesso pulsante con dentro due righe.
 * A stare stretti si va a capo con i PULSANTI, non dentro un pulsante.
 */
.btn {
    white-space: nowrap;
}

/*
 * ═══════════════════════════════════════════════════════════════════════════
 * LA FASCIA COLORATA IN TESTA ALLA PAGINA
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * ⚠️ PERCHE' STA QUI E NON IN `_doc_tema.php`.
 *
 * Queste regole vivevano dentro un `<style>` stampato da
 * `templates/_doc_tema.php`, che a sua volta viene incluso da
 * `templates/_intestazione.php`. Funzionava per le pagine che includono la
 * fascia condivisa. Ma ventisette pagine scrivono a mano il loro
 * `<div class="doc-banner">` senza includere ne' l'una ne' l'altro: su quelle
 * la classe esisteva nell'HTML e non esisteva in nessun foglio di stile, e la
 * fascia usciva bianca su fondo bianco. Chi entrava nella scheda di un
 * articolo o di un cliente vedeva sparire la barra del colore della sezione
 * che c'era un attimo prima nell'elenco, e sembrava di essere usciti dal
 * gestionale.
 *
 * Il guaio non era di quelle ventisette pagine: era che il colore della
 * sezione dipendeva dal fatto che ogni pagina si RICORDASSE di includere un
 * file. Un requisito che vale su centosessanta pagine e che nessuno controlla
 * e' un requisito che prima o poi qualcuno non rispetta - ed e' successo
 * ventisette volte.
 *
 * Adesso la fascia sta nel foglio che `layout.php` carica SEMPRE: basta
 * scrivere `class="doc-banner"` e il colore c'e'. Nessuna pagina puo' piu'
 * dimenticarselo, perche' non c'e' piu' niente da ricordare.
 *
 * ⚠️ Il colore non e' scritto qui: e' `var(--section-gradient)`, che
 * `layout.php` riempie con la tinta della sezione della rotta corrente
 * (`ColoriSezione`). Cosi' la fascia e la voce accesa nel menu non possono
 * dire due cose diverse.
 */
.doc-banner {
    background: var(--section-gradient, linear-gradient(135deg, #0D2240, #1A4B7C));
    border-radius: .75rem;
    padding: .75rem 1.25rem;
    margin-bottom: .75rem;
    color: #fff;
    /* ⚠️ La fascia occupa TUTTA la larghezza, anche quando qualcuno la infila
       dentro una riga flex: li' un blocco normale si stringerebbe al suo
       contenuto e il banner uscirebbe come una pastiglia invece che come una
       fascia. */
    width: 100%;
    flex: 1 1 100%;
    box-sizing: border-box;
}

.doc-banner .doc-titolo {
    font-size: 1.05rem;
    font-weight: 600;
}

.doc-banner .doc-cod {
    background: rgba(16, 185, 129, .2);
    padding: .2rem .6rem;
    border-radius: .375rem;
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-size: .85rem;
    color: #6ee7b7;
}

.doc-banner .doc-chip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-size: .72rem;
    font-weight: 600;
    padding: .15rem .55rem;
    border-radius: 2rem;
}

/* La fascia condivisa (`_intestazione.php`): stessa altezza dappertutto. */
.doc-banner .int-riga {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    flex-wrap: wrap;
}

.doc-banner .int-testa {
    display: flex;
    align-items: center;
    gap: .6rem;
    flex-wrap: wrap;
    min-width: 0;
}

.doc-banner .int-chip {
    background: rgba(255, 255, 255, .18);
    color: inherit;
}

.doc-banner .int-azioni {
    display: flex;
    gap: .4rem;
    flex-wrap: wrap;
}

.doc-banner .int-nota {
    margin-top: .3rem;
    font-size: .78rem;
    opacity: .85;
}

.doc-banner-con-tabs {
    margin-bottom: .5rem;
}

/* ⚠️ Le schede stanno FUORI dalla fascia, su fondo chiaro: dentro si
   confondevano coi pulsanti d'azione, e non si capiva quali cambiassero
   pagina e quali facessero qualcosa. */
/* ═══ LE SCHEDE: «SEGMENTATA» (proposta B, Matteo 08/10/2026) ═══
 *
 * Matteo: «in tutto il gestionale mi fa schifo le schede dei tab fatti cosi'»
 * — scelta la B per tutto il gestionale, la C (menu laterale, `.lat-*` qui
 * sotto) per Ditta e App Config.
 *
 * Una barra grigia sola; la scheda scelta e' un tasto bianco «alzato». L'icona
 * sta SOPRA la scritta (la prima `<i>` diventa un blocco), conteggi e
 * pastiglie restano accanto alla scritta.
 *
 * ⚠️ Una riga sola, MAI a capo: troppe schede scorrono di lato (e la scelta
 * viene portata in vista da calypso-responsive.js). Due righe di tasti
 * sembravano una pulsantiera, ed era proprio quello che non piaceva.
 *
 * ⚠️ Le schede di Bootstrap (`.nav-tabs`, `.nav-pills`) hanno la stessa veste:
 * erano mezze pagine con le linguette e mezze coi tasti.
 */
.int-tabs {
    display: flex;
    gap: 3px;
    margin-bottom: .85rem;
    padding: 4px;
    background: #e2e8f0;
    border: 0 !important;
    border-radius: 11px;
    overflow-x: auto;
    flex-wrap: nowrap !important;
    scrollbar-width: thin;
    list-style: none;
}

.nav-tabs,
.nav-pills {
    display: flex;
    flex-wrap: nowrap !important;
    gap: 3px;
    margin-bottom: .85rem;
    padding: 4px;
    background: #e2e8f0;
    border: 0 !important;
    border-radius: 11px;
    overflow-x: auto;
    scrollbar-width: thin;
    list-style: none;
}

.nav-tabs > .nav-item,
.nav-pills > .nav-item {
    flex: 1 0 auto;
    display: flex;
}

.int-tab {
    flex: 1 0 auto;
    display: block;
    width: 100%;
    min-width: 4.6rem;
    margin: 0 !important;
    padding: .38rem .75rem;
    border: 0 !important;
    border-radius: 8px !important;
    background: transparent;
    color: #475569 !important;
    font-size: .8rem;
    font-weight: 500;
    line-height: 1.25;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
}

.nav-tabs .nav-link,
.nav-pills .nav-link {
    flex: 1 0 auto;
    display: block;
    width: 100%;
    min-width: 4.6rem;
    margin: 0 !important;
    padding: .38rem .75rem;
    border: 0 !important;
    border-radius: 8px !important;
    background: transparent;
    color: #475569 !important;
    font-size: .8rem;
    font-weight: 500;
    line-height: 1.25;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
}

.int-tab > i.bi:first-child,
.nav-tabs .nav-link > i.bi:first-child,
.nav-pills .nav-link > i.bi:first-child {
    display: block;
    margin: 0 auto 2px !important;
    font-size: 1.05rem;
    line-height: 1.1;
    color: #64748b;
}

.int-tab:hover,
.nav-tabs .nav-link:hover,
.nav-pills .nav-link:hover {
    background: rgba(255, 255, 255, .6);
    color: #0f172a !important;
}

.int-tab.attivo,
.nav-tabs .nav-link.active,
.nav-pills .nav-link.active {
    background: #fff !important;
    color: #0f172a !important;
    font-weight: 600;
    box-shadow: 0 1px 3px rgba(15, 23, 42, .16);
}

.int-tab.attivo > i.bi:first-child,
.nav-tabs .nav-link.active > i.bi:first-child,
.nav-pills .nav-link.active > i.bi:first-child {
    color: var(--section-color, #2E7DD1);
}

/* ⚠️ Una scheda puo' essere un `<button>` e non un link: succede quando le
   schede non cambiano pagina ma mostrano un pezzo diverso dello stesso modulo
   (le impostazioni di base). Il browser da' ai pulsanti il suo carattere e il
   cursore a freccia: senza queste due righe la stessa scheda si vedeva scritta
   in un font diverso a seconda che portasse altrove o no. */
button.int-tab {
    cursor: pointer;
    font-family: inherit;
}

/* ═══ IL MENU LATERALE: proposta C, solo Ditta e App Config ═══
 *
 * Pagine con tante schede: tutte le voci sempre in vista, divise in gruppi,
 * con un anello che si riempie man mano che la sezione si compila (verde con
 * la spunta quando e' completa).
 *
 *   <div class="lat-lay">
 *     <nav class="lat-nav"> .lat-gruppo + .lat-voce (a | button | span) </nav>
 *     <div class="lat-corpo"> ...il contenuto... </div>
 *   </div>
 */
.lat-lay {
    display: grid;
    grid-template-columns: 228px minmax(0, 1fr);
    gap: .9rem;
    align-items: start;
}

.lat-nav {
    position: sticky;
    top: .75rem;
    padding: .35rem;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: .6rem;
}

.lat-gruppo {
    padding: .55rem .6rem .2rem;
    font-size: .66rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: #94a3b8;
}

.lat-gruppo:first-child { padding-top: .3rem; }

.lat-voce {
    display: flex;
    align-items: center;
    gap: .55rem;
    width: 100%;
    padding: .45rem .6rem;
    border: 0;
    border-radius: .45rem;
    background: none;
    color: #334155;
    font-family: inherit;
    font-size: .83rem;
    line-height: 1.25;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.lat-voce > i.bi:first-child {
    flex-shrink: 0;
    width: 1.1rem;
    font-size: 1rem;
    color: #94a3b8;
}

.lat-voce:hover { background: #f8fafc; color: #0f172a; }

.lat-voce.attivo {
    background: var(--section-soft, #E8F1FA);
    color: #0f172a;
    font-weight: 600;
    box-shadow: inset 3px 0 0 var(--section-color, #2E7DD1);
}

.lat-voce.attivo > i.bi:first-child { color: var(--section-color, #2E7DD1); }

.lat-anello {
    --p: 0;
    --anello: var(--section-color, #2E7DD1);
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 19px;
    height: 19px;
    margin-left: auto;
    border-radius: 50%;
    background: conic-gradient(var(--anello) calc(var(--p) * 1%), #e2e8f0 0);
}

.lat-anello::after {
    content: "";
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #fff;
}

.lat-voce.attivo .lat-anello::after { background: var(--section-soft, #E8F1FA); }
.lat-anello.poco { --anello: #f59e0b; }

.lat-fatto {
    flex-shrink: 0;
    margin-left: auto;
    color: #16a34a;
    font-size: .95rem;
}

.lat-testa {
    margin-bottom: .7rem;
}

.lat-testa .lat-titolo {
    font-size: 1.02rem;
    font-weight: 700;
    color: #0f172a;
}

.lat-testa .lat-sotto {
    font-size: .74rem;
    color: #64748b;
}

.doc-toolbar {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
    margin-bottom: .85rem;
}

@media (max-width: 575.98px) {
    .doc-banner { padding: .65rem .85rem; }
    .doc-banner .doc-titolo { font-size: 1rem; }
    .doc-banner .int-azioni { width: 100%; }
    .doc-banner .int-azioni .btn { flex: 1 1 calc(50% - .4rem); justify-content: center; }
    .doc-toolbar .btn { flex: 1 1 calc(50% - .5rem); justify-content: center; }
}

/*
 * ⚠️ I PULSANTI DENTRO LA FASCIA SONO CHIARI. Tutti.
 *
 * La fascia e' del colore della sezione, e i pulsanti prendono anche loro il
 * colore della sezione: dentro la fascia sparivano. Su «Giacenze» il pulsante
 * «Articoli» era rosa su rosa - c'era, si poteva cliccare, ma non si vedeva.
 *
 * Dentro la fascia il colore della sezione ce l'ha gia' il fondo: i pulsanti
 * fanno il contrario, chiari sopra al colore. Vale per tutte le varianti -
 * pieni, a contorno, di ogni tinta - se no ne resta sempre uno che sparisce.
 */
.doc-banner .btn,
.action-bar .btn,
.print-header-box .btn {
    background: rgba(255, 255, 255, .94);
    border-color: transparent;
    color: var(--section-dark, #0D2240);
    font-weight: 500;
}

.doc-banner .btn:hover,
.doc-banner .btn:focus,
.action-bar .btn:hover,
.action-bar .btn:focus,
.print-header-box .btn:hover,
.print-header-box .btn:focus {
    background: #fff;
    border-color: transparent;
    color: var(--section-dark, #0D2240);
    filter: none;
}

/* ⚠️ Tranne quello che cancella: li' il rosso deve restare leggibile, non
   diventare un pulsante come gli altri. Fondo chiaro, scritta rossa. */
.doc-banner .btn-danger,
.doc-banner .btn-outline-danger,
.action-bar .btn-danger,
.action-bar .btn-outline-danger {
    background: rgba(255, 255, 255, .94);
    color: #b91c1c;
    border-color: transparent;
}

.doc-banner .btn-danger:hover,
.doc-banner .btn-outline-danger:hover,
.action-bar .btn-danger:hover,
.action-bar .btn-outline-danger:hover {
    background: #fff;
    color: #991b1b;
}

/*
 * ⚠️ LA BARRA DEI FILTRI: pulsanti tutti della stessa altezza.
 *
 * Erano alti quanto il loro contenuto, e uno con l'icona e due righe di testo
 * risultava piu' alto degli altri: tre pulsanti affiancati di tre misure.
 */
.filtri-azioni {
    display: flex;
    align-items: stretch;
    gap: .5rem;
    flex-wrap: wrap;
}

.filtri-azioni .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* ⚠️ Alti quanto una casella di testo, non quanto il loro contenuto: un
       pulsante con la sola icona risultava alto la meta' di quello accanto.
       `align-self` non basta - la colonna porta `align-items-end` di Bootstrap,
       che e' !important e vince sullo stiramento. */
    min-height: 40px;
}

/* I piccoli restano piccoli, ma uguali fra loro. */
.filtri-azioni .btn-sm {
    min-height: 31px;
}

/* I pulsanti principali prendono il colore della sezione in cui si e'.
   ⚠️ Prima erano il blu di Calypso ovunque: in Acquisti la fascia era verde
   petrolio e il pulsante «Cerca» accanto restava blu. Le variabili le riempie
   il layout da `ColoriSezione`; se manca (una pagina senza layout) la riserva
   e' il blu di sempre. */
/* ⚠️ I pulsanti sono PIATTI, non sfumati. Con una sfumatura a 135 gradi il
   disegno si adatta alla larghezza del pulsante: «Cerca» e «Invia le
   giacenze», stesso colore, sembravano due tonalita' diverse perche' uno e'
   largo il triplo dell'altro. La fascia in testa alla pagina la sfumatura la
   tiene: li' e' una superficie sola e non c'e' niente accanto con cui
   confrontarla. */
.btn-primary {
    background: var(--section-color, var(--calypso-primary));
    border: none;
    color: var(--section-text, #fff);
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active {
    background: var(--section-color, var(--calypso-primary));
    color: var(--section-text, #fff);
    filter: brightness(1.12);
}

.btn-outline-primary {
    color: var(--section-color, var(--calypso-primary));
    border-color: var(--section-color, var(--calypso-primary));
}

.btn-outline-primary:hover,
.btn-outline-primary:focus,
.btn-outline-primary:active,
.btn-check:checked + .btn-outline-primary {
    background: var(--section-color, var(--calypso-primary));
    border-color: var(--section-color, var(--calypso-primary));
    color: var(--section-text, #fff);
}

/* Le utility del colore di sezione. I valori li riempie il layout. */
.section-bg { background-color: var(--section-color) !important; }
.section-color { color: var(--section-color) !important; }
.section-border { border-color: var(--section-color) !important; }
.section-btn { background-color: var(--section-color) !important; border-color: var(--section-color) !important; color: var(--section-text) !important; }
.section-btn:hover { filter: brightness(0.9); }
.card-header.section-bg { color: var(--section-text); }
.badge.section-bg { color: var(--section-text); }
h1 .bi, h2 .bi, h3 .bi { color: var(--section-color); }
/* ⚠️ Dentro la fascia no: li' il fondo E' il colore della sezione, e un
   pulsante dello stesso colore sparisce. Le regole della fascia vincono. */
.doc-banner .section-btn,
.action-bar .section-btn {
    background-color: rgba(255, 255, 255, .94) !important;
    border-color: transparent !important;
    color: var(--section-dark, #0D2240) !important;
}

/*
 * I CINQUE TONI DELLA SEZIONE.
 *
 * Una pagina non ha un banner solo: c'e' la fascia in testa e sotto le card
 * dei totali. Erano dipinte coi colori di Bootstrap - rosso, giallo, blu,
 * verde - e nella stessa schermata sembravano venire da quattro sezioni
 * diverse. Qui sono cinque toni della STESSA tinta, dal piu' scuro al piu'
 * chiaro: si distinguono fra loro e si vede che sono parenti.
 *
 * ⚠️ I valori li riempie il layout, calcolandoli dal colore della sezione
 * (`ColoriSezione::scala()`), testo bianco o nero incluso: il tono piu' chiaro
 * del magazzino regge il nero, non il bianco. Le riserve qui sotto servono a
 * una pagina aperta senza layout, che altrimenti resterebbe trasparente.
 */
.section-1 { background: var(--section-1, #102F4D) !important; color: var(--section-t1, #fff) !important; }
.section-2 { background: var(--section-2, #16406A) !important; color: var(--section-t2, #fff) !important; }
.section-3 { background: var(--section-3, #1A4B7C) !important; color: var(--section-t3, #fff) !important; }
.section-4 { background: var(--section-4, #46709A) !important; color: var(--section-t4, #fff) !important; }
.section-5 { background: var(--section-5, #7392B7) !important; color: var(--section-t5, #fff) !important; }
.section-grad-1 { background: var(--section-g1, #102F4D) !important; color: var(--section-t1, #fff) !important; }
.section-grad-2 { background: var(--section-g2, #16406A) !important; color: var(--section-t2, #fff) !important; }
.section-grad-3 { background: var(--section-g3, #1A4B7C) !important; color: var(--section-t3, #fff) !important; }
.section-grad-4 { background: var(--section-g4, #46709A) !important; color: var(--section-t4, #fff) !important; }
.section-grad-5 { background: var(--section-g5, #7392B7) !important; color: var(--section-t5, #fff) !important; }
.section-soft { background: var(--section-soft, #eef3f8) !important; }

/*
 * ⚠️ I RIQUADRI DEI TOTALI SONO TUTTI DELLA STESSA ALTEZZA.
 *
 * Erano alti quanto il loro contenuto: quello con una riga sotto il numero
 * («24 ordini in attesa») era piu' alto di quelli senza, e una fila di quattro
 * card di tre altezze diverse sembra un errore di impaginazione. Le colonne di
 * Bootstrap si allungano gia' tutte uguali: bastava dirlo anche alla card
 * dentro, che invece si fermava al suo contenuto.
 */
.row > [class*="col"] > .card[class*="section-"],
.row > [class*="col"] > .card.h-100 {
    height: 100%;
}

/* E un'altezza minima, cosi' una fila di card corte non sembra schiacciata. */
.card[class*="section-"] > .card-body {
    min-height: 4.6rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* ⚠️ Dentro un riquadro colorato il testo lo decide il tono, sempre bianco per
   com'e' fatta la scala: un `text-muted` grigio sopra non si leggerebbe. */
.card[class*="section-"] .text-muted,
.card[class*="section-"] small {
    color: inherit !important;
    opacity: .8;
}
/* ⚠️ Il testo dentro un riquadro di sezione EREDITA il colore del tono, non lo
   sceglie. Un `text-white` fisso sparisce sul tono piu' chiaro del magazzino,
   che vuole il nero. `.section-sub` e' il testo secondario: stesso colore,
   piu' tenue. */
.section-1 .section-sub, .section-2 .section-sub, .section-3 .section-sub,
.section-4 .section-sub, .section-5 .section-sub { color: inherit; opacity: .78; }

/*
 * ⚠️ ANCHE I PULSANTI D'AZIONE SEGUONO LA SEZIONE.
 *
 * In FUMOGENI.IT la fascia e tre pulsanti su quattro erano cremisi, e «Invia le
 * giacenze» restava VERDE: era un `btn-success` di Bootstrap, e il verde non
 * voleva dire niente li' dentro - solo «questo pulsante e' stato scritto in un
 * altro momento».
 *
 * `success`, `info` e `dark` sono tutti pulsanti d'azione: mandare, creare,
 * aggiungere, salvare. Prendono il colore della sezione come il primario.
 *
 * ⚠️ Rosso e giallo NON si toccano. `btn-danger` cancella e `btn-warning`
 * avverte: quelli il colore ce l'hanno per dire una cosa, e vale piu' della
 * simmetria - esattamente come il rosso e il verde dei popup.
 */
.btn-success,
.btn-info,
.btn-dark {
    background: var(--section-color, var(--calypso-primary));
    border-color: transparent;
    color: var(--section-text, #fff);
}

.btn-success:hover, .btn-success:focus, .btn-success:active,
.btn-info:hover, .btn-info:focus, .btn-info:active,
.btn-dark:hover, .btn-dark:focus, .btn-dark:active {
    background: var(--section-color, var(--calypso-primary));
    border-color: transparent;
    color: var(--section-text, #fff);
    filter: brightness(1.12);
}

.btn-outline-success,
.btn-outline-info,
.btn-outline-dark {
    color: var(--section-color, var(--calypso-primary));
    border-color: var(--section-color, var(--calypso-primary));
}

.btn-outline-success:hover, .btn-outline-success:focus, .btn-outline-success:active,
.btn-outline-info:hover, .btn-outline-info:focus, .btn-outline-info:active,
.btn-outline-dark:hover, .btn-outline-dark:focus, .btn-outline-dark:active {
    background: var(--section-color, var(--calypso-primary));
    border-color: var(--section-color, var(--calypso-primary));
    color: var(--section-text, #fff);
}

.btn-calypso {
    background: linear-gradient(135deg, var(--calypso-primary), var(--calypso-accent));
    border: none;
    color: #fff;
}

.btn-calypso:hover {
    background: linear-gradient(135deg, var(--calypso-accent), var(--calypso-primary));
    color: #fff;
}

/* ===== FORM CONTROLS ENHANCED ===== */
.form-control:focus,
.form-select:focus {
    border-color: var(--calypso-primary);
    box-shadow: 0 0 0 0.2rem rgba(26, 75, 124, 0.15);
}

.form-label {
    font-weight: 500;
    color: #495057;
    margin-bottom: 0.375rem;
}

/* ===== BADGES ENHANCED ===== */
.badge {
    font-weight: 500;
    padding: 0.4em 0.7em;
    border-radius: 0.375rem;
}

/* ===== ALERTS ENHANCED ===== */
.alert {
    border: none;
    border-radius: 0.5rem;
    border-left: 4px solid;
}

.alert-success { border-left-color: var(--calypso-success); }
.alert-warning { border-left-color: var(--calypso-warning); }
.alert-danger { border-left-color: var(--calypso-danger); }
.alert-info { border-left-color: var(--calypso-info); }

/* ===== FOOTER ===== */
.app-footer {
    background: #fff;
    border-top: 1px solid rgba(0,0,0,0.05);
    padding: 1rem 1.5rem;
    font-size: 0.85rem;
    color: #6c757d;
}

/* ===== LOGIN PAGE ===== */
.login-page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, var(--calypso-dark) 0%, var(--calypso-primary) 100%);
}

.login-card {
    background: #fff;
    border-radius: 1rem;
    box-shadow: 0 20px 60px rgba(0,0,0,0.3);
    padding: 2.5rem;
    width: 100%;
    max-width: 420px;
}

.login-logo {
    text-align: center;
    margin-bottom: 2rem;
}

.login-logo-icon {
    width: 80px;
    height: 80px;
    background: linear-gradient(135deg, var(--calypso-primary), var(--calypso-accent));
    border-radius: 1.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 1rem;
    font-size: 2rem;
    font-weight: 700;
    color: #fff;
}

.login-title {
    font-size: 1.75rem;
    font-weight: 700;
    color: var(--calypso-dark);
    margin-bottom: 0.25rem;
}

.login-subtitle {
    color: #6c757d;
    font-size: 0.95rem;
}

.login-btn {
    width: 100%;
    padding: 0.75rem;
    font-size: 1rem;
    font-weight: 600;
    background: linear-gradient(135deg, var(--calypso-primary), var(--calypso-accent));
    border: none;
    border-radius: 0.5rem;
    color: #fff;
    cursor: pointer;
    transition: all 0.3s;
}

.login-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(26, 75, 124, 0.4);
}

/* ===== PRINT STYLES ===== */
@media print {
    .sidebar,
    .navbar-top,
    .app-footer,
    .btn,
    .no-print {
        display: none !important;
    }
    
    .app-content {
        margin-left: 0 !important;
    }
    
    .card {
        box-shadow: none !important;
        border: 1px solid #ddd !important;
    }
}

/* ===== UTILITY CLASSES ===== */
.text-calypso { color: var(--calypso-primary) !important; }
.bg-calypso { background-color: var(--calypso-primary) !important; }
.border-calypso { border-color: var(--calypso-primary) !important; }

.cursor-pointer { cursor: pointer; }
.hover-lift:hover { transform: translateY(-2px); }
.transition-all { transition: all 0.2s ease; }

/* Animation */
@keyframes fadeIn {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

.fade-in {
    animation: fadeIn 0.3s ease-out;
}

/* Loading overlay */
.loading-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(255,255,255,0.9);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
}

.loading-spinner {
    width: 50px;
    height: 50px;
    border: 3px solid #f3f3f3;
    border-top: 3px solid var(--calypso-primary);
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* Testo che compare SOLO in stampa: sostituisce a video un controllo (una
   tendina, un pulsante) con il suo valore, cosi' il foglio non stampa una
   select vuota. */
.solo-stampa { display: none; }
@media print {
    .solo-stampa { display: inline !important; }
}

/* ===== CLASSI BOOTSTRAP ASSENTI NEL FOGLIO RIDOTTO =====
   Il bootstrap.min.css di questo progetto e' una versione ridotta: alcune
   classi comunemente usate non ci sono. Una classe assente non da' errore, non
   fa NIENTE - e il difetto si vede solo a video. Qui si definiscono quelle
   effettivamente usate dalle pagine. */

/* Intestazione di tabella su fondo chiaro */
.table-light,
.table-light > th,
.table-light > td,
thead.table-light th {
    background-color: #f8fafc;
    color: #0f172a;
}

/* Gruppo di pulsanti in versione piccola */
.btn-group-sm > .btn {
    padding: 0.25rem 0.5rem;
    font-size: 0.875rem;
    border-radius: 0.25rem;
}

/* ===== TESTATA CLIENTE SUI DOCUMENTI (_doc_cliente_dati.php) =====
   ⚠️ Questo blocco NON usa .row/.col di Bootstrap di proposito. Il partial
   viene incluso dentro schede diverse, e in almeno una finiva dentro una .row
   gia' aperta: le sue .row interne diventavano sorelle delle colonne del form
   invece che contenute in una, Bootstrap le stringeva alla larghezza di una
   colonna sola e le card delle sedi si incolonnavano a un carattere per riga.
   Con una griglia CSS propria il risultato non dipende piu' da chi lo ospita. */
.dc-blocco { width: 100%; flex: 0 0 100%; margin-top: .75rem; }
.dc-blocco > * + * { margin-top: .75rem; }

.dc-chip {
    display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
    background: #f8fafc; border: 1px solid #e2e8f0;
    border-radius: .5rem; padding: .5rem .6rem;
}

/* Le due sedi affiancate, in colonna sul telefono */
.dc-sedi {
    display: grid; gap: .75rem;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

/* Le altre sedi: quante ne stanno, senza mai stringersi sotto il leggibile */
.dc-altre-griglia {
    display: grid; gap: .5rem;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}

/* I dati fiscali riempiono tutta la larghezza disponibile */
.dc-card .card-body > div[style*="grid"] { width: 100%; }

/* ⚠️ Gli importi non devono spezzarsi fra il simbolo e le cifre: nelle colonne
   strette si leggeva "€" su una riga e "16,40" su quella dopo. Vale per tutte
   le celle di importo di tutti i documenti. */
td.text-end, th.text-end,
.nowrap-importo,
.dash-kpi .val {
    white-space: nowrap;
}
/* Le colonne descrizione devono poter andare a capo: sono l'unica cosa che
   deve cedere quando lo spazio manca. */
td.text-end .riga-campo { white-space: normal; }

/* ===== PANNELLO RIGA DOCUMENTO: caselle sempre allineate =====
   ⚠️ I campi si disallineavano perche' le etichette hanno lunghezze diverse:
   "Prezzo di listino *" va su due righe mentre "Sconto" ne occupa una, e il
   campo sotto scende di una riga. Stessa cosa con i testi di aiuto sotto
   ("senza IVA", "listino meno lo sconto"): chi ce l'ha spinge la riga
   successiva piu' in basso. Il risultato e' una scacchiera storta.

   Si risolve riservando lo stesso spazio a tutti: etichetta su due righe
   sempre, testo di aiuto sempre presente anche quando e' vuoto. */
.riga-form .form-label {
    min-height: 2.6em;
    display: flex;
    align-items: flex-end;   /* l'etichetta si appoggia al campo, non galleggia */
    margin-bottom: .25rem;
    line-height: 1.25;
}
/* Lo spazio del testo di aiuto e' riservato anche dove non c'e': cosi' la riga
   sotto parte sempre dalla stessa altezza. */
.riga-form .rf-aiuto {
    display: block;
    min-height: 1.15em;
    font-size: .72rem;
    color: #6c757d;
    margin-top: .15rem;
}
/* Le colonne si allineano in basso: i campi restano sulla stessa linea anche
   se un'etichetta occupa una riga in piu' del previsto. */
.riga-form .row > [class*="col-"] {
    display: flex;
    flex-direction: column;
}
.riga-form .row > [class*="col-"] > .input-group,
.riga-form .row > [class*="col-"] > .form-control,
.riga-form .row > [class*="col-"] > .form-select {
    margin-top: auto;
}

/* ── I campi numerici devono potersi LEGGERE ────────────────────────────
   ⚠️ Un campo numero in un gruppo stretto restava largo 40px: fra il
   margine interno (12px per lato) e le frecce del browser non restava
   posto per una cifra, e non ci si scriveva dentro. Regola per tutto il
   programma: un campo numero in un gruppo non scende mai sotto 4 cifre. */
.input-group > input[type="number"].form-control { min-width: 4.25rem; }

/* I tre sconti di acquisto: niente frecce (rubano meta' del campo), cifra
   al centro, margine interno ridotto. Si scrive il numero e basta. */
.rf-sconti > input[type="number"].form-control {
    min-width: 3.4rem;
    padding-left: .3rem;
    padding-right: .3rem;
    text-align: center !important;
    font-weight: 600;
    -moz-appearance: textfield;
    appearance: textfield;
}
.rf-sconti > input[type="number"]::-webkit-outer-spin-button,
.rf-sconti > input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.rf-sconti > .input-group-text { padding-left: .35rem; padding-right: .35rem; }

/* Per TUTTO il programma: i campi numero e data perdono il margine interno
   largo di Bootstrap (12px per lato), che in un campo stretto si mangiava le
   cifre. Il numero resta leggibile, le frecce restano dove servono. */
input[type="number"].form-control { padding-left: .5rem; padding-right: .3rem; }
input[type="number"].form-control-sm,
.input-group-sm > input[type="number"].form-control { padding-left: .4rem; padding-right: .2rem; }
input[type="date"].form-control,
input[type="time"].form-control,
input[type="datetime-local"].form-control { padding-left: .5rem; padding-right: .35rem; }
input[inputmode="decimal"].form-control-sm { padding-left: .3rem; padding-right: .3rem; }
input[type="date"].form-control-sm { padding-left: .35rem; padding-right: .15rem; }
/* Campi piccoli con la cifra al centro, o con i propri tasti + e - accanto:
   le frecce del browser non servono e coprono il numero. */
input[type="number"].form-control-sm.text-center,
input[type="number"].qty-input,
input[type="number"]#qtyInput {
    -moz-appearance: textfield;
    appearance: textfield;
}
input[type="number"].form-control-sm.text-center::-webkit-inner-spin-button,
input[type="number"].form-control-sm.text-center::-webkit-outer-spin-button,
input[type="number"].qty-input::-webkit-inner-spin-button,
input[type="number"].qty-input::-webkit-outer-spin-button,
input[type="number"]#qtyInput::-webkit-inner-spin-button,
input[type="number"]#qtyInput::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
/* Un numero che non si puo' modificare, e i prezzi del pannello riga (le frecce
   li muoverebbero di un centesimo): senza frecce, tutto lo spazio alla cifra. */
input[type="number"][readonly],
.riga-form input[type="number"][step="0.01"] { -moz-appearance: textfield; appearance: textfield; }
input[type="number"][readonly]::-webkit-inner-spin-button,
input[type="number"][readonly]::-webkit-outer-spin-button,
.riga-form input[type="number"][step="0.01"]::-webkit-inner-spin-button,
.riga-form input[type="number"][step="0.01"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
/* La tendina dell'IVA nel pannello riga: meno margine, cosi' «22 — Iva 22%»
   si legge intero anche quando la colonna e' stretta. */
.riga-form select.rf-iva { font-size: .92rem; padding-left: .45rem; padding-right: 1.5rem; background-position: right .35rem center; }

/* Il menu laterale delle schede sta in fila sopra il contenuto quando lo
   schermo non ha posto per due colonne. */
@media (max-width: 767.98px) {
    .lat-lay { grid-template-columns: 1fr; }
    .lat-nav { position: static; display: flex; gap: 3px; overflow-x: auto; }
    .lat-gruppo { display: none; }
    .lat-voce { width: auto; white-space: nowrap; }
}
