/* Gestionale Handling — stile (coerente col sito) */
:root{--blu:#122f52;--blu-scuro:#0c2038;--arancio:#f2930d;--testo:#232b35;--linea:#e3e8ef;--fondo:#f5f7fa;--ok:#1f8a4c;--ko:#c0392b;--warn:#b9770a}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:"Segoe UI",system-ui,Arial,sans-serif;color:var(--testo);background:var(--fondo);line-height:1.55}
a{color:#1c4c85}
.barra{display:flex;align-items:center;justify-content:space-between;background:#fff;border-bottom:1px solid var(--linea);padding:.6rem 1rem;position:sticky;top:0;z-index:10}
.marchio{display:flex;align-items:center;gap:.5rem;font-weight:800;color:var(--blu);font-size:1.15rem}
.marchio em{color:var(--arancio);font-style:normal}
.marchio small{font-weight:600;color:#6b7686;font-size:.7rem;letter-spacing:2px;text-transform:uppercase}
.utente{display:flex;align-items:center;gap:1rem;font-size:.9rem;color:#46505c}
.contenuto{max-width:960px;margin:0 auto;padding:1.2rem 1rem 3rem}
.pie{text-align:center;color:#9aa4b1;font-size:.82rem;padding:1.5rem}
h1{font-size:1.4rem;color:var(--blu);margin-bottom:.2rem}
h2{font-size:1.1rem;color:var(--blu);margin:1.6rem 0 .6rem}
.card{background:#fff;border:1px solid var(--linea);border-radius:12px;padding:1.2rem;margin-bottom:1rem}
.bottone{display:inline-block;background:var(--arancio);color:var(--blu-scuro);font-weight:700;border:none;border-radius:999px;padding:.7rem 1.4rem;font-size:1rem;cursor:pointer;text-decoration:none}
.bottone:hover{background:#ffb84d}
.bottone.scuro{background:var(--blu);color:#fff}
.bottone.grande{font-size:1.15rem;padding:1rem 2rem;width:100%;max-width:340px}
.timbra{display:flex;gap:1rem;flex-wrap:wrap;justify-content:center;margin:1rem 0}
.esito{text-align:center;min-height:1.4em;font-weight:600;margin-top:.5rem}
input,select,textarea{width:100%;padding:.6rem .8rem;border:1.5px solid #c8d1dd;border-radius:8px;font:inherit;margin-top:.25rem;background:#fff}
label{font-weight:600;font-size:.92rem;display:block;margin-top:.7rem}
table{width:100%;border-collapse:collapse;font-size:.9rem}
th,td{text-align:left;padding:.5rem .6rem;border-bottom:1px solid var(--linea)}
th{color:#6b7686;font-weight:700;font-size:.8rem;text-transform:uppercase}
.tag{display:inline-block;padding:.15rem .55rem;border-radius:999px;font-size:.78rem;font-weight:700}
.tag.ok{background:#e5f5ec;color:var(--ok)}
.tag.ko{background:#fbe8e6;color:var(--ko)}
.tag.warn{background:#fdf0dc;color:var(--warn)}
.griglia{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:.8rem}
.kpi{background:#fff;border:1px solid var(--linea);border-radius:10px;padding:.9rem;text-align:center}
.kpi b{display:block;font-size:1.6rem;color:var(--blu)}
.kpi span{font-size:.8rem;color:#6b7686}
.avviso{background:#fdf0dc;border-left:4px solid var(--arancio);border-radius:0 8px 8px 0;padding:.8rem 1rem;font-size:.9rem;margin:.8rem 0}
.login-wrap{max-width:380px;margin:6vh auto}
.errore{color:var(--ko);font-weight:600;margin-top:.6rem}

/* =====================================================================
   AGGIUNTE DEL 25/07/2026 — modulo contabilità e fatturazione elettronica
   Solo classi NUOVE, usate dalle pagine portate dal gestionale gemello
   (contabilita.php, banca.php, registri-iva.php, fatture.php,
   fattura-xml.php, aruba-fe.php, clienti.php) e dalla barra dei moduli.
   Nessuna regola preesistente è stata modificata: il gestionale è in
   produzione e le pagine di presenze/ferie non devono cambiare aspetto.
   ===================================================================== */

/* --- Barra dei moduli (lib/moduli.php) ------------------------------- */
.moduli{display:flex;flex-wrap:wrap;gap:.2rem;margin:0 0 1.4rem;border-bottom:1px solid var(--linea)}
.moduli a{padding:.6rem .95rem;font-size:.9rem;font-weight:600;color:#6b7686;text-decoration:none;border-bottom:2px solid transparent;white-space:nowrap}
.moduli a:hover{color:var(--blu)}
.moduli a.attivo{color:var(--blu);border-bottom-color:var(--arancio)}

/* --- Barra delle azioni: filtri e pulsanti in linea -------------------
   Le pagine contabili mettono i filtri (mese, centro, stato) in un <form
   class="barra-azioni"> con <label><input>. Senza queste righe gli input
   ereditano width:100% e ogni filtro finisce su una riga sua. */
.barra-azioni{display:flex;gap:.6rem;flex-wrap:wrap;align-items:flex-end;margin:.4rem 0 1rem}
.barra-azioni label{margin-top:0;font-size:.82rem;color:#6b7686;font-weight:600}
.barra-azioni input,.barra-azioni select{width:auto;min-width:8.5rem;margin-top:.15rem;padding:.45rem .6rem}
.barra-azioni .bottone{padding:.5rem 1.1rem;font-size:.92rem}

/* --- Etichette di stato ----------------------------------------------
   Le pagine stampano span class="pill" seguito dal valore dello stato: il
   nome della classe È il valore dell'ENUM del database. Uno stato non
   previsto qui resta grigio neutro, comunque leggibile e mai invisibile. */
.pill{display:inline-block;padding:.2rem .6rem;border-radius:999px;font-size:.78rem;font-weight:700;background:#eef2f7;color:#46505c;white-space:nowrap;margin-top:0}
/* verde: concluso bene, confermato, incassato */
.pill.attivo,.pill.attiva,.pill.ok,.pill.approvata,.pill.consegnata,.pill.accettata_pa,
.pill.pagata,.pill.autorizzata,.pill.verificata,.pill.riconciliato,.pill.fatturata{background:#e5f5ec;color:var(--ok)}
/* rosso: rifiutato, scartato, insoluto, da pagare */
.pill.ko,.pill.errore,.pill.scartata,.pill.rifiutata,.pill.rifiutata_pa,
.pill.insoluta,.pill.da_pagare{background:#fbe8e6;color:var(--ko)}
/* ambra: in attesa di un'azione nostra o di una risposta */
.pill.aperta,.pill.parziale,.pill.in_attesa,.pill.mancata_consegna,.pill.decorsi_termini,
.pill.da_autorizzare,.pill.da_verificare,.pill.da_riconciliare,.pill.scaduta{background:#fdf0dc;color:var(--warn)}
/* blu: documento in viaggio verso lo SdI */
.pill.trasmessa{background:#e7f0fb;color:#1c4c85}
/* grigio esplicito: non ancora emesso, annullato, ignorato */
.pill.bozza,.pill.annullata,.pill.ignorato,.pill.manuale{background:#eef2f7;color:#46505c}

/* --- Tabelle larghe e numeri ------------------------------------------
   I registri IVA e l'estratto conto hanno più colonne di quante ne stiano
   su un telefono: la tabella scorre dentro il suo contenitore, la pagina no. */
.tabella-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.mini{font-size:.82rem;color:#9aa4b1}

/* --- Riga del form fattura (è anche l'aggancio del JS che ricalcola i
       totali e clona la riga: non rinominare la classe) ---------------- */
.riga-fattura{display:flex;gap:.6rem;flex-wrap:wrap;margin-bottom:.7rem;padding-bottom:.5rem;border-bottom:1px solid var(--linea)}
.riga-fattura label{margin-top:0}

/* =====================================================================
   AGGIUNTE DEL 25/07/2026 — nuova interfaccia dell'AREA DIPENDENTE
   (dipendente.php). Impostazione dei prodotti di mercato, riferimento
   "Dipendenti in Cloud": scheda di stato, orologio, pulsante di
   timbratura a tutta larghezza, storico per giorno, ferie in schede.
   Tutte le classi qui sotto sono NUOVE e hanno prefisso .dip- : nessuna
   regola preesistente è stata toccata (il gestionale è in produzione e
   le altre pagine non devono cambiare aspetto).
   Progettato per il telefono con una mano sola: bersagli da almeno 48px,
   testo dei campi 16px (evita lo zoom automatico su iOS), niente
   scorrimenti orizzontali.
   ===================================================================== */

/* --- Saluto ---------------------------------------------------------- */
.dip-hero{display:flex;align-items:center;gap:.85rem;margin:.1rem 0 1rem}
.dip-avatar{flex:0 0 50px;width:50px;height:50px;border-radius:50%;background:var(--blu);color:#fff;
  display:flex;align-items:center;justify-content:center;font-weight:800;font-size:1.15rem;letter-spacing:.5px}
.dip-hero-testo{min-width:0}
.dip-hero .dip-ciao{margin:0;font-size:1.35rem;line-height:1.2}
.dip-commessa{margin:.15rem 0 0;font-size:.9rem;color:#6b7686}
.dip-titolo-card{font-size:1.05rem;color:var(--blu);margin:0 0 .5rem}
.dip-sottotitolo{font-size:1rem;color:var(--blu);margin:1.2rem 0 .6rem}
.dip-sez{margin:1.8rem 0 .7rem}
.dip-sez h2{margin:0}
.dip-nota-testo{color:#6b7686;font-size:.92rem;margin-top:.4rem}
.dip-vuoto{color:#9aa4b1;text-align:center;font-size:.95rem;padding:1.4rem 1rem}

/* --- Scheda di stato: dentro o fuori turno, ultima timbratura, ore oggi */
.dip-stato{border-radius:16px;padding:1rem 1.1rem;margin-bottom:1rem;color:#fff;
  background:linear-gradient(135deg,#1b3f6b 0%,#0c2038 100%);box-shadow:0 8px 20px rgba(12,32,56,.22)}
.dip-stato.dentro{background:linear-gradient(135deg,#1f9d57 0%,#12734a 100%);box-shadow:0 8px 20px rgba(18,115,74,.24)}
.dip-stato.pausa{background:linear-gradient(135deg,#d7850a 0%,#9a5d05 100%);box-shadow:0 8px 20px rgba(154,93,5,.24)}
.dip-stato-testa{display:flex;align-items:center;justify-content:space-between;gap:.6rem;flex-wrap:wrap}
.dip-badge{display:inline-flex;align-items:center;gap:.45rem;background:rgba(255,255,255,.18);
  border-radius:999px;padding:.32rem .85rem;font-weight:700;font-size:.95rem}
.dip-punto{width:9px;height:9px;border-radius:50%;background:#fff}
.dip-stato.dentro .dip-punto,.dip-stato.pausa .dip-punto{animation:dip-battito 2.2s infinite}
@keyframes dip-battito{
  0%{box-shadow:0 0 0 0 rgba(255,255,255,.75)}
  70%{box-shadow:0 0 0 10px rgba(255,255,255,0)}
  100%{box-shadow:0 0 0 0 rgba(255,255,255,0)}}
.dip-stato-data{font-size:.85rem;opacity:.85}
.dip-stato-dati{display:grid;grid-template-columns:repeat(3,1fr);gap:.5rem;margin-top:.9rem}
.dip-stato-dati div{background:rgba(255,255,255,.13);border-radius:12px;padding:.6rem .4rem;text-align:center}
.dip-stato-dati b{display:block;font-size:1.3rem;font-weight:800;line-height:1.2;font-variant-numeric:tabular-nums}
.dip-stato-dati span{display:block;font-size:.7rem;opacity:.88;text-transform:uppercase;letter-spacing:.4px;margin-top:.15rem}
.dip-stato-piede{font-size:.82rem;opacity:.85;margin-top:.7rem}

/* --- Orologio e pulsante di timbratura -------------------------------- */
.dip-timbra-card{text-align:center}
#dip-timbra{scroll-margin-top:calc(var(--hl-h, 64px) + .75rem);scroll-margin-bottom:calc(var(--hl-dock-offset, 0px) + .75rem)}
.dip-orologio{margin:.2rem 0 1rem}
.dip-ora{display:block;font-size:3.2rem;font-weight:800;color:var(--blu);line-height:1;
  letter-spacing:-1.5px;font-variant-numeric:tabular-nums}
.dip-data{display:block;font-size:.9rem;color:#6b7686;margin-top:.35rem}
.dip-btn-timbra{display:block;width:100%;min-height:92px;border:none;border-radius:18px;
  padding:1rem;color:#fff;font:inherit;cursor:pointer;text-align:center;-webkit-tap-highlight-color:transparent;
  transition:transform .08s ease,box-shadow .15s ease,filter .15s ease}
.dip-btn-timbra.entrata{background:linear-gradient(135deg,#22a75e 0%,#157a43 100%);box-shadow:0 10px 22px rgba(21,122,67,.3)}
.dip-btn-timbra.uscita{background:linear-gradient(135deg,#1b3f6b 0%,#0c2038 100%);box-shadow:0 10px 22px rgba(12,32,56,.32)}
.dip-btn-timbra.inizio-pausa{background:linear-gradient(135deg,#f2a323 0%,#b9770a 100%);box-shadow:0 10px 22px rgba(185,119,10,.28)}
.dip-btn-timbra.fine-pausa{background:linear-gradient(135deg,#2c8d76 0%,#176552 100%);box-shadow:0 10px 22px rgba(23,101,82,.28)}
.dip-azioni-timbratura{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.75rem}
.dip-azioni-timbratura.singola{grid-template-columns:1fr}
.dip-btn-timbra:hover{filter:brightness(1.06)}
.dip-btn-timbra:active{transform:translateY(2px);box-shadow:0 4px 12px rgba(12,32,56,.25)}
.dip-btn-timbra:focus-visible{outline:3px solid var(--arancio);outline-offset:3px}
.dip-btn-timbra:disabled{cursor:progress;filter:saturate(.7);animation:dip-attesa 1.2s ease-in-out infinite}
@keyframes dip-attesa{0%,100%{opacity:.7}50%{opacity:1}}
.dip-btn-riga{display:flex;align-items:center;justify-content:center;gap:.6rem}
.dip-btn-icona{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;
  border-radius:50%;background:rgba(255,255,255,.2);font-size:1rem;line-height:1}
.dip-btn-testo{font-size:1.35rem;font-weight:700;letter-spacing:.3px}
.dip-btn-testo b{font-weight:800}
.dip-btn-sotto{display:block;font-size:.83rem;opacity:.9;margin-top:.35rem}

/* --- Riscontro dopo il clic (lo stesso riquadro usato per le ferie).
       Le classi dip-ok / dip-ko / dip-attesa le mette il JS di pagina
       leggendo il testo scritto da timbratura.js: il testo non cambia. --- */
.dip-esito{margin-top:.9rem;border-radius:12px;padding:.75rem .9rem;font-size:.95rem;
  line-height:1.4;text-align:center;background:#eef2f7;color:#46505c;font-weight:600}
.dip-esito:empty{display:none;padding:0;margin:0;min-height:0}
.dip-esito.dip-ok{background:#e5f5ec;color:#136c39}
.dip-esito.dip-ko{background:#fbe8e6;color:var(--ko)}
.dip-esito.dip-attesa{background:#fdf0dc;color:var(--warn)}

/* --- Informativa sulla posizione (quello che la persona legge deve
       corrispondere a quello che il sistema fa davvero) ----------------- */
.dip-avviso-geo{margin-top:1rem;background:#eef4fb;border-radius:12px;padding:.7rem .9rem;
  font-size:.87rem;color:#31445e;text-align:left;line-height:1.5}
.dip-nota{margin-top:.7rem;background:#f7f9fc;border:1px solid var(--linea);border-radius:12px;
  padding:.75rem .9rem;text-align:left}
.dip-nota>summary{cursor:pointer;font-weight:700;font-size:.9rem;color:var(--blu);
  list-style:none;display:flex;align-items:center;justify-content:space-between;gap:.5rem;min-height:24px}
.dip-nota>summary::-webkit-details-marker{display:none}
.dip-nota>summary::after{content:'▾';font-size:.9rem;transition:transform .15s ease}
.dip-nota[open]>summary::after{transform:rotate(180deg)}
.dip-nota ul{margin:.7rem 0 0;padding-left:1.15rem;font-size:.86rem;color:#46505c;line-height:1.5}
.dip-nota li{margin-bottom:.4rem}
.dip-nota p{margin-top:.6rem;font-size:.84rem;color:#6b7686;line-height:1.5}

/* --- Storico raggruppato per giorno ----------------------------------- */
.dip-giorno{padding:0;overflow:hidden}
.dip-giorno-testa{display:flex;align-items:center;justify-content:space-between;gap:.6rem;
  padding:.7rem 1rem;background:#f7f9fc;border-bottom:1px solid var(--linea)}
.dip-giorno-nome{font-weight:700;color:var(--blu);font-size:.95rem}
.dip-giorno-operativo{display:block;color:#6b7686;font-size:.68rem;font-weight:600;letter-spacing:.2px;text-transform:uppercase}
.dip-giorno-ore{font-size:.85rem;color:#46505c;font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
.dip-giorno-ore.approx{color:#6b7686;font-weight:600}
.dip-righe{list-style:none;margin:0;padding:0}
.dip-riga{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;border-bottom:1px solid var(--linea);min-height:60px}
.dip-riga:last-child{border-bottom:none}
.dip-icona{flex:0 0 38px;width:38px;height:38px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;font-size:1.05rem;font-weight:800;line-height:1}
.dip-riga.entrata .dip-icona{background:#e5f5ec;color:var(--ok)}
.dip-riga.uscita .dip-icona{background:#e9edf3;color:var(--blu)}
.dip-riga.inizio-pausa .dip-icona{background:#fdf0dc;color:var(--warn)}
.dip-riga.fine-pausa .dip-icona{background:#e6f4f0;color:#176552}
.dip-riga-testo{flex:1;min-width:0;display:flex;flex-direction:column}
.dip-riga-ora{font-size:1.1rem;font-weight:800;line-height:1.2;font-variant-numeric:tabular-nums}
.dip-riga-tipo{font-size:.8rem;color:#6b7686}
.dip-turno{border-top:1px solid var(--linea)}
.dip-turno:first-of-type{border-top:none}
.dip-turno-meta{display:flex;align-items:center;justify-content:space-between;gap:.6rem;flex-wrap:wrap;
  padding:.55rem 1rem;background:#fbfcfe;color:#6b7686;font-size:.8rem}
.dip-turno-avviso{margin:.65rem 1rem .85rem;background:#fdf0dc;border-radius:9px;padding:.55rem .7rem;
  color:#76500c;font-size:.83rem;line-height:1.45;text-align:left}

/* --- Ferie e permessi ------------------------------------------------- */
.dip-campi{display:flex;gap:.7rem;flex-wrap:wrap}
.dip-campo{flex:1 1 150px;min-width:150px}
.dip-campo label{margin-top:.8rem}
.dip-campo input,.dip-campo select,.dip-campo textarea{font-size:16px;padding:.7rem .8rem;min-height:48px}
.dip-campo-ore.nascosto{display:none}
.dip-btn-invia{display:block;width:100%;min-height:52px;margin-top:1.1rem;background:var(--arancio);
  color:var(--blu-scuro);font:inherit;font-weight:800;font-size:1.02rem;border:none;border-radius:999px;
  padding:.85rem 1.4rem;cursor:pointer;-webkit-tap-highlight-color:transparent}
.dip-btn-invia:hover{background:#ffb84d}
.dip-btn-invia:active{transform:translateY(1px)}
.dip-btn-invia:focus-visible{outline:3px solid var(--blu);outline-offset:2px}
.dip-richieste{list-style:none;margin:0;padding:0;display:grid;gap:.7rem}
.dip-richiesta{margin:0;padding:.9rem 1rem;border-left:4px solid #c8d1dd}
.dip-richiesta.richiesta{border-left-color:var(--warn)}
.dip-richiesta.approvata{border-left-color:var(--ok)}
.dip-richiesta.rifiutata{border-left-color:var(--ko)}
.dip-richiesta-testa{display:flex;align-items:center;justify-content:space-between;gap:.6rem;margin-bottom:.3rem}
.dip-richiesta-tipo{font-weight:800;color:var(--blu);font-size:1rem}
.dip-richiesta-periodo{font-size:.98rem;font-weight:600;font-variant-numeric:tabular-nums}
.dip-richiesta-quanto{display:inline-block;margin-left:.4rem;font-size:.85rem;font-weight:600;color:#6b7686}
.dip-richiesta-nota{margin-top:.45rem;background:#f7f9fc;border-radius:8px;padding:.45rem .65rem;
  font-size:.87rem;color:#46505c;line-height:1.45}
.dip-richiesta-meta{margin-top:.45rem;font-size:.78rem;color:#9aa4b1}

/* --- Telefono --------------------------------------------------------- */
@media (max-width:480px){
  .dip-ora{font-size:2.7rem}
  .dip-stato-dati b{font-size:1.05rem}
  .dip-stato-dati span{font-size:.64rem}
  .dip-btn-testo{font-size:1.2rem}
  .dip-btn-timbra{min-height:88px}
  .dip-hero .dip-ciao{font-size:1.2rem}
  .dip-campo{flex:1 1 100%;min-width:0}
  .dip-giorno-testa{padding:.65rem .85rem}
  .dip-riga{padding:.7rem .85rem;gap:.6rem}
  .dip-azioni-timbratura{gap:.55rem}
  .dip-azioni-timbratura:not(.singola) .dip-btn-timbra{min-height:104px;padding:.75rem .55rem}
  .dip-azioni-timbratura:not(.singola) .dip-btn-riga{gap:.35rem}
  .dip-azioni-timbratura:not(.singola) .dip-btn-icona{width:30px;height:30px}
  .dip-azioni-timbratura:not(.singola) .dip-btn-testo{font-size:1rem}
}

@media (max-width:350px){
  .dip-azioni-timbratura{grid-template-columns:1fr}
  .dip-azioni-timbratura:not(.singola) .dip-btn-timbra{min-height:88px}
}

/* --- Chi ha chiesto meno animazioni ----------------------------------- */
@media (prefers-reduced-motion:reduce){
  .dip-stato.dentro .dip-punto,.dip-stato.pausa .dip-punto,.dip-btn-timbra:disabled{animation:none}
  .dip-btn-timbra,.dip-nota>summary::after{transition:none}
}

/* #####################################################################
   AGGIUNTE DEL 26/07/2026 — TENUTA SUL TELEFONO E COMPONENTI COMUNI
   #####################################################################

   PERCHÉ ESISTE QUESTA PARTE
   Richiesta di Luca Di Matteo del 26/07/2026: «il gestionale deve
   funzionare anche in maniera ottimizzata per i dispositivi mobile, non
   si deve distorcere e non deve creare scroll laterali o spostamenti di
   posizione». Tradotta in quattro condizioni verificabili:
     (1) la pagina non scorre mai di lato, a nessuna larghezza;
     (2) nessun elemento esce dal bordo dello schermo;
     (3) il contenuto non si sposta dopo il caricamento;
     (4) niente testo o comandi troppo piccoli per leggerli o premerli.
   Non è un capriccio estetico: dal 01/08/2026 timbrano 107 lavoratori
   (500 in prospettiva) dal proprio telefono, in capannone, di corsa, a
   volte con i guanti. Il telefono è il dispositivo PRINCIPALE.

   COME È SCRITTA
   Solo regole AGGIUNTE in coda: nessuna riga precedente è stata
   modificata o rinominata. Dove serviva cambiare il comportamento di una
   classe già in produzione (.bottone, .card, .dip-esito) la regola è
   riscritta qui sotto con lo stesso selettore: essendo più in basso nel
   foglio vince a parità di specificità, e chi legge il file dall'alto
   vede prima l'originale e poi la correzione con il motivo.
   Colori: solo le variabili di :root già esistenti. Nessuna grafica
   rifatta da zero — il gestionale è in produzione e deve restare
   riconoscibile.

   CONFINE CON lib/layout.php — DA RISPETTARE
   Sempre il 26/07/2026 `lib/layout.php` è stato rifatto e porta con sé
   un proprio <style> (classi con prefisso `hl-`) stampato nel <head>
   DOPO il <link> a questo foglio. Conseguenza pratica: sugli elementi
   che hanno entrambe le classi — `<header class="barra hl-testa">`,
   `<nav class="utente hl-utente">`, `<a class="marchio hl-marchio">` —
   a parità di specificità vince layout.php, ma un selettore più
   specifico scritto QUI (per esempio `.utente a`, che vale 0,1,1) vince
   su `.hl-esci` (0,1,0) e finisce per ridipingere un comando disegnato
   in un altro file. È già successo e si è corretto.
   REGOLA: la barra superiore la governa lib/layout.php. Qui si scrivono
   solo dimensioni minime e `min-width:0` — mai colori, sfondi o
   riempimenti per `.barra`, `.marchio`, `.utente`.
   ##################################################################### */


/* =====================================================================
   1. FONDAMENTA CONTRO LO SBORDAMENTO — si scrivono una volta e valgono
      ovunque, anche sulle pagine che ancora non esistono.
   ===================================================================== */

/* 1.1 — La pagina non scorre mai di lato.
   `overflow-x:clip` e NON `hidden`: `hidden` crea un contenitore di
   scorrimento e romperebbe `.barra`, che è position:sticky (riga 6);
   `clip` taglia e basta, lo sticky continua a funzionare. I browser che
   non conoscono `clip` (Safari ≤15) ignorano la dichiarazione e si
   comportano come oggi: non si peggiora nulla.
   `-webkit-text-size-adjust:100%` impedisce a iOS di ingrandire da solo
   il testo quando si gira il telefono: è una delle «distorsioni» citate
   nella richiesta, e la si vede solo su iPhone.
   ATTENZIONE A CHI LEGGE: questa è una RETE DI SICUREZZA, non il
   permesso di scrivere markup che sborda. Ciò che esce dal bordo qui
   viene tagliato, cioè diventa irraggiungibile invece che raggiungibile
   scorrendo. La larghezza si governa con .tabella-scroll /
   .tabella-schede (punto 2), non contando su questa riga. */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{max-width:100%;overflow-x:clip;overflow-wrap:break-word}

/* 1.2 — Padding e bordi non allargano mai i riquadri.
   La riga 3 ha già `*{box-sizing:border-box}` ma NON copre gli
   pseudo-elementi, che qui sotto usiamo per le etichette delle tabelle a
   schede e per il calendario in elenco: senza questa riga quelle
   etichette sborderebbero dalla loro cella. */
*::before,*::after{box-sizing:border-box}

/* 1.3 — Immagini, mappe e contenuti incorporati non superano mai lo
   spazio disponibile. Oggi in pagina c'è un solo elemento grafico (il
   marchio in `lib/layout.php`), ma arriveranno loghi cliente, firme,
   allegati e anteprime: la regola serve prima che il problema si
   presenti, non dopo. */
img,svg,video,canvas,iframe,embed,object{max-width:100%}
img,video{height:auto}
/* Eccezione obbligatoria: Leaflet (mappa di presenze.php) dimensiona i
   tasselli da sé e la regola qui sopra li deformerebbe. Leaflet si
   difende già con !important nel proprio foglio; questa riga serve se un
   giorno l'ordine di caricamento cambia o la mappa viene ospitata da noi. */
.leaflet-container img,.leaflet-container svg{max-width:none}

/* 1.4 — Le parole lunghissime vanno a capo invece di allargare la pagina.
   Due livelli, e la differenza è importante:
   · `break-word` (su body, quindi ovunque) spezza una parola SOLO se
     altrimenti uscirebbe dal riquadro. Non riduce la larghezza minima
     dell'elemento, quindi NON stringe le tabelle: una tabella larga
     continua a scorrere dentro .tabella-scroll invece di schiacciare
     dieci colonne in 320 px illeggibili.
   · `anywhere` (mirato) riduce anche la larghezza minima, cioè permette
     davvero all'elemento di stringersi. Lo si usa solo dove il dato è un
     blocco unico senza spazi — email, PEC, codici fiscali, coordinate,
     token, nomi di file — e dove stringere è un guadagno, non un danno.
   Caso reale misurato il 26/07/2026: `postacertificata@pec.handling
   service.it` in index.php usciva di ~26 px dal bordo della sua card a
   320 px. Con `a[href^="mailto:"]` va a capo e rientra, senza toccare
   il markup di nessuna pagina. */
code,.spezza,a[href^="mailto:"],a[href^="tel:"]{overflow-wrap:anywhere}

/* 1.5 — Un elemento flex o grid, per impostazione predefinita, non si
   stringe sotto la larghezza del proprio contenuto (min-width:auto): è
   la causa più frequente e meno evidente di sbordamento. `min-width:0`
   toglie quel pavimento. Applicato ai contenitori che distribuiscono
   spazio, non a tutto, per non alterare layout già collaudati. */
.griglia>*,.cruscotto>*,.impianto>*,.barra-azioni>*{min-width:0}

/* 1.6 — Rete di sicurezza sulle schede bianche.
   `.card` è il contenitore di TUTTI gli elenchi del gestionale. Con
   `overflow-x:auto` una tabella più larga dello schermo scorre DENTRO la
   card: la pagina resta ferma (requisito 1) e nessuna colonna diventa
   irraggiungibile. Misurato il 26/07/2026: hr.php sbordava di +233 px a
   360 px e commesse.php di +122 px, con le tabelle dentro una `.card` e
   fuori da ogni contenitore scorrevole; questa riga li riporta a zero da
   sola, senza modificare quelle pagine.
   Resta comunque un ripiego: la forma giusta è .tabella-scroll (che dà
   anche l'indicazione visiva dello scorrimento) o .tabella-schede. */
.card{overflow-x:auto}


/* =====================================================================
   2. TABELLE — è il punto in cui un gestionale si rompe sul telefono.
      Due strategie, entrambe pronte: la pagina sceglie quale usare.
   ===================================================================== */

/* --- (a) SOLO LA TABELLA SCORRE, MAI LA PAGINA -----------------------
   Uso (classe già esistente dal 25/07/2026, non rinominata):

     <div class="tabella-scroll">
       <table> … </table>
     </div>

   Quando usarla: tabelle da consultare per confronto fra righe (registri
   IVA, estratto conto, cruscotto presenze), dove tenere le colonne
   allineate vale più che vedere tutto insieme.

   Le due aggiunte del 26/07/2026:
   · `overscroll-behavior-x:contain` — senza, quando si arriva in fondo
     allo scorrimento della tabella il gesto prosegue sulla pagina e su
     iOS attiva il «torna indietro» del browser: si perde la pagina
     mentre si legge una tabella. Con `contain` il gesto si ferma lì.
   · Le ombre ai bordi — sono l'«indicazione visibile che si può
     scorrere» chiesta da Luca. Tecnica di sole due coppie di sfumature:
     quelle bianche sono ancorate al contenuto (`local`) e scorrono via
     scoprendo quelle scure, che sono ancorate al riquadro (`scroll`).
     Risultato: l'ombra compare sul lato dove c'è ancora contenuto e
     sparisce quando si è arrivati in fondo. Zero JavaScript, zero
     markup in più. Le barre di scorrimento sul telefono non si vedono:
     senza questo segnale il lettore non sa che la tabella continua. */
.tabella-scroll,.tabella-schede{
  overflow-x:auto;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;
  scrollbar-width:thin;scrollbar-color:#c8d1dd transparent;
  background-color:#fff;
  background-image:
    linear-gradient(to right,#fff 40%,rgba(255,255,255,0)),
    linear-gradient(to left,#fff 40%,rgba(255,255,255,0)),
    linear-gradient(to right,rgba(18,47,82,.20),rgba(18,47,82,0)),
    linear-gradient(to left,rgba(18,47,82,.20),rgba(18,47,82,0));
  background-position:left center,right center,left center,right center;
  background-size:28px 100%,28px 100%,13px 100%,13px 100%;
  background-repeat:no-repeat;
  background-attachment:local,local,scroll,scroll}
.tabella-scroll::-webkit-scrollbar,.tabella-schede::-webkit-scrollbar{height:8px}
.tabella-scroll::-webkit-scrollbar-thumb,.tabella-schede::-webkit-scrollbar-thumb{background:#c8d1dd;border-radius:999px}
/* Riga di servizio da mettere sopra la tabella quando la si vuole dire a
   parole oltre che con l'ombra: <p class="tabella-suggerimento">Scorri
   per vedere tutte le colonne</p>. Sparisce da sola sopra i 700 px,
   dove le colonne ci stanno. */
.tabella-suggerimento{display:none}
@media (max-width:700px){
  .tabella-suggerimento{display:block;font-size:.82rem;color:#6b7686;margin:0 0 .4rem}
  .tabella-suggerimento::before{content:'↔ ';font-weight:700}
}

/* --- (b) IMPILAMENTO A SCHEDE SOTTO I 700 px -------------------------
   Uso: stesso markup, classe diversa, PIÙ un attributo per cella —

     <div class="tabella-schede">
       <table>
         <thead><tr><th>Dipendente</th><th>Ora</th><th>Esito</th><th></th></tr></thead>
         <tbody>
           <tr>
             <td data-etichetta="Dipendente">Mario Rossi</td>
             <td data-etichetta="Ora">08:03</td>
             <td data-etichetta="Esito"><span class="tag ok">ok</span></td>
             <td><button class="bottone compatto">Apri</button></td>
           </tr>
         </tbody>
       </table>
     </div>

   `data-etichetta` è obbligatorio su ogni cella che porta un dato: sotto
   i 700 px l'intestazione della tabella sparisce e quel testo diventa
   l'etichetta stampata accanto al valore. Una cella SENZA
   `data-etichetta` (tipicamente quella dei pulsanti) occupa tutta la
   larghezza della scheda: è voluto, così i comandi restano larghi e
   premibili invece di stare in mezza colonna.
   Sopra i 700 px la classe si comporta esattamente come .tabella-scroll,
   quindi non c'è mai una larghezza in cui la pagina scorre.

   Quando usarla al posto di (a): elenchi che si leggono una riga alla
   volta e da cui si decide qualcosa — richieste ferie, timbrature del
   giorno, anagrafiche. È l'impianto dei prodotti presi a riferimento.

   `thead` non viene nascosto con display:none ma spostato fuori campo:
   così i lettori di schermo continuano a leggere le intestazioni. */
@media (max-width:700px){
  .tabella-schede{overflow-x:visible;background:none}
  .tabella-schede table{display:block;width:100%;font-size:.95rem}
  .tabella-schede thead{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
    overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
  .tabella-schede tbody,.tabella-schede tfoot{display:block}
  .tabella-schede tr{display:block;background:#fff;border:1px solid var(--linea);
    border-radius:12px;margin-bottom:.7rem;overflow:hidden}
  .tabella-schede td,.tabella-schede tbody th{display:grid;
    grid-template-columns:minmax(6rem,38%) minmax(0,1fr);gap:.1rem .8rem;align-items:baseline;
    padding:.55rem .85rem;border-bottom:1px solid var(--linea);text-align:left;
    overflow-wrap:anywhere}
  .tabella-schede tr>:last-child{border-bottom:none}
  .tabella-schede td::before,.tabella-schede tbody th::before{content:attr(data-etichetta);
    color:#6b7686;font-weight:700;font-size:.75rem;text-transform:uppercase;letter-spacing:.2px}
  .tabella-schede td:not([data-etichetta]){display:block;padding:.7rem .85rem;background:#fbfcfe}
  .tabella-schede td:not([data-etichetta])::before{content:none}
  /* In modalità scheda l'allineamento a destra dei numeri non serve più
     (non c'è nessuna colonna con cui allinearsi) e sposterebbe a destra
     anche l'etichetta, che è l'altra parte della griglia. */
  .tabella-schede td.num{text-align:left;white-space:normal}
}


/* =====================================================================
   3. BERSAGLI PREMIBILI — soglia 44 px.
      Le linee guida di accessibilità si fermano a 24 px; qui si sale a
      44 perché il gesto avviene con i guanti da lavoro, in movimento, e
      perché un tocco sbagliato non è mai innocuo (si esce dalla
      sessione, si approva la ferie della persona sbagliata).
   ===================================================================== */

/* `.bottone` restava alto 28 px dove le pagine gli scrivevano addosso un
   `style="padding:.3rem .8rem"` (hr.php, dipendenti.php): l'attributo
   style vince su qualunque selettore, ma NON tocca `min-height`, che
   quindi rialza il bersaglio senza dover ripulire quelle pagine.
   `inline-flex` + `justify-content:center` centra anche l'etichetta di
   `.bottone.grande`, che essendo largo 100% la teneva a sinistra.
   `touch-action:manipulation` toglie l'attesa del doppio tocco: il
   pulsante risponde subito, che è quello che serve a chi timbra di corsa
   (lo zoom con due dita resta possibile: si disattiva solo il doppio
   tocco sul comando). */
.bottone{min-height:44px;display:inline-flex;align-items:center;justify-content:center;
  text-align:center;touch-action:manipulation}
/* Variante compatta LEGITTIMA: serve quando in una riga ci sono due o
   tre comandi. È più stretta e ha il testo più piccolo, ma resta alta
   44 px. Esiste per togliere ogni motivo di scrivere padding a mano
   nell'attributo style. */
.bottone.compatto{padding:.4rem 1rem;font-size:.92rem}
button,summary,label,select{touch-action:manipulation}

/* Caselle di spunta e scelte singole: 13 × 13 px misurati in
   dipendenti.php, una per ciascuno dei 107 dipendenti.
   `min-width`/`min-height` e non `width`/`height`: le pagine scrivono
   `style="width:auto"` per sfuggire alla regola `input{width:100%}`
   della riga 22, e l'attributo style vincerebbe su `width`. Su
   `min-width` non ha voce, quindi la casella diventa comunque 22 px
   senza dover modificare quelle pagine né usare !important. */
input[type=checkbox],input[type=radio]{width:22px;min-width:22px;height:22px;min-height:22px;
  padding:0;margin-top:0;accent-color:var(--blu);flex:0 0 auto;cursor:pointer}
/* Area di tocco piena per una casella: avvolgere casella ed etichetta —
   <label class="spunta-tocco"><input type="checkbox"> Attivo</label> —
   porta il bersaglio a 44 px senza allargare la colonna, perché il
   riempimento sta attorno al testo che c'è già. */
.spunta-tocco{display:inline-flex;align-items:center;gap:.6rem;min-height:44px;
  margin:0;padding:.3rem .5rem;border-radius:8px;font-weight:600;cursor:pointer;
  touch-action:manipulation}
.spunta-tocco:hover{background:#f1f4f9}

/* Utilità per i collegamenti piccoli sparsi nelle pagine («← Cruscotto»,
   «Oggi», «Ieri», «Vedi posizione»: misurati fra 18 e 21 px di altezza).
   Si applica al collegamento — <a class="tocco" href="…">Ieri</a> — e ne
   fa un bersaglio da 44 × 44 px senza cambiarne l'aspetto di testo. */
.tocco{display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;min-width:44px;padding:0 .7rem;border-radius:999px;
  touch-action:manipulation}
.tocco:hover{background:#f1f4f9}

/* «Esci» era 22 × 24 px in cima a OGNI pagina, compresa quella del
   lavoratore: l'unico comando fuori norma sul suo telefono, e sbagliarlo
   significa rifare l'accesso con il turno che comincia.
   Dal 26/07/2026 se ne occupa `lib/layout.php` con `.hl-esci` (44 × 44,
   verificati). Questa riga resta come sola misura minima e NON dichiara
   più sfondo, colore né riempimento: li dichiarava, e siccome
   `.utente a` (0,1,1) batte `.hl-esci` (0,1,0) finiva per ridipingere
   un comando disegnato in un altro file. Una rete di sicurezza deve
   garantire una dimensione, non imporre un aspetto. */
.utente a{display:inline-flex;align-items:center;min-height:44px;touch-action:manipulation}

/* Le voci della barra dei moduli erano già a 44 px per via del
   riempimento: qui il valore diventa esplicito, così resta tale anche se
   un domani si cambia il font o il padding. */
.moduli a{display:inline-flex;align-items:center;min-height:44px}
/* Il pieghevole «Come viene trattata la tua posizione» sulla pagina del
   lavoratore: era 24 px. */
.dip-nota>summary{min-height:44px}

/* --- PAVIMENTO DI 44 px SOLO DOVE SI TOCCA CON IL DITO -----------------
   `pointer:coarse` è vero sui telefoni e sui tablet, falso su un
   computer con mouse o trackpad. La distinzione conta per due motivi:
   · su schermo con mouse un comando da 27 px si preme benissimo, e
     ingrandire tutto rifarebbe l'aspetto di pagine in produzione senza
     che nessuno l'abbia chiesto — rischio inutile;
   · sul telefono lo stesso comando non si prende con il guanto.
   Selettori volutamente GENERICI (`button`, `input`, `select`,
   `textarea`) e non nomi di classi di altre pagine: così valgono anche
   per le sezioni non ancora scritte — turni, area responsabili,
   esportazioni — e nessun foglio di stile va a mettere le mani nel
   nome di classi che appartengono a un altro file.
   Misurato il 26/07/2026 su presenze.php a 360 px: portava a norma i 13
   comandi `.pres-cmd` (27 px), il campo data (39 px) e i due elenchi a
   discesa (35 px) senza toccare quella pagina.
   SPECIFICITÀ, PERCHÉ NON ABBASSA NULLA: `button` e `input` valgono
   (0,0,1), cioè perdono contro qualunque regola scritta per classe. Le
   caselle di spunta restano 22 px (`input[type=checkbox]`, 0,1,1), i
   campi delle ferie restano 48 (`.dip-campo input`, 0,1,1) e il
   pulsante «Timbra» resta 92 (`.dip-btn-timbra`, 0,1,0). Il pavimento
   alza soltanto ciò che nessuno ha ancora alzato.
   Un collegamento SOLO nella sua cella è un comando, non una parola in
   mezzo a una frase: quello si può alzare senza ambiguità. Per i
   collegamenti in mezzo al testo c'è la classe `.tocco` qui sopra, che
   la pagina applica dove serve. */
@media (pointer:coarse){
  button,input,select,textarea{min-height:44px}
  td>a:only-child{display:inline-flex;align-items:center;min-height:44px}
}


/* =====================================================================
   4. COMPONENTI NUOVI — impianto ispirato ai gestionali presi a
      riferimento (barra laterale a gruppi, schede orizzontali, cruscotto
      a riquadri, calendario dei turni). Sono SCHEMI DI NAVIGAZIONE, che
      non sono protetti: nessun foglio di stile, immagine, icona, marchio
      o testo altrui è stato ripreso. I colori sono i nostri, quelli di
      :root alla riga 2.
   ===================================================================== */

/* --- 4.1 SCHEDE ORIZZONTALI ------------------------------------------
   Uso:
     <nav class="schede">
       <a href="?s=generale" class="attiva">Generale</a>
       <a href="?s=presenze">Presenze</a>
       <a href="?s=buste">Buste paga</a>
     </nav>
   Vanno bene sia <a> sia <button> (per le schede gestite da JavaScript).
   La scheda corrente si marca con `attiva` — è accettato anche `attivo`,
   perché è la parola già usata da `.moduli a.attivo`: due nomi per la
   stessa cosa causano bug, meglio riconoscerli entrambi.

   Differenza con `.moduli` (che resta com'è e non va sostituita): la
   barra dei moduli manda le voci a capo perché sono poche e tutte di
   pari importanza; le schede invece NON vanno a capo, scorrono in
   orizzontale dentro se stesse. Motivo: una scheda mezza visibile sul
   bordo destro dice da sola che ce ne sono altre, mentre tre righe di
   schede a capo fanno perdere il senso di «sezioni della stessa
   pagina». `overscroll-behavior-x:contain` impedisce che lo scorrimento
   delle schede trascini la pagina o attivi il «torna indietro». */
.schede{display:flex;gap:.15rem;margin:0 0 1.2rem;border-bottom:1px solid var(--linea);
  overflow-x:auto;overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;
  scroll-snap-type:x proximity;scrollbar-width:none}
.schede::-webkit-scrollbar{display:none}
.schede>a,.schede>button{flex:0 0 auto;scroll-snap-align:start;display:inline-flex;
  align-items:center;min-height:48px;padding:0 1rem;font:inherit;font-size:.92rem;
  font-weight:600;color:#6b7686;background:none;border:none;border-bottom:3px solid transparent;
  text-decoration:none;white-space:nowrap;cursor:pointer;touch-action:manipulation}
.schede>a:hover,.schede>button:hover{color:var(--blu)}
.schede>.attiva,.schede>.attivo{color:var(--blu);border-bottom-color:var(--arancio)}
.schede>a:focus-visible,.schede>button:focus-visible{outline:3px solid var(--arancio);outline-offset:-3px}

/* --- 4.2 CRUSCOTTO A RIQUADRI ----------------------------------------
   Uso:
     <div class="cruscotto">
       <section class="riquadro">
         <div class="riquadro-testa">
           <h3 class="riquadro-titolo">Cose da fare</h3>
           <a class="tocco mini" href="…">Tutte</a>
         </div>
         <ul class="riquadro-lista">
           <li class="riquadro-voce"><span>4 richieste ferie</span><span class="tag warn">da approvare</span></li>
         </ul>
       </section>
     </div>

   `minmax(min(100%,260px),1fr)` invece del solito `minmax(260px,1fr)`:
   quando lo spazio disponibile scende sotto 260 px (telefono stretto
   dentro una card), il `min(100%,…)` fa scendere anche il minimo della
   colonna, altrimenti la griglia resterebbe larga 260 px e sborderebbe.
   È esattamente il caso che la richiesta di Luca vieta. */
.cruscotto{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr));
  gap:1rem;margin:0 0 1.2rem;align-items:start}
.riquadro{background:#fff;border:1px solid var(--linea);border-radius:12px;padding:1rem 1.1rem;
  box-shadow:0 1px 3px rgba(12,32,56,.05);min-width:0}
.riquadro-testa{display:flex;align-items:center;justify-content:space-between;gap:.6rem;
  flex-wrap:wrap;margin-bottom:.6rem}
.riquadro-titolo{font-size:1rem;color:var(--blu);margin:0}
.riquadro-lista{list-style:none;margin:0;padding:0}
.riquadro-voce{display:flex;align-items:center;justify-content:space-between;gap:.7rem;
  flex-wrap:wrap;min-height:44px;padding:.5rem 0;border-bottom:1px solid var(--linea)}
.riquadro-voce:last-child{border-bottom:none}
.riquadro-vuoto{color:#9aa4b1;font-size:.92rem;padding:.8rem 0;text-align:center}

/* --- 4.3 BARRA LATERALE DI NAVIGAZIONE (pagine amministrative) -------
   Uso — si mette DENTRO <main class="contenuto">, quindi non richiede
   alcuna modifica a lib/layout.php:

     <div class="impianto">
       <nav class="laterale">
         <div class="laterale-gruppo">
           <p class="laterale-titolo">Presenze</p>
           <a href="presenze.php" class="attivo">Presenze e ore</a>
           <a href="turni.php">Turni</a>
         </div>
         <div class="laterale-gruppo">
           <p class="laterale-titolo">Azienda</p>
           <a href="commesse.php">Commesse</a>
         </div>
       </nav>
       <div class="impianto-corpo"> …la pagina… </div>
     </div>

   SU TELEFONO DIVENTA UNA BARRA IN BASSO, non un menu apribile. Scelta
   motivata:
   · non richiede JavaScript, quindi funziona anche quando la rete del
     capannone fa cadere uno script — e un menu di navigazione che non si
     apre è una pagina senza uscite;
   · non ha uno stato nascosto: chi la guarda vede dove si trova, mentre
     un menu chiuso costringe a due tocchi solo per sapere che cosa c'è;
   · sta nella metà bassa dello schermo, dove arriva il pollice di una
     mano sola — la stessa ragione per cui il pulsante «Timbra» è grande
     e in basso.
   Limite dichiarato: comode fino a 5 voci; oltre, la barra scorre in
   orizzontale (e le intestazioni di gruppo spariscono, perché in basso
   conta la destinazione, non la famiglia). Se un giorno le voci
   diventassero quindici, la scelta andrà rivista.
   `minmax(0,1fr)` sulla colonna del contenuto: senza, una tabella larga
   allargherebbe la colonna e con essa la pagina. */
.impianto{display:grid;grid-template-columns:minmax(170px,215px) minmax(0,1fr);
  gap:1.4rem;align-items:start}
.impianto-corpo{min-width:0}
.laterale{background:#fff;border:1px solid var(--linea);border-radius:12px;padding:.5rem;
  position:sticky;top:4.6rem}
.laterale-gruppo+.laterale-gruppo{margin-top:.4rem;border-top:1px solid var(--linea);padding-top:.4rem}
.laterale-titolo{font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:1px;
  color:#9aa4b1;margin:0;padding:.6rem .8rem .25rem}
.laterale a{display:flex;align-items:center;gap:.55rem;min-height:44px;padding:.4rem .8rem;
  border-radius:8px;border-left:3px solid transparent;color:#46505c;font-weight:600;
  font-size:.92rem;text-decoration:none;touch-action:manipulation}
.laterale a:hover{background:#f1f4f9;color:var(--blu)}
.laterale a.attivo,.laterale a.attiva{background:#eef4fb;color:var(--blu);border-left-color:var(--arancio)}
.laterale-icona{flex:0 0 auto;font-size:1.05rem;line-height:1}
@media (max-width:820px){
  .impianto{display:block;
    /* spazio in fondo perché la barra fissa non copra mai l'ultima riga
       del contenuto; env(safe-area-inset-bottom) è la fascia della barra
       gesti degli iPhone recenti. */
    padding-bottom:calc(4.6rem + env(safe-area-inset-bottom,0px))}
  .laterale{position:fixed;left:0;right:0;bottom:0;top:auto;z-index:20;
    display:flex;gap:0;padding:0 0 env(safe-area-inset-bottom,0px);
    border:none;border-top:1px solid var(--linea);border-radius:0;
    overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none;
    box-shadow:0 -4px 14px rgba(12,32,56,.10)}
  .laterale::-webkit-scrollbar{display:none}
  .laterale-titolo{display:none}
  /* `display:contents` scioglie il gruppo: le voci diventano figlie
     dirette della barra e si dispongono in fila, senza dover cambiare
     l'HTML fra telefono e scrivania. */
  .laterale-gruppo{display:contents}
  .laterale-gruppo+.laterale-gruppo{margin:0;border:none;padding:0}
  .laterale a{flex:0 0 auto;min-width:5.4rem;flex-direction:column;justify-content:center;
    gap:.15rem;min-height:56px;padding:.45rem .7rem;font-size:.75rem;text-align:center;
    border-left:none;border-top:3px solid transparent;border-radius:0}
  .laterale a.attivo,.laterale a.attiva{background:#f7f9fc;border-top-color:var(--arancio)}
  .laterale-icona{font-size:1.25rem}
}

/* --- 4.4 GRIGLIA CALENDARIO (turni) ----------------------------------
   Uso:
     <div class="calendario">
       <div class="cal-intestazione">Lun</div> … ×7
       <div class="cal-giorno fuori"><span class="cal-numero">28</span></div>
       <div class="cal-giorno oggi" data-giorno="Lun 3 agosto">
         <span class="cal-numero">3</span>
         <div class="cal-turni">
           <span class="cal-turno coperto">06–14 · 12</span>
           <span class="cal-turno scoperto">14–22 · manca 1</span>
         </div>
       </div>
     </div>
     <div class="cal-legenda">
       <span><i class="coperto"></i> turno coperto</span>
       <span><i class="scoperto"></i> personale mancante</span>
       <span><i class="assenza"></i> ferie o permesso</span>
     </div>

   SOTTO I 640 px LA GRIGLIA DIVENTA UN ELENCO PER GIORNI. Perché non si
   tiene la griglia a sette colonne: a 320 px ogni casella sarebbe larga
   ~40 px, cioè né leggibile né premibile, e per starci dentro il testo
   dovrebbe scendere sotto i 10 px — il difetto che questa revisione
   toglie, non che introduce. Un mese di turni sul telefono si legge un
   giorno alla volta, non a colpo d'occhio.
   Per questo `data-giorno` è OBBLIGATORIO su ogni `.cal-giorno` del mese
   corrente: in modalità elenco il solo numero non basterebbe a capire di
   che giorno si parla, e quel testo diventa l'intestazione della riga.
   I giorni dell'altro mese (`fuori`) spariscono: servono solo a
   quadrare la griglia. */
.calendario{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:.3rem;margin:.6rem 0 1rem}
.cal-intestazione{font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.3px;
  color:#6b7686;text-align:center;padding:.3rem 0}
.cal-giorno{display:flex;flex-direction:column;gap:.25rem;min-width:0;min-height:68px;
  background:#fff;border:1px solid var(--linea);border-radius:8px;padding:.35rem}
.cal-giorno.fuori{background:#fafbfd;opacity:.55}
.cal-giorno.oggi{border-color:var(--arancio);box-shadow:inset 0 0 0 1px var(--arancio)}
.cal-numero{font-size:.82rem;font-weight:700;color:var(--blu);font-variant-numeric:tabular-nums}
.cal-turni{display:flex;flex-direction:column;gap:.2rem;min-width:0}
.cal-turno{display:block;font-size:.75rem;font-weight:600;line-height:1.3;padding:.15rem .35rem;
  border-radius:5px;background:#eef2f7;color:#46505c;overflow-wrap:anywhere}
.cal-turno.coperto{background:#e5f5ec;color:var(--ok)}
.cal-turno.scoperto{background:#fbe8e6;color:var(--ko)}
.cal-turno.assenza{background:#fdf0dc;color:var(--warn)}
.cal-legenda{display:flex;flex-wrap:wrap;gap:.45rem .95rem;font-size:.85rem;color:#46505c;margin:0 0 1rem}
.cal-legenda span{display:inline-flex;align-items:center;gap:.4rem}
.cal-legenda i{width:13px;height:13px;border-radius:4px;background:#eef2f7;flex:0 0 auto}
.cal-legenda i.coperto{background:#e5f5ec;box-shadow:inset 0 0 0 1px var(--ok)}
.cal-legenda i.scoperto{background:#fbe8e6;box-shadow:inset 0 0 0 1px var(--ko)}
.cal-legenda i.assenza{background:#fdf0dc;box-shadow:inset 0 0 0 1px var(--warn)}
@media (max-width:640px){
  .calendario{display:block;margin-top:.4rem}
  .cal-intestazione{display:none}
  .cal-giorno{flex-direction:row;flex-wrap:wrap;align-items:flex-start;gap:.2rem .8rem;
    min-height:52px;margin-bottom:.4rem;padding:.6rem .8rem;border-radius:10px}
  .cal-giorno::before{content:attr(data-giorno);flex:0 0 6.2rem;font-weight:700;
    color:var(--blu);font-size:.88rem}
  .cal-giorno.oggi::after{content:'oggi';font-size:.72rem;font-weight:700;color:var(--arancio);
    text-transform:uppercase;letter-spacing:.5px}
  .cal-numero{display:none}
  .cal-turni{flex:1 1 100%;margin-left:6.2rem}
  .cal-turno{padding:.3rem .5rem;font-size:.85rem}
  .cal-giorno.fuori{display:none}
}

/* --- 4.5 ELENCO DESCRITTIVO etichetta / valore ------------------------
   Per le schede di dettaglio (anagrafica del dipendente, scheda della
   commessa, testata di una fattura). Uso:
     <dl class="dettagli">
       <dt>Codice fiscale</dt><dd>RSSMRA80A01F205X</dd>
       <dt>Commessa</dt><dd>Truccazzano — Cosmetica</dd>
     </dl>
   Due colonne dove c'è spazio, una sola sotto i 520 px: sul telefono
   l'etichetta sopra e il valore sotto si leggono meglio di due colonne
   strette, e i valori lunghi (email, IBAN, codici) hanno tutta la
   larghezza. `minmax(0,1fr)` sulla colonna dei valori per lo stesso
   motivo del punto 4.3. */
.dettagli{display:grid;grid-template-columns:minmax(7rem,13rem) minmax(0,1fr);
  gap:0 .9rem;margin:.3rem 0}
.dettagli dt{font-size:.78rem;font-weight:700;text-transform:uppercase;letter-spacing:.2px;
  color:#6b7686;padding:.5rem 0;border-bottom:1px solid var(--linea);align-self:stretch;
  display:flex;align-items:center}
.dettagli dd{margin:0;padding:.5rem 0;min-width:0;border-bottom:1px solid var(--linea)}
.dettagli dt:last-of-type,.dettagli dd:last-of-type{border-bottom:none}
@media (max-width:520px){
  .dettagli{grid-template-columns:minmax(0,1fr)}
  .dettagli dt{padding:.6rem 0 0;border-bottom:none}
  .dettagli dd{padding:.05rem 0 .6rem;font-weight:600;border-bottom:1px solid var(--linea)}
  .dettagli dd:last-of-type{border-bottom:none}
}


/* =====================================================================
   5. NESSUNO SPOSTAMENTO DI POSIZIONE — lo spazio si riserva PRIMA che
      il contenuto arrivi. È il requisito (3) della richiesta.
   ===================================================================== */

/* 5.1 — Il riquadro di esito della timbratura.
   Difetto di partenza, misurato il 26/07/2026: `.dip-esito:empty{
   display:none}` (riga 169) teneva il riquadro fuori dal flusso finché
   era vuoto; appena timbratura.js ci scriveva dentro, tutto ciò che
   stava sotto scendeva di 60 px, e fino a 230 px con il messaggio
   «TIMBRATURA NON REGISTRATA» — cioè proprio quello che il lavoratore
   deve leggere. È il gesto che si ripete 214 volte al giorno.

   PRINCIPIO: perché non ci sia spostamento, il riquadro deve avere la
   STESSA altezza da vuoto e da pieno. Una sola misura riservata, valida
   in ogni stato — non una che cresce al tocco: far comparire spazio
   vuoto quando ancora non c'è nessun messaggio è uno spostamento come
   gli altri, solo più difficile da spiegare.

   QUANTO RISERVARE — altezza reale dei messaggi di timbratura.js,
   misurata nel browser il 26/07/2026 sulla pagina vera:
       messaggio                                  320 px   360 px
       «Rilevo la posizione…» / «Invio…»            45       45
       «✅ Entrata registrata alle 08:03 — 📍 …»     67       67
       …stesso, con «± 12 m» di precisione         109       88
       …stesso, con «⚠️ FUORI dal luogo di lavoro» 109       88
   7rem = 112 px coprono TUTTO il percorso normale fino a 320 px:
   attesa, invio ed esito della timbratura riuscita non muovono un
   pixel. Restano fuori solo i messaggi di guasto (rifiuto del server
   194 px, rete caduta 216 px): lì il riquadro cresce verso il basso una
   volta sola, con il bordo superiore e il pulsante fermi — si allunga
   il messaggio, non si sposta ciò che si sta leggendo. Accorciare quei
   due testi in assets/timbratura.js li riporterebbe dentro i 112 px:
   è l'unica correzione rimasta, e non è CSS.
   Da vuoto il riquadro è trasparente e senza riempimento: si legge come
   aria fra il pulsante e l'informativa, non come un riquadro grigio.

   PERCHÉ `min-height` È RIPETUTO ANCHE NELLA REGOLA `:empty` — verificato
   il 26/07/2026, ed è la correzione di un difetto vero, non una ripetizione
   per sicurezza. Alla riga 169 vive ancora `.dip-esito:empty{…min-height:0}`
   della stesura del 25/07/2026. Quel selettore vale (0,2,0) — una classe più
   una pseudo-classe — mentre `.dip-esito` qui sotto vale (0,1,0): la
   specificità più alta vince a prescindere dall'ordine, quindi da VUOTO il
   riquadro tornava a `min-height:0` e non riservava niente.
   Misurato prima della correzione, a 320 px, sul riquadro delle ferie:
   vuoto 0 px → «Invio…» 67 px → «✅ Richiesta inviata» 88 px, cioè uno
   spostamento di +67 e poi +88 px proprio nel modulo con cui si chiedono
   ferie e permessi. Il riquadro della timbratura non era colpito perché
   `.dip-btn-timbra ~ .dip-esito` (0,2,0, più in basso) vinceva comunque.
   Ripetendo la dichiarazione QUI, a parità di specificità (0,2,0) e più in
   basso nel foglio, questa regola batte quella della riga 169 e lo spazio
   resta riservato anche a riquadro vuoto. */
.dip-esito{min-height:4.2rem}
.dip-esito:empty{display:block;min-height:4.2rem;padding:0;margin-top:.9rem;
  background:transparent;box-shadow:none}
/* Solo il riquadro della timbratura riserva 7rem, ed è selezionato per
   quello che è — il fratello che segue il pulsante di timbratura — non
   per il suo id. Gli altri due riquadri con la stessa classe
   (`esito-ferie`, `esito-assenza`) mostrano messaggi di una o due righe
   («Invio…», «✅ Richiesta inviata», «⚠️ Scegli un motivo dall'elenco»):
   i 4,2rem qui sopra bastano, e riservarne 7 lascerebbe un vuoto in
   fondo a due moduli senza guadagnare nulla. */
.dip-btn-timbra ~ .dip-esito{min-height:7rem}

/* 5.1-bis — Lo STESSO difetto sui riquadri `.esito` "nudi", cioè quelli senza
   `.dip-esito`: sono i riscontri in fondo ai moduli di commesse.php
   («Salva commessa») e dipendenti.php («Crea dipendente»), l'ultimo elemento
   del <form>, quindi tutto ciò che segue nella pagina — l'elenco delle
   commesse, l'elenco dei 107 dipendenti — scorre giù quando compare il
   messaggio. La riga 21 riserva `1.4em`, cioè UNA riga di testo: basta su
   schermo largo, non su un telefono, dove lo stesso messaggio ne occupa tre.
   Misurato il 26/07/2026 con «⚠️ Non è stato possibile salvare: controlla i
   campi obbligatori e riprova.»:
       larghezza   riquadro vuoto   riquadro pieno   spostamento
         320 px         22 px            74 px          +52 px
        1280 px         22 px            25 px           +2 px
   PERCHÉ SOLO SOTTO I 700 px: su schermo largo lo spostamento è di 2 px e
   riservare spazio lascerebbe un vuoto in fondo a due moduli in produzione
   senza che nessuno l'abbia chiesto. Il difetto è del telefono, la
   correzione sta dov'è il difetto.
   PERCHÉ 4,2rem E NON 74 px: è la stessa misura già riservata dai riquadri
   della pagina del lavoratore — un valore solo, non tre da tenere allineati.
   Copre il messaggio di due righe e riduce il residuo da 52 px a 7 px nel
   caso peggiore delle tre righe.
   `:not(.dip-esito)` NON è prudenza: senza, questa regola (0,1,0) starebbe
   più in basso di `.dip-esito` (0,1,0) e vincerebbe per ordine, mettendo le
   mani sui riquadri della timbratura che il punto 5.1 ha appena sistemato.
   Escludendoli, i due impianti restano indipendenti. */
@media (max-width:700px){
  .esito:not(.dip-esito){min-height:4.2rem}
}

/* 5.2 — Segnaposto per ciò che arriva dopo (mappa, elenchi caricati da
   JavaScript, anteprime di documenti). Si stampa al posto del contenuto
   e occupa da subito l'altezza che quel contenuto avrà:
     <div class="segnaposto mappa">Carico la mappa…</div>
   REGOLA PER CHI SCRIVE LE PAGINE: se il contenuto non arriva (CDN
   irraggiungibile, errore di rete), NON si nasconde il riquadro — si
   sostituisce il testo dentro al riquadro, che resta della stessa
   altezza. Nasconderlo fa risalire di colpo tutta la pagina, che è
   esattamente ciò che Luca ha chiesto di evitare; ed è il caso più
   probabile su rete mobile, non il caso raro. */
.segnaposto{display:flex;align-items:center;justify-content:center;text-align:center;
  min-height:8rem;padding:1rem;border-radius:12px;color:#6b7686;font-size:.9rem;
  background-color:#eef2f7;
  background-image:linear-gradient(100deg,rgba(255,255,255,0) 35%,rgba(255,255,255,.7) 50%,rgba(255,255,255,0) 65%);
  background-size:220% 100%;background-repeat:no-repeat;
  animation:scorre-segnaposto 1.5s linear infinite}
.segnaposto.mappa{min-height:380px}
@keyframes scorre-segnaposto{from{background-position:130% 0}to{background-position:-30% 0}}
@media (prefers-reduced-motion:reduce){.segnaposto{animation:none}}


/* =====================================================================
   6. RIFINITURE SU CLASSI GIÀ IN PRODUZIONE
      Nessuna rinominata: stesso selettore, valore corretto, motivo
      scritto. Chi cerca `.card` o `.barra` trova prima l'originale in
      alto e poi questa correzione.
   ===================================================================== */

/* 6.1 — LA BARRA IN CIMA NON È PIÙ GOVERNATA DA QUESTO FILE.
   Il 26/07/2026 `lib/layout.php` è stato rifatto e stampa la barra come
   `<header class="barra hl-testa">`: le classi `hl-` vivono in un
   <style> dentro il <head>, DOPO il <link> a questo foglio, quindi a
   parità di specificità vincono loro. Là la barra ha altezza fissa
   (56/60 px), `flex-wrap:nowrap` e il nome utente troncato con i
   puntini — che risolve, in modo migliore, lo stesso difetto misurato
   qui (a 320 px il nome andava a capo e la barra passava da 55 a 77 px).

   QUI RESTANO SOLO DUE RIGHE, e sono reti di sicurezza, non stile:
   `min-width:0` permette ai due blocchi flessibili di stringersi invece
   di spingere fuori la pagina. Vale anche se un domani la barra venisse
   ridisegnata: è la proprietà che impedisce lo sbordo, non un colore.
   NON si scrivono qui sfondi, colori, riempimenti o `flex-wrap` per
   `.barra`, `.marchio` o `.utente`: sarebbero dichiarazioni che si
   scavalcano fra due file, e chi legge l'uno non vedrebbe l'altro. */
.marchio{min-width:0}
.utente{min-width:0}

/* 6.2 — Le etichette della scheda di stato del lavoratore («ULTIMA
   USCITA», «ORE OGGI», «TIMBRATURE OGGI») erano a 10,24 px su telefono:
   il testo più piccolo dell'intera pagina si trovava sulla scheda che
   dice se si risulta dentro o fuori turno, cioè la prima cosa che si
   guarda. Fondo fissato a 12 px (.75rem). Lo spazio non si recupera
   rimpicciolendo ma mandando il terzo dato a capo: sotto i 380 px la
   griglia passa da tre colonne fisse a colonne che si adattano. */
.dip-stato-dati span{font-size:.75rem}
@media (max-width:480px){
  .dip-stato-dati span{font-size:.75rem}
  .dip-stato-dati b{font-size:1.15rem}
}
@media (max-width:380px){
  .dip-stato-dati{grid-template-columns:repeat(auto-fit,minmax(96px,1fr))}
}

/* 6.3 — Varianti dell'avviso. `.avviso` da solo resta ambra come oggi
   (nessuna pagina cambia aspetto): questi sono modificatori nuovi, per
   quando il messaggio è una conferma o un errore e il colore deve dirlo
   prima delle parole. */
.avviso.ok{background:#e5f5ec;border-left-color:var(--ok)}
.avviso.ko{background:#fbe8e6;border-left-color:var(--ko)}
.avviso.info{background:#eef4fb;border-left-color:#1c4c85}

/* 6.4 — Il modulo dei filtri: i campi si stringono fino a 8,5rem, che a
   320 px sono 136 px contro i ~250 disponibili. Sotto i 480 px un campo
   per riga si compila meglio di due mezzi campi affiancati, e un
   <input type="date"> italiano (gg/mm/aaaa più l'icona) chiede da solo
   circa 140 px. */
@media (max-width:480px){
  .barra-azioni{gap:.5rem}
  .barra-azioni input,.barra-azioni select{width:100%;min-width:0}
  .barra-azioni label{width:100%}
  .barra-azioni .bottone{width:100%}
}

/* 6.5 — Il contorno del focus da tastiera deve restare visibile su tutti
   i comandi, non solo su quelli della pagina del lavoratore: è l'unico
   modo di usare il gestionale senza mouse, e serve anche a chi lavora
   dallo scanner o da un terminale in magazzino.
   QUI NON SI SCRIVE `border-radius`, ed è una correzione, non una
   dimenticanza: la prima stesura di questa regola ne aveva uno da 6px e
   il 26/07/2026 si è misurato che cambiava la FORMA dei comandi appena
   ricevevano il fuoco — il pulsante «Timbra» passava da 18px a 6px di
   raggio e ogni `.bottone` a pillola da 999px a 6px. Cioè proprio la
   «distorsione» che questo lavoro deve togliere, introdotta dalla regola
   che doveva aiutare. Il contorno segue da sé il raggio dell'elemento:
   non serve dichiararlo, serve non dichiararlo. */
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,
textarea:focus-visible,summary:focus-visible,.bottone:focus-visible{
  outline:3px solid var(--arancio);outline-offset:2px}
