
        :root {
            /* Design System — Dandelion 3.0 Premium */
            --dan-primary: #095373;
            --dan-accent: #F2602A;
            --dan-dark: #081825;
            --dan-beige: #E2D6D5;
            --dan-bg: #F7F5F3;
            --dan-card: #FFFFFF;
            --dan-text: #1A202C;
            --dan-success: #2D8659;
            --dan-danger: #C53030;
            --dan-warning: #D97706;
            --dan-muted: #9CA3AF;
            --dan-border: #E8E4E0;
            /* Legacy aliases */
            --dan-navy: var(--dan-primary);
            --dan-navy-dark: var(--dan-dark);
            --dan-gold: var(--dan-accent);
            --dan-secondary: #4A90A4;
            --dan-light: var(--dan-bg);
            /* Layered shadows */
            --shadow-sm: 0 0 0 1px rgba(0,0,0,0.03), 0 1px 2px rgba(0,0,0,0.04), 0 4px 16px rgba(0,0,0,0.06);
            --shadow-md: 0 0 0 1px rgba(0,0,0,0.03), 0 2px 4px rgba(0,0,0,0.06), 0 8px 24px rgba(0,0,0,0.1);
            --shadow-lg: 0 0 0 1px rgba(0,0,0,0.03), 0 4px 8px rgba(0,0,0,0.08), 0 16px 48px rgba(0,0,0,0.12);
            --shadow-accent: 0 2px 8px rgba(242,96,42,0.35);
            --shadow-accent-hover: 0 4px 16px rgba(242,96,42,0.45);
        }

        /* === GLOBAL RESET & BASE === */
        * { -webkit-tap-highlight-color: transparent; box-sizing: border-box; }
        html { scroll-behavior: smooth; }
        body { font-family: 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif; background-color: var(--dan-bg); user-select: none; color: var(--dan-text); font-weight: 400; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
        a, button, input, select, .btn, .form-control, .form-select { transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); }
        h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { font-family: 'Roboto', sans-serif; font-weight: 700; color: var(--dan-dark); }
        .brand-title { font-family: 'Noto Serif', serif; font-weight: 800; letter-spacing: 2px; color: #ffffff; }
        .brand-accent { color: var(--dan-accent); font-weight: 700; font-family: 'Roboto', sans-serif; letter-spacing: 3px; }

        /* === DISPLAY TYPOGRAPHY — Noto Serif for hero numbers === */
        .display-num { font-family: 'Noto Serif', serif; font-weight: 700; color: var(--dan-dark); }
        .display-label { font-family: 'Roboto', sans-serif; font-weight: 400; font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.5px; color: var(--dan-muted); }

        /* === SCROLLBAR CUSTOM (desktop) === */
        ::-webkit-scrollbar { width: 6px; height: 6px; }
        ::-webkit-scrollbar-track { background: transparent; }
        ::-webkit-scrollbar-thumb { background: var(--dan-beige); border-radius: 3px; }
        ::-webkit-scrollbar-thumb:hover { background: var(--dan-primary); }

        /* === COLOR UTILITIES === */
        .bg-primary { background-color: var(--dan-primary) !important; color: white !important; }
        .text-primary { color: var(--dan-primary) !important; }
        .border-primary { border-color: var(--dan-primary) !important; }
        .bg-dark { background-color: var(--dan-dark) !important; }

        /* === BUTTONS — Three tiers === */
        .btn { border-radius: 10px; font-weight: 600; transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); letter-spacing: 0.3px; border: none; }
        .btn:active { transform: scale(0.97); }

        /* Tier 1: CTA / Accent */
        .btn-accent { background: linear-gradient(135deg, #F2602A 0%, #e0521d 100%); color: white !important; font-weight: 700; border: none; box-shadow: var(--shadow-accent); }
        .btn-accent:hover { transform: translateY(-1px); box-shadow: var(--shadow-accent-hover); background: linear-gradient(135deg, #F2602A 0%, #d44a18 100%); color: white !important; }

        /* Tier 2: Primary */
        .btn-primary { background-color: var(--dan-primary) !important; border-color: var(--dan-primary) !important; color: white !important; border-radius: 10px; }
        .btn-primary:hover { background-color: var(--dan-dark) !important; border-color: var(--dan-dark) !important; transform: translateY(-1px); box-shadow: 0 4px 12px rgba(9,83,115,0.3); }

        /* Tier 3: Ghost */
        .btn-ghost { background: transparent; color: var(--dan-primary); font-weight: 600; border: 1.5px solid var(--dan-beige); border-radius: 10px; }
        .btn-ghost:hover { border-color: var(--dan-primary); background: rgba(9,83,115,0.04); }
        .btn-outline-primary { color: var(--dan-primary) !important; border: 1.5px solid var(--dan-beige) !important; font-weight: 600; border-radius: 10px; }
        .btn-outline-primary:hover { background-color: var(--dan-primary) !important; color: white !important; border-color: var(--dan-primary) !important; }

        /* === NAVBAR — Minimal, breathing === */
        /* La barra in alto e' appiccicata: la colonna laterale parte da 56px e
           senza questo, scorrendo, restava scoperta una fessura in cima da cui
           passava il contenuto. */
        .navbar { height: 56px; border-bottom: 1px solid var(--dan-accent); background-color: var(--dan-dark) !important; backdrop-filter: blur(10px); padding: 0 16px; position: sticky; top: 0; z-index: 1040; }
        .navbar .navbar-brand img { height: 28px; }

        /* Avatar initials */
        .avatar-circle { width: 32px; height: 32px; border-radius: 50%; background: linear-gradient(135deg, var(--dan-primary), var(--dan-secondary)); color: white; display: inline-flex; align-items: center; justify-content: center; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.5px; flex-shrink: 0; }

        .nav-pills .nav-link { border-radius: 10px; font-weight: 500; transition: all 0.25s; }
        .nav-pills .nav-link.active { background-color: var(--dan-primary) !important; color: white !important; font-weight: 700; box-shadow: 0 2px 8px rgba(9,83,115,0.25); }

        /* === CARDS — Layered shadows, no borders === */
        .card { border: none; box-shadow: var(--shadow-sm); border-radius: 16px; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); background: var(--dan-card); }
        .card:hover { box-shadow: var(--shadow-md); }
        /* LA SCHEDA DELL'APP (spostata qui il 14/8/26).
           Stava nel <style> di user.html e valeva soltanto li'. Tredici altri
           template la usavano — i_miei_dati, tutte le privacy_*, admin_backup,
           admin_compliance, admin_trustworthiness_register,
           admin_archivio_richieste — per cinquantasei elementi che non
           ricevevano nessuno stile: div con il solo padding di Bootstrap,
           appoggiati al colore della pagina. Non erano schede brutte: la
           scheda non c'era.
           Le dichiarazioni sono quelle di prima, non una di piu': e' uno
           spostamento, e user.html deve restare identico. Il padding cede
           alle utility di Bootstrap (`p-3`, `p-4`) perche' quelle portano
           `!important`, ed e' giusto cosi': la scheda da' carta e ombra, la
           pagina decide quanto respiro. */
        .dan-card {
            background: var(--dan-card); border-radius: 16px;
            box-shadow: var(--shadow-sm); padding: 24px;
            margin-bottom: 20px; border: none;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        }
        .card-header { font-weight: 700; letter-spacing: 0.3px; border-bottom: 1px solid var(--dan-border); background: transparent; }
        .card-body { padding: 24px; }

        /* === FORMS — Minimal, premium === */
        .form-control, .form-select { border: 1.5px solid var(--dan-beige); border-radius: 10px; padding: 12px 16px; font-size: 15px; font-weight: 500; background-color: #FAFAF8; transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); }
        .form-control:focus, .form-select:focus { border-color: var(--dan-primary); box-shadow: 0 0 0 3px rgba(9,83,115,0.1); background: white; }
        .badge { font-weight: 600; letter-spacing: 0.3px; }

        /* === ALERTS — Premium === */
        .alert { border: none; border-radius: 12px; box-shadow: var(--shadow-sm); font-weight: 600; }

        .cella-festa { background-color: #E8E4E0; } .cella-assenza { background-color: #FEE2E2; font-weight: 700; color: #991B1B; }
        .cella-smart { background-color: #FEF3C7; font-weight: 700; color: #92400E; } .cella-presenza { background-color: #D1FAE5; font-weight: 700; color: #065F46; }
        .cella-missione { background-color: #DBEAFE; font-weight: 700; color: #1E40AF; } .cella-permesso_doc { background-color: #EDE9FE; font-weight: 700; color: #6D28D9; } .cella-fuori { background-color: #FAFAF9; color: #9CA3AF; }
        
        .cella-passata { background-color: #F0EDEB !important; color: #6B7280 !important; border-color: #D5D0CC !important; font-weight: 600;}

        .testo-rosso:not(.cella-passata) { color: #dc2626 !important; font-weight: 900 !important; font-size: 1.15rem !important; }
        .testo-nero:not(.cella-passata) { color: #000000 !important; font-weight: 900 !important; font-size: 1.15rem !important; }
        .testo-verde:not(.cella-passata) { color: #16a34a !important; font-weight: 900 !important; font-size: 1.15rem !important; }
        
        .testo-rosso.cella-passata { color: #991b1b !important; font-weight: 900 !important; font-size: 1.15rem !important; }
        .testo-nero.cella-passata { color: #0f172a !important; font-weight: 900 !important; font-size: 1.15rem !important; }
        .testo-verde.cella-passata { color: #14532d !important; font-weight: 900 !important; font-size: 1.15rem !important; }

        .bordo-std { box-shadow: inset 0 0 0 4px #e02424 !important; color: #e02424 !important; font-weight: 900 !important; }
        .bordo-pref { box-shadow: inset 0 0 0 4px #057a55 !important; color: #057a55 !important; font-weight: 900 !important; }
        .bordo-back { box-shadow: inset 0 0 0 4px #3f83f8 !important; color: #1c64f2 !important; font-weight: 900 !important; }
        .bordo-pd { box-shadow: inset 0 0 0 4px #8b5cf6 !important; color: #6d28d9 !important; font-weight: 900 !important; background-image: repeating-linear-gradient(45deg, transparent, transparent 3px, rgba(139,92,246,0.12) 3px, rgba(139,92,246,0.12) 6px) !important; }

        /* ── LA CORNICE DELLE TABELLE (14/8/26) ─────────────────────────
           Ogni tabella e' UNA card: raggio, ombra e ritaglio sul
           contenitore, cosi' la prima e l'ultima riga seguono la curva.
           La densita' non cambia — e' una cornice, non un ridisegno.

           PERCHE' NON E' IL CSS DEL PLANNING. Le righe-card del planning
           (dandelion-coda.css) simulano gli angoli tondi con ombre
           multiple, fra cui dei TAPPI del colore dello sfondo di QUELLA
           pagina. Funzionano li' e soltanto li': su una tabella dentro
           una card bianca disegnerebbero rettangoli grigi in mezzo al
           bianco. Stesso raggio e stessa ombra, quindi stesso linguaggio
           visivo; mezzo diverso, perche' il caso e' diverso.

           Il ritaglio e' anche il motivo per cui il planning e le strisce
           .table-cal NON adottano questa classe: fra una colonna
           `position: sticky` e il contenitore che scorre, un antenato che
           ritaglia congela lo sticky. Il confine lo tiene fermo
           tests/test_tabelle_incorniciate.py, che legge i template e
           pretende una cornice o una regola di esenzione scritta.

           Lo sfondo bianco NON e' ridondante: su queste pagine `.dan-card`
           e' una classe senza stile (e' definita solo dentro user.html),
           quindi sotto la tabella c'e' il colore della pagina. */
        .dan-tabella {
            background: #fff;
            border-radius: 12px;
            overflow: hidden;
            box-shadow: 0 2px 5px -1px rgba(8,24,37,0.26);
        }
        /* Dentro un contenitore che ritaglia, il margine di `.table` e il
           bordo dell'ultima riga diventano una striscia bianca e una riga
           grigia appese sotto l'ultima riga: prima finivano fuori dalla
           tabella e non si notavano, adesso stanno dentro la cornice. */
        .dan-tabella > table, .dan-tabella > .table-responsive > table { margin-bottom: 0; }
        .dan-tabella table > tbody > tr:last-child > * { border-bottom: 0; }

        .table-cal { border-collapse: separate; border-spacing: 0; }
        .table-cal th, .table-cal td { text-align: center; padding: 0.35rem 0; min-width: 50px; max-width: 50px; width: 50px; border-bottom: 1px solid #D5D0CC; border-right: 1px solid #D5D0CC; vertical-align: middle; box-sizing: border-box; background-clip: padding-box; }
        .table-cal thead th { position: sticky; top: 0; z-index: 14; background-color: var(--dan-primary); color: white; border-bottom: 2px solid var(--dan-accent) !important; box-shadow: 0 2px 8px rgba(0,0,0,0.12); }
        .table-cal thead th .nome-giorno{ color: var(--dan-accent); font-weight: 600; }
        .table-cal thead th.oggi-col .nome-giorno { color: var(--dan-dark); }
        
        
        .month-header-row + tr th.sticky-col { top: 26px !important; z-index: 16 !important; }
        .table-cal thead th.oggi-col { background-color: var(--dan-accent) !important; color: white !important; border-left: 1px solid var(--dan-dark) !important; border-right: 1px solid var(--dan-dark) !important; }
        td.oggi-col { border-left: 3px solid var(--dan-accent) !important; border-right: 3px solid var(--dan-accent) !important; background-color: rgba(242,96,42,0.08) !important; font-weight: bold; }
        
        .sticky-col { position: sticky; left: 0; background-color: var(--dan-bg); z-index: 12; border-right: 2px solid var(--dan-accent) !important; font-weight: 600; text-align: left !important; min-width: 220px !important; max-width: 220px !important; width: 220px !important; padding-left: 10px !important; box-shadow: 2px 0 8px rgba(0,0,0,0.06); cursor: default; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .table-cal thead th.sticky-col { background-color: var(--dan-dark); color: var(--dan-accent); z-index: 16 !important; top: 0; left: 0; border-bottom: 2px solid var(--dan-accent) !important; }
        
        .admin-cell, .user-cell { transition: all 0.15s ease; cursor: pointer; }
        .admin-cell:hover, .user-cell:hover { filter: brightness(0.92); box-shadow: inset 0 0 6px rgba(0,0,0,0.2), 0 2px 8px rgba(0,0,0,0.1); transform: scale(1.12); z-index: 10; position: relative; border: 2px solid var(--dan-primary); border-radius: 4px; }
        
        .drag-scroll { overflow-x: auto; overflow-y: auto; white-space: nowrap; padding-bottom: 8px; cursor: grab; position: relative; }
        .drag-scroll:active { cursor: grabbing; }
        .drag-scroll::-webkit-scrollbar { height: 6px; width: 6px; }
        .drag-scroll::-webkit-scrollbar-track { background: transparent; }
        .drag-scroll::-webkit-scrollbar-thumb { background: var(--dan-beige); border-radius: 3px; }
        .drag-scroll::-webkit-scrollbar-thumb:hover { background: var(--dan-primary); }
        .legend-box { display: inline-block; width: 14px; height: 14px; margin-right: 5px; vertical-align: middle; border-radius: 3px; }
        
        .cedolino-card { transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); position: relative; border: none; box-shadow: var(--shadow-sm); }
        .cedolino-card:hover { box-shadow: var(--shadow-md) !important; }
        .cassaforte-locked { filter: grayscale(100%) opacity(0.6); pointer-events: none; }

        .dropzone-area { border: 2px dashed var(--dan-beige); border-radius: 14px; padding: 28px 12px; text-align: center; background-color: #FAFAF8; transition: all 0.3s ease; cursor: pointer; position: relative;}
        .dropzone-area:hover, .dropzone-area.dragover { border-color: var(--dan-accent); background-color: rgba(242,96,42,0.04); }
        .dropzone-area input[type="file"] { position: absolute; top:0; left:0; width:100%; height:100%; opacity:0; cursor:pointer; }
        
        /* STILI MATRICE PLANNING (ERP) */
        .planning-tab { border: none; background: transparent; padding: 10px 20px; font-weight: 600; color: var(--dan-muted); transition: all 0.25s; border-bottom: 2px solid transparent; border-radius: 0; }
        .planning-tab.active { color: var(--dan-primary); border-bottom: 2px solid var(--dan-accent); background-color: white;}
        .planning-tab:hover { color: var(--dan-dark); }
        
        .matrix-table { border-collapse: separate; border-spacing: 0; min-width: max-content; }
        .matrix-table th, .matrix-table td { text-align: center; vertical-align: middle; border-bottom: 1px solid #cbd5e1; border-right: 1px solid #cbd5e1; padding: 0; min-width: 55px; max-width: 55px; width: 55px; height: 35px; box-sizing: border-box; background-clip: padding-box;}
        
        .matrix-table thead th.th-day { position: sticky; top: 0; z-index: 14; background-color: var(--dan-primary); color: white; }
        
        
        .matrix-table thead th.th-avail { position: sticky; top: 59px; z-index: 14; background-color: #1e3a8a; color: white; font-weight: bold; font-size: 0.85rem;}
        .matrix-table thead th.th-need { position: sticky; top: 94px; z-index: 14; background-color: #7f1d1d; color: white; font-weight: bold; font-size: 0.85rem;}
        .matrix-table thead th.th-delta { position: sticky; top: 129px; z-index: 14; background-color: var(--dan-dark); color: white; font-weight: bold; font-size: 0.85rem; border-bottom: 2px solid var(--dan-accent) !important;}
        
        .matrix-table .m-col-1 { position: sticky; left: 0; z-index: 15; min-width: 120px; max-width: 120px; width: 120px; background-color: var(--dan-bg); font-weight: 600; font-size: 0.8rem; text-align: left !important; padding-left: 5px !important; overflow: hidden; text-overflow: ellipsis; white-space: normal; word-wrap: break-word;}
        .matrix-table .m-col-2 { position: sticky; left: 120px; z-index: 15; min-width: 120px; max-width: 120px; width: 120px; background-color: var(--dan-bg); font-weight: 600; font-size: 0.8rem; text-align: left !important; padding-left: 5px !important; overflow: hidden; text-overflow: ellipsis; white-space: normal; word-wrap: break-word;}
        /* FIX 10/8/26: via il border-right da 3px. Aveva specificita' (2,0) e
           batteva il 'border: 0 !important' (1,2) del blocco card in fondo:
           una riga petrolio tagliava in due ogni card, testata compresa. */
        .matrix-table .m-col-3 { position: sticky; left: 240px; z-index: 15; min-width: 90px; max-width: 90px; width: 90px; background-color: var(--dan-bg); font-size: 0.7rem; color: var(--dan-muted); text-align: center !important; overflow: hidden; text-overflow: ellipsis; white-space: normal; word-wrap: break-word;}
        
        
        
        
        
        

        .cell-fte { cursor: pointer; transition: all 0.15s ease; background-color: white; color: var(--dan-dark); font-weight: 800; font-size: 0.95rem; }
        /* Colonna festiva (sab/dom/feste nazionali) su griglia pianificazione:
           PRIMA di :hover, cosi' l'hover — pari specificita', dopo nel foglio — vince. */
        .col-festa:not(.oggi-col) { background-color: #F0EDEB !important; }
        .cell-fte:hover { background-color: rgba(242,96,42,0.08) !important; transform: scale(1.12); z-index: 10; position: relative; border: 2px solid var(--dan-accent); box-shadow: 0 2px 8px rgba(0,0,0,0.15); border-radius: 4px;}
        
        
        .delta-ok { color: #4ade80 !important; }
        .delta-warn { color: #facc15 !important; }
        .delta-alert { color: #f87171 !important; }

        /* ── Capacita' non assegnata (quarta riga di testata) ───────────────
           Il DELTA dice se il budget sta in piedi; questa riga dice chi e'
           fermo, cioe' chi si puo' spostare per alleggerire qualcun altro. */
        .matrix-table thead th.th-liberi { position: sticky; top: 164px; z-index: 14; background-color: #123f2e; color: white; font-weight: bold; font-size: 0.85rem; border-bottom: 2px solid var(--dan-accent) !important; }
        
        .lib-si { color: #6ee7a8 !important; }
        .lib-zero { color: #94a3b8 !important; }
        .lib-over { color: #f87171 !important; }
        .lib-vuoto { color: rgba(255,255,255,0.25) !important; }

        /* ── Assegnazione nominativa: sotto-righe del progetto ────────────── */
        .chev-prj { color: var(--dan-muted); font-size: 0.7rem; cursor: pointer; transition: transform .18s, color .18s; }
        .chev-prj:hover { color: var(--dan-primary); }
        tr.riga-progetto.aperta .chev-prj { transform: rotate(90deg); color: var(--dan-primary); }
        
        /* ══ Barra laterale di navigazione (area amministratore) ═══════════
           Dieci sezioni su due righe in alto, piu' un secondo livello che si
           vedeva solo una volta dentro, non erano piu' una mappa ma un elenco.
           Qui i due livelli stanno insieme e restano sempre visibili. */
        :root { --dan-sidebar-w: 236px; --dan-sidebar-w-min: 60px; }

        .dan-sidebar {
            position: fixed; top: 56px; left: 0; bottom: 0; width: var(--dan-sidebar-w);
            background: var(--dan-dark); z-index: 1030;
            display: flex; flex-direction: column;
            transition: width .22s cubic-bezier(.4,0,.2,1);
            border-right: 1px solid rgba(255,255,255,0.06);
        }
        .dan-sidebar-scroll { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 10px 0 6px; }
        .dan-sidebar-scroll::-webkit-scrollbar { width: 4px; }
        .dan-sidebar-scroll::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.14); border-radius: 2px; }

        .sb-sez { font-size: 0.58rem; text-transform: uppercase; letter-spacing: 1.2px; font-weight: 700;
                  color: rgba(255,255,255,0.32); padding: 14px 18px 6px; white-space: nowrap; }
        .sb-voce {
            display: flex; align-items: center; gap: 11px; width: 100%;
            padding: 9px 18px; border: none; background: transparent; text-align: left;
            color: rgba(255,255,255,0.72); font-size: 0.78rem; font-weight: 500;
            text-decoration: none; white-space: nowrap; cursor: pointer;
            border-left: 3px solid transparent; transition: background .15s, color .15s;
        }
        .sb-voce:hover { background: rgba(255,255,255,0.06); color: #fff; }
        .sb-voce .sb-ico { font-size: 1rem; width: 18px; flex-shrink: 0; text-align: center; }
        .sb-voce .sb-txt { overflow: hidden; text-overflow: ellipsis; }
        .sb-voce.attiva { background: rgba(242,96,42,0.13); color: #fff; font-weight: 700;
                          border-left-color: var(--dan-accent); }
        .sb-voce.attiva .sb-ico { color: var(--dan-accent); }

        /* Secondo livello: si srotola come una veneziana — l'altezza si
           apre in 280ms e le voci scendono in cascata, una dopo l'altra. */
        .sb-sub { display: block; overflow: hidden; max-height: 0;
                  transition: max-height .28s cubic-bezier(.2,.8,.25,1); }
        .sb-sub.aperto { max-height: 200px; }
        .sb-sub .sb-voce { opacity: 0; transform: translateY(-7px);
                           transition: opacity .22s ease, transform .25s cubic-bezier(.2,.8,.25,1); }
        .sb-sub.aperto .sb-voce { opacity: 1; transform: none; }
        .sb-sub.aperto .sb-voce:nth-child(1) { transition-delay: .04s; }
        .sb-sub.aperto .sb-voce:nth-child(2) { transition-delay: .09s; }
        .sb-sub.aperto .sb-voce:nth-child(3) { transition-delay: .14s; }
        .sb-sub.aperto .sb-voce:nth-child(4) { transition-delay: .19s; }
        .sb-voce.sb-figlia { padding-left: 46px; font-size: 0.74rem; color: rgba(255,255,255,0.55); }
        .sb-voce.sb-figlia::before { content: ''; position: absolute; }
        .sb-voce.sb-figlia.attiva { background: rgba(255,255,255,0.07); color: #fff;
                                    border-left-color: rgba(242,96,42,0.55); font-weight: 600; }

        .sb-piede { border-top: 1px solid rgba(255,255,255,0.08); padding: 6px 0; }
        .sb-toggle { color: rgba(255,255,255,0.45); font-size: 0.72rem; }
        .sb-toggle:hover { color: #fff; }

        /* Stretta: solo icone. Sul tabellone annuale sono 176px recuperati. */
        body.sb-stretta .dan-sidebar { width: var(--dan-sidebar-w-min); }
        body.sb-stretta .sb-txt,
        body.sb-stretta .sb-sez { display: none; }
        body.sb-stretta .sb-sub { display: none !important; }
        body.sb-stretta .sb-voce { justify-content: center; padding-left: 0; padding-right: 0; gap: 0; }

        /* Lo scostamento sta sul body e non su una classe da mettere in ogni
           template: le pagine di conformita' sono file separati e ognuna si
           sarebbe dovuta ricordare di applicarlo. La barra in alto resta a
           tutta larghezza, quindi recupera con un margine negativo. */
        body.ha-sidebar { padding-left: var(--dan-sidebar-w); transition: padding-left .22s cubic-bezier(.4,0,.2,1); }
        body.ha-sidebar > .navbar { margin-left: calc(-1 * var(--dan-sidebar-w)); width: calc(100% + var(--dan-sidebar-w)); }
        body.ha-sidebar.sb-stretta { padding-left: var(--dan-sidebar-w-min); }
        body.ha-sidebar.sb-stretta > .navbar { margin-left: calc(-1 * var(--dan-sidebar-w-min)); width: calc(100% + var(--dan-sidebar-w-min)); }
        @media (max-width: 991.98px) {
            body.ha-sidebar { padding-left: 0 !important; }
            body.ha-sidebar > .navbar { margin-left: 0 !important; width: 100% !important; }
        }

        @media (max-width: 991.98px) {
            /* Su schermo stretto la colonna ruberebbe troppo: resta la barra
               orizzontale, che con poche voci per volta funziona gia'. */
            .dan-sidebar { display: none; }
        }

        /* ── Vista colleghi in sola lettura ────────────────────────────────
           Quattro stati soltanto: presente, smart, missione, assente. Il
           motivo dell'assenza non arriva nemmeno al browser, quindi qui non
           c'e' nessuna classe per ferie, permessi o malattia. */
        .pub-pres  { background: #E3F2EA; color: #1F6B47; font-weight: 700; }
        .pub-smart { background: #E4EEF5; color: #0B5878; font-weight: 700; }
        .pub-miss  { background: #FBEDD9; color: #8A5209; font-weight: 700; }
        .pub-ass   { background: #EDE6DF; color: #A2988D; font-weight: 700; }
        .pub-nl    { background: #FBFAF9; color: #E6E2DE; }
        .pub-fuori { background: #FFFFFF; }
        .pub-key { display: inline-block; width: 11px; height: 11px; border-radius: 3px; margin-right: 4px; vertical-align: -1px; }
        .pub-key.pub-pres { background: #7DC4A0; } .pub-key.pub-smart { background: #6FA6C6; }
        .pub-key.pub-miss { background: #E8B672; } .pub-key.pub-ass { background: #E0DAD4; }
        tr.pub-io .sticky-col { background: #FFF6F1 !important; }
        .pub-badge-io { font-size: 0.58rem; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
                        background: var(--dan-accent); color: #fff; border-radius: 4px; padding: 1px 5px; vertical-align: 1px; }
        tr.pub-prj-row .sticky-col { background: #EAF2F6 !important; }
        .pub-prj-cell { background: #EAF2F6; }
        tr.pub-who-row .sticky-col { font-size: 0.78rem; color: var(--dan-text); font-weight: 500; padding-left: 26px !important; }
        .pub-fte-cell { background: #FCFBFA; color: var(--dan-primary); font-weight: 600; font-size: 0.8rem; }

        .sn-wrap { display: flex; align-items: center; justify-content: space-between; gap: 4px; width: 100%; }
        .sn-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        /* Copertura del progetto: quanta parte del budget e' gia' coperta da
           persone assegnate. Una barretta senza etichetta non diceva niente a
           nessuno; un numero in percentuale si legge da solo, e la legenda in
           testata alla scheda spiega di cosa si tratta. */
        .cop-pill { flex-shrink: 0; cursor: pointer; font-size: 0.62rem; font-weight: 700;
                    border-radius: 5px; padding: 1px 5px; font-variant-numeric: tabular-nums; letter-spacing: -0.2px; }
        .cop-ok   { background: #DFF0E6; color: #1F6B47; }
        .cop-parz { background: #FBEDD9; color: #8A5209; }
        .cop-zero { background: #F7E3E3; color: #A33A3A; }
        tr.riga-persona { display: none; background: #FCFBFA; }
        tr.riga-persona.visibile { display: table-row; }
        .nome-assegnato { font-size: 0.72rem; color: var(--dan-text); font-weight: 500; padding-left: 8px !important; text-align: left !important; }
        /* Il filtro dentro il riquadro RISORSA: piccolo, monocromo, sempre
           visibile perche' la colonna e' fissa. */
        .dev-banner { position: sticky; top: 0; z-index: 1045; background: #8944AB; color: #fff;
                      font-size: 0.74rem; font-weight: 600; padding: 6px 16px; text-align: center; }
        .dev-banner-esci { color: #fff; text-decoration: underline; margin-left: 10px; font-weight: 700; }
        .dev-banner-esci:hover { color: #FFE3A3; }

        .btn-filtro-risorsa { background: rgba(120,120,128,0.12); color: var(--hig-testo);
                              border: none; border-radius: 7px; font-size: 0.66rem; font-weight: 600;
                              padding: 2px 8px; }
        .btn-filtro-risorsa:hover { background: rgba(120,120,128,0.22); color: var(--hig-testo); }
        .dropdown-menu { border: 0.5px solid var(--hig-linea); border-radius: 12px; }

        .btn-x-persona { border: none; background: transparent; color: #C9C2BB; font-size: 0.95rem;
                         line-height: 1; padding: 0 6px 0 2px; cursor: pointer; vertical-align: middle; }
        .btn-x-persona:hover { color: var(--dan-danger); }
        .nome-assegnato .bi { color: var(--dan-primary); margin-right: 5px; opacity: .6; }
        .cell-asseg { background: #FCFBFA; color: var(--dan-primary); font-weight: 600; font-size: 0.8rem; }
        tr.riga-scoperto td { color: var(--dan-danger) !important; font-weight: 700; font-size: 0.75rem; font-style: italic; }
        tr.riga-scoperto .m-col-2 { padding-left: 30px !important; text-align: left !important; }
        .btn-assegna { border: 1.5px dashed var(--dan-beige); background: transparent; color: var(--dan-primary); border-radius: 8px; font-size: 0.68rem; font-weight: 700; padding: 2px 10px; margin-left: 22px; cursor: pointer; }
        

        /* ══ Assegnazione persone — ORIGAMI ════════════════════════════════
           Linguaggio preso dall'app contabilita' (BIBBIA.md): la tessera
           cliccata VOLA dalla sua posizione reale al centro (600ms), poi la
           scheda si sdoppia in fogli che si aprono ruotando sul bordo
           sinistro con ritardo crescente — la piega diagonale. */
        .asg-ovl { position: fixed; inset: 0; background: rgba(8,24,37,.55); display: none; z-index: 1050; }
        .asg-ovl.on { display: block; }
        .asg-stage { position: fixed; inset: 24px; max-width: 1180px; margin: 0 auto; background: var(--dan-bg);
                     border-radius: 18px; z-index: 1051; display: none; flex-direction: column; overflow: hidden;
                     box-shadow: 0 24px 80px rgba(8,24,37,.45); }
        .asg-stage.on { display: flex; animation: asg-ingresso .34s cubic-bezier(.2,.8,.25,1); }
        @keyframes asg-ingresso { from { opacity: .2; transform: perspective(1400px) rotateY(-72deg); }
                                  to { opacity: 1; transform: none; } }
        .asg-testata { background: var(--dan-dark); color: #fff; padding: 14px 22px; position: relative;
                       display: flex; align-items: center; gap: 22px; flex-wrap: wrap; flex-shrink: 0;
                       border-bottom: 2px solid var(--dan-accent); }
        .asg-testata .tit h5 { margin: 0; font-size: 1rem; font-weight: 700; }
        .asg-testata .tit p { margin: 2px 0 0; font-size: 0.7rem; opacity: .7; }
        .asg-testata .chiudi { position: absolute; top: 10px; right: 14px; color: #fff; background: none;
                               border: none; font-size: 1.4rem; cursor: pointer; opacity: .7; }
        .asg-testata .chiudi:hover { opacity: 1; }
        .asg-periodo { display: flex; gap: 8px; align-items: flex-end; }
        .asg-periodo label { font-size: 0.58rem; text-transform: uppercase; letter-spacing: .5px;
                             color: rgba(255,255,255,.55); display: block; margin-bottom: 3px; font-weight: 700; }
        .asg-periodo input { border: 1px solid rgba(255,255,255,.25); border-radius: 8px; padding: 5px 9px;
                             font-size: 0.75rem; background: rgba(255,255,255,.08); color: #fff; font-family: inherit; width: 118px; }
        .asg-riepilogo { display: flex; gap: 18px; margin-left: auto; padding-right: 26px; }
        .asg-kpi { text-align: right; }
        .asg-kpi b { display: block; font-size: 1.15rem; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
        .asg-kpi span { font-size: 0.56rem; text-transform: uppercase; letter-spacing: .6px; color: rgba(255,255,255,.55); }
        .asg-kpi.rosso b { color: #FF9D7A; } .asg-kpi.verde b { color: #6EE7A8; }
        .asg-corpo { flex: 1; overflow-y: auto; padding: 18px 22px 26px; }
        .asg-sec { font-size: 0.62rem; text-transform: uppercase; letter-spacing: .8px; color: var(--dan-muted);
                   font-weight: 700; margin: 16px 0 10px; }
        .asg-sec:first-child { margin-top: 0; }

        /* Le tessere: niente lista grigia, una griglia di carte con la
           ciambella d'impiego a 12 mesi. */
        .asg-griglia { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 12px; }
        .asg-tess { background: #fff; border: 1.5px solid var(--dan-border); border-radius: 14px;
                    padding: 14px 12px 12px; cursor: pointer; text-align: center; position: relative;
                    transition: transform .18s, box-shadow .18s, border-color .18s; }
        .asg-tess:hover { transform: translateY(-3px); border-color: var(--dan-primary);
                          box-shadow: 0 10px 24px rgba(9,83,115,.16); }
        .asg-tess.dentro { border-color: var(--dan-primary); background: linear-gradient(180deg, #F4FAFD 0%, #fff 60%); }
        .asg-tess .badge-dentro { position: absolute; top: 8px; left: 8px; font-size: 0.54rem; font-weight: 700;
                                  text-transform: uppercase; letter-spacing: .5px; background: var(--dan-primary);
                                  color: #fff; border-radius: 4px; padding: 1px 5px; }
        .asg-tess .nome { font-size: 0.78rem; font-weight: 700; color: var(--dan-dark); margin-top: 8px;
                          white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .asg-tess .ruolo { font-size: 0.6rem; color: var(--dan-muted); }
        .asg-tess .pct { font-size: 0.62rem; font-weight: 700; margin-top: 3px; }
        .asg-tess .pct.ok { color: var(--dan-success); } .asg-tess .pct.mezzo { color: var(--dan-warning); }
        .asg-tess .pct.pieno { color: var(--dan-danger); }

        /* Il volo: un clone della tessera che va dalla posizione reale al
           centro. Le coordinate di partenza sono quelle vere del rettangolo
           cliccato, cosi' sembra la stessa cosa che si muove. */
        .asg-volo { position: fixed; z-index: 1053; display: none; pointer-events: none;
                    background: #fff; border: 1.5px solid var(--dan-primary); border-radius: 14px;
                    transition: all 600ms cubic-bezier(.2,.8,.25,1); }
        .asg-volo.on { display: block; }

        /* L'origami aperto: tre fogli che ruotano sul bordo sinistro con
           ritardo crescente e un gradino verso il basso — la piega. */
        /* ── Chiusura del mese con giornate incomplete (rilievo #3) ──
           Riquadro sospeso, stesso linguaggio dell'origami del planning. */
        #chiuOverlay { position: fixed; inset: 0; z-index: 1060; background: rgba(8,24,37,.45);
                       display: flex; align-items: flex-start; justify-content: center;
                       overflow: auto; padding: 28px 16px; }
        .chiu-foglio { width: 100%; max-width: 1000px; background: #fff; border-radius: 18px;
                       box-shadow: 0 22px 70px -22px rgba(8,24,37,.55); overflow: hidden; }
        .chiu-foglio header { padding: 16px 22px; border-bottom: 1px solid var(--linea, #E4E4E8);
                              display: flex; align-items: center; gap: 14px; }
        .chiu-foglio h1 { margin: 0; font-size: 1.02rem; font-weight: 700; color: #081825; }
        .chiu-sub { font-size: .78rem; color: #9CA3AF; margin-top: 2px; }
        .chiu-chip { margin-left: auto; font-size: .68rem; font-weight: 700; letter-spacing: .4px;
                     text-transform: uppercase; padding: 5px 12px; border-radius: 999px;
                     background: #FFF1E6; color: #B25000; border: 1px solid #F0C9A6; }
        .chiu-x { border: 0; background: transparent; font-size: 1.5rem; line-height: 1;
                  color: #9CA3AF; cursor: pointer; padding: 0 2px; }
        .chiu-barra { margin: 0; padding: 13px 22px; background: #FFF8F2;
                      border-bottom: 1px solid #F0D9C4; font-size: .84rem; line-height: 1.5; }
        .chiu-barra b { color: #B25000; }
        .chiu-corpo { padding: 18px 22px; }
        .chiu-corpo table { width: 100%; border-collapse: separate; border-spacing: 0 6px; font-size: .83rem; }
        .chiu-corpo thead th { font-size: .58rem; text-transform: uppercase; letter-spacing: .6px;
                               color: #9CA3AF; font-weight: 700; text-align: left; padding: 0 10px 2px; }
        .chiu-corpo tbody tr { background: #F7F7F9; }
        .chiu-corpo tbody tr.risolta { background: #F1F8F4; }
        .chiu-corpo tbody td { padding: 9px 10px; border-top: 1px solid #E4E4E8;
                               border-bottom: 1px solid #E4E4E8; vertical-align: middle; }
        .chiu-corpo tbody td:first-child { border-left: 1px solid #E4E4E8; border-radius: 12px 0 0 12px; }
        .chiu-corpo tbody td:last-child { border-right: 1px solid #E4E4E8; border-radius: 0 12px 12px 0; }
        .chiu-corpo tbody tr.risolta td { border-color: #CBE5D6; }
        .chiu-g b { color: #081825; }
        .chiu-g small { display: block; font-weight: 400; color: #9CA3AF; font-size: .72rem; }
        .chiu-t { font-variant-numeric: tabular-nums; color: #5B6B75; }
        .chiu-manca { color: #D70015; font-weight: 700; }
        .chiu-nd { color: #9CA3AF; font-size: .78rem; }
        #chiuOverlay select, #chiuOverlay input[type=time], #chiuOverlay input[type=text] {
            font: inherit; font-size: .82rem; padding: 5px 8px; border: 1px solid #E4E4E8;
            border-radius: 8px; background: #fff; color: #081825; }
        #chiuOverlay input[type=time], #chiuOverlay .chiu-val input { width: 108px; }
        #chiuOverlay select.vuoto { color: #9CA3AF; border-color: #F0C9A6; background: #FFFCF9; }
        .chiu-pill { display: inline-block; font-size: .62rem; font-weight: 700; padding: 3px 8px;
                     border-radius: 999px; background: #E7EEF2; color: #095373; }
        .chiu-pill.admin { background: #FFF1E6; color: #B25000; }
        .chiu-pill.rosso { background: #FDECEA; color: #D70015; }
        /* La decisione c'e', ma il suo autore non si puo' nominare: utente
           cancellato, oppure nessun uid registrato. Grigio e non arancione
           perche' non e' una decisione di chi sta guardando — e lo stato
           dev'essere leggibile prima del testo. */
        .chiu-pill.grigio { background: #EFEFF2; color: #6B6B73; font-style: italic; }
        .chiu-multi { display: flex; align-items: center; gap: 10px; margin: 4px 0 12px;
                      padding: 10px 12px; background: #F7F7F9; border: 1px dashed #E4E4E8;
                      border-radius: 12px; font-size: .8rem; }
        .chiu-multi span { color: #9CA3AF; }
        .chiu-motivo { margin-top: 20px; padding: 15px 17px; background: #F7F7F9;
                       border-radius: 14px; border: 1px solid #E4E4E8; }
        .chiu-motivo .tit { display: block; font-size: .6rem; text-transform: uppercase;
                            letter-spacing: .9px; color: #9CA3AF; font-weight: 700; margin-bottom: 8px; }
        .chiu-scelte { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
        .chiu-scelte label { display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px;
                             background: #fff; border: 1px solid #E4E4E8; border-radius: 999px;
                             font-size: .8rem; cursor: pointer; }
        .chiu-scelte label:has(input:checked) { border-color: #095373; background: #E7EEF2;
                             color: #095373; font-weight: 600; }
        .chiu-motivo input[type=text] { width: 100%; }
        .chiu-nota { font-size: .72rem; color: #9CA3AF; margin: 8px 0 0; line-height: 1.45; }
        .chiu-foglio footer { padding: 15px 22px; border-top: 1px solid #E4E4E8;
                              display: flex; align-items: center; gap: 12px; background: #FAFAFB; }
        .chiu-btn { font: inherit; font-size: .84rem; font-weight: 700; border: 0;
                    border-radius: 10px; padding: 9px 18px; cursor: pointer; }
        .chiu-btn.primario { background: #095373; color: #fff; }
        .chiu-btn.primario[disabled] { background: #C9CDD1; cursor: not-allowed; }
        .chiu-btn.neutro { background: #fff; color: #095373; border: 1px solid #095373; }
        .chiu-stato { margin-left: auto; font-size: .78rem; color: #9CA3AF; }
        .chiu-stato b { color: #B25000; }

        .asg-origami { position: fixed; inset: 0; z-index: 1054; display: none; align-items: center;
                       justify-content: center; perspective: 1400px; pointer-events: none; }
        .asg-origami.on { display: flex; }
        /* VASSOIO: i tre fogli stanno su un ripiano grigio trasparente. Senza,
           l'area da afferrare per spostare l'origami era invisibile — si
           trascinava a intuito. Il ripiano E' la presa: tutto quello che non
           e' un comando muove il pannello. */
        .asg-origami .fogli { display: flex; gap: 16px; align-items: flex-start; max-width: 1160px;
                              width: calc(100vw - 70px); pointer-events: auto;
                              background: rgba(60,60,67,0.22); -webkit-backdrop-filter: blur(3px);
                              backdrop-filter: blur(3px); border: 1px solid rgba(255,255,255,0.30);
                              border-radius: 22px; padding: 14px; cursor: grab;
                              box-shadow: 0 26px 70px -18px rgba(8,24,37,.55); }
        .asg-origami .fogli:active { cursor: grabbing; }
        .asg-origami .fogli input, .asg-origami .fogli button,
        .asg-origami .fogli select, .asg-origami .fogli label { cursor: auto; }
        .asg-origami .fogli button { cursor: pointer; }
        .asg-foglio { background: #fff; border-radius: 16px; box-shadow: 0 18px 60px rgba(8,24,37,.5);
                      transform-origin: left center; transform: rotateY(-70deg) scale(.85); opacity: 0;
                      padding: 16px 18px; }
        .asg-origami.aperto .asg-foglio { transform: rotateY(0) scale(1); opacity: 1; }
        .asg-foglio:nth-child(1) { flex: 1.55 1 0; transition: transform 620ms cubic-bezier(.2,.8,.25,1) 0ms, opacity 300ms 0ms; }
        .asg-foglio:nth-child(2) { flex: 1 1 0; margin-top: 26px; transition: transform 620ms cubic-bezier(.2,.8,.25,1) 110ms, opacity 300ms 110ms; }
        .asg-foglio:nth-child(3) { flex: 1 1 0; margin-top: 52px; transition: transform 620ms cubic-bezier(.2,.8,.25,1) 220ms, opacity 300ms 220ms; }
        .asg-foglio h6 { font-size: 0.62rem; text-transform: uppercase; letter-spacing: .8px;
                         color: var(--dan-muted); font-weight: 700; margin: 0 0 10px; }
        .asg-of-testa { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
        .asg-of-testa .nome { font-size: 0.95rem; font-weight: 700; color: var(--dan-dark); }
        .asg-of-testa .ruolo { font-size: 0.62rem; color: var(--dan-muted); }
        .asg-of-chiudi { position: absolute; top: -14px; right: -10px; width: 30px; height: 30px; border-radius: 50%;
                         background: var(--dan-dark); color: #fff; border: none; font-size: 1rem; cursor: pointer;
                         box-shadow: 0 4px 12px rgba(8,24,37,.4); }
        .asg-sofferenza { font-size: 0.72rem; font-weight: 700; margin-top: 8px; }
        .asg-sofferenza.ok { color: var(--dan-success); } .asg-sofferenza.male { color: var(--dan-accent); }
        .asg-puodare { display: flex; align-items: center; gap: 11px; background: #F1F7F4;
                       border: 1px solid #CFE8DC; border-radius: 12px; padding: 10px 13px; margin-bottom: 12px; }
        .asg-puodare b { font-size: 1.6rem; font-weight: 700; color: var(--dan-success);
                         font-variant-numeric: tabular-nums; line-height: 1; }
        .asg-puodare .et { display: block; font-size: 0.72rem; font-weight: 700; color: var(--dan-dark); }
        .asg-puodare .sub { display: block; font-size: 0.62rem; color: var(--dan-muted); margin-top: 2px; }
        .asg-campo { margin-bottom: 10px; }
        .asg-campo label { font-size: 0.6rem; text-transform: uppercase; letter-spacing: .5px;
                           color: var(--dan-muted); font-weight: 700; display: block; margin-bottom: 3px; }
        .asg-campo input { width: 100%; border: 1.5px solid var(--dan-beige); border-radius: 9px; padding: 7px 10px;
                           font-size: 0.85rem; background: #FAFAF8; font-family: inherit; font-variant-numeric: tabular-nums; }
        .asg-campo .nota { font-size: 0.62rem; color: var(--dan-muted); margin-top: 3px; display: block; }
        .asg-check { display: block; font-size: 0.68rem; color: var(--dan-text); margin-top: 8px; cursor: pointer; }
        .asg-check input { vertical-align: -1px; margin-right: 4px; accent-color: var(--hig-tint, var(--dan-primary)); }
        .asg-impatto { font-size: 0.78rem; line-height: 1.5; }
        .asg-impatto b { font-variant-numeric: tabular-nums; }
        .asg-freccia-cop { display: flex; align-items: center; gap: 8px; margin: 8px 0 12px; font-variant-numeric: tabular-nums; }
        .asg-freccia-cop .da { font-size: 1.3rem; font-weight: 700; color: var(--dan-muted); }
        .asg-freccia-cop .a { font-size: 1.7rem; font-weight: 700; color: var(--dan-primary); }
        .asg-btn { background: var(--dan-primary); color: #fff; border: none; border-radius: 10px;
                   font-size: 0.78rem; font-weight: 700; padding: 10px 18px; cursor: pointer; width: 100%; }
        .asg-btn:hover { background: var(--dan-dark); }
        .asg-btn.togli { background: #fff; color: var(--dan-danger); border: 1.5px solid #F3B5B5; margin-top: 8px; }
        .asg-warn { font-size: 0.68rem; color: var(--dan-danger); margin-top: 8px; line-height: 1.4; }
        @media (max-width: 900px) {
            .asg-origami .fogli { flex-direction: column; overflow-y: auto; max-height: 92vh; }
            .asg-foglio:nth-child(2), .asg-foglio:nth-child(3) { margin-top: 0; }
            .asg-stage { inset: 8px; }
            .asg-riepilogo { margin-left: 0; }
        }

        .btn-add-proj { font-size: 0.7rem; padding: 2px 6px; border-radius: 4px; }
        .bulk-btn { font-size: 0.7rem; background: var(--dan-primary); color: white; border: none; border-radius: 4px; padding: 2px 6px; cursor: pointer; transition: all 0.2s; }
        .bulk-btn:hover { background: var(--dan-accent); color: white; }

        /* Z-index per garantire che il calendario si sovrapponga correttamente alle modali Bootstrap */
        .flatpickr-calendar { z-index: 9999 !important; }

        /* ===== MOBILE UX PREMIUM ===== */
        @media (max-width: 768px) {
            .card { border-radius: 14px; }
            /* Su schermo stretto la scheda si stringe. Veniva dalla media
               query di user.html: lasciandola li', sul telefono le pagine
               nuove avrebbero tenuto il respiro del desktop. */
            .dan-card { padding: 20px; border-radius: 14px; }
            .card-body { padding: 16px; }
            .card-header { padding: 14px 16px; }
            .modal-dialog { margin: 0; max-width: 100%; }
            .modal-content { border-radius: 16px 16px 0 0; min-height: 80vh; box-shadow: var(--shadow-lg); }
            .btn { min-height: 44px; }
            .form-control, .form-select { min-height: 44px; font-size: 16px !important; }

            /* Navbar compatta su mobile */
            .navbar { padding: 0 12px; height: 48px; }
            .navbar .navbar-brand img { height: 24px !important; }

            /* Safe area per iPhone con notch */
            body { padding-bottom: env(safe-area-inset-bottom); }

            /* Modali full-screen per anagrafica/fascicolo */
            .modal-fullscreen-mobile .modal-dialog {
                margin: 0; max-width: 100%; height: 100%;
            }
            .modal-fullscreen-mobile .modal-content {
                border-radius: 0; min-height: 100vh; border: none;
            }

            /* Tabellone: nomi colonna nascosta */
            .sticky-col {
                min-width: 140px !important; max-width: 140px !important; width: 140px !important;
                font-size: 0.75rem !important; padding-left: 6px !important;
            }

            /* Legend hide */
            #hr-legenda { display: none !important; }

            /* Hide custom scrollbar on touch */
            ::-webkit-scrollbar { display: none; }
            * { scrollbar-width: none; }
        }

        @media (max-width: 480px) {
            .sticky-col {
                min-width: 110px !important; max-width: 110px !important; width: 110px !important;
            }
        }

        /* ═══════════════════════════════════════════════════════════════════
           LIVELLO HIG — minimalismo assoluto (Human Interface Guidelines)
           Sta in FONDO al foglio apposta: vince sulla decorazione precedente
           senza doverla smontare regola per regola. Tre principi:
           1. un solo colore d'accento (petrolio); l'arancio si ritira al
              ruolo semantico di avviso;
           2. niente lastre colorate: fondi chiari, hairline da 0.5px, il
              colore vive solo nei valori;
           3. tipografia di sistema (su Mac/iPhone diventa SF Pro), gerarchia
              data da corpo e peso, non da colori e maiuscole.
           ═══════════════════════════════════════════════════════════════════ */
        :root {
            --hig-bg: #F5F5F7;            /* systemGroupedBackground */
            --hig-card: #FFFFFF;
            --hig-testo: #1D1D1F;         /* label */
            --hig-testo2: #6E6E73;        /* secondaryLabel */
            --hig-testo3: #AEAEB2;        /* tertiaryLabel */
            --hig-linea: rgba(60,60,67,0.12);       /* separator */
            --hig-linea-forte: rgba(60,60,67,0.22);
            --hig-tint: #095373;          /* il petrolio Dandelion come tint unico */
            --hig-tint-bg: rgba(9,83,115,0.09);
            --hig-verde: #248A3D;         /* systemGreen (declinazione scura) */
            --hig-rosso: #D70015;         /* systemRed */
            --hig-ambra: #C93400;         /* arancio: SOLO avvisi */
            --dan-bg: var(--hig-bg);
            --dan-border: var(--hig-linea);
            --dan-muted: var(--hig-testo2);
            --dan-text: var(--hig-testo);
        }
        body, h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6, button, input, select, textarea {
            font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, "Helvetica Neue", sans-serif !important;
        }
        body { background: var(--hig-bg); color: var(--hig-testo); -webkit-font-smoothing: antialiased; }
        h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6 { color: var(--hig-testo); letter-spacing: -0.01em; }
        .display-num { font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", sans-serif !important;
                       font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }

        /* ── Barra in alto: traslucida chiara, hairline, niente lastra scura ── */
        .navbar, nav.navbar, .navbar.bg-dark {
            background: rgba(255,255,255,0.82) !important;
            backdrop-filter: blur(22px) saturate(180%); -webkit-backdrop-filter: blur(22px) saturate(180%);
            border-bottom: 0.5px solid var(--hig-linea) !important;
        }
        .navbar * { color: var(--hig-testo) !important; }
        .navbar .brand-accent { color: var(--hig-testo) !important; letter-spacing: 2px; }
        /* Il marchio era bianco per la barra scura: sulla chiara diventa
           monocromo scuro, come un glifo di sistema. */
        .navbar img { filter: invert(0.85) sepia(0.4) saturate(4) hue-rotate(160deg) brightness(0.45); }
        .navbar .btn, .navbar button { border-color: var(--hig-linea-forte) !important; background: transparent !important; }
        .navbar .avatar-circle { background: var(--hig-tint) !important; color: #fff !important; }
        .navbar span[style] { color: var(--hig-testo2) !important; }

        /* ── Sidebar: chiara come macOS, icone monocrome, accento sull'attiva ── */
        .dan-sidebar {
            background: rgba(246,246,248,0.92);
            backdrop-filter: blur(24px) saturate(180%); -webkit-backdrop-filter: blur(24px) saturate(180%);
            border-right: 0.5px solid var(--hig-linea);
        }
        .sb-sez { color: var(--hig-testo3); }
        .sb-voce { color: var(--hig-testo); border-left: none; border-radius: 8px; margin: 1px 8px; padding: 8px 12px; width: auto; display: flex; }
        .sb-voce .sb-ico { color: var(--hig-testo2); }
        .sb-voce:hover { background: rgba(0,0,0,0.05); color: var(--hig-testo); }
        .sb-voce.ha-sotto { background: rgba(0,0,0,0.045); font-weight: 600; }
        .sb-voce.ha-sotto:hover { background: rgba(0,0,0,0.08); }
        .sb-voce.attiva { background: var(--hig-tint-bg); color: var(--hig-tint); border-left: none; }
        .sb-voce.attiva .sb-ico { color: var(--hig-tint); }
        .sb-voce.sb-figlia { color: var(--hig-testo2); padding-left: 34px; }
        .sb-voce.sb-figlia.attiva { background: rgba(0,0,0,0.05); color: var(--hig-testo); border-left: none; }
        .sb-piede { border-top: 0.5px solid var(--hig-linea); }
        .sb-toggle { color: var(--hig-testo3); }
        .sb-toggle:hover { color: var(--hig-testo); }
        body.sb-stretta .sb-voce { justify-content: center; }

        /* ── Card: bianche, raggio continuo, hairline, niente ombre pesanti ── */
        .card { border: 0.5px solid var(--hig-linea) !important; border-radius: 14px; box-shadow: none !important; }
        .card:hover { transform: none !important; box-shadow: none !important; }
        /* Le testate colorate inline diventano bianche: !important nel foglio
           vince sugli style inline, ed e' il modo per spegnerle tutte insieme. */
        .card > .card-header, .card .card-header {
            background: transparent !important; color: var(--hig-testo) !important;
            border-bottom: 0.5px solid var(--hig-linea) !important; font-weight: 600;
        }
        .card-header *, .card-header .text-white, .card-header small { color: var(--hig-testo) !important; }
        .card-header small, .card-header .text-white-50 { color: var(--hig-testo2) !important; }
        .card-header .btn { background: rgba(120,120,128,0.12) !important; color: var(--hig-testo) !important;
                            border: none !important; border-radius: 8px; }
        .card-header .btn:hover { background: rgba(120,120,128,0.2) !important; }

        /* ── Bottoni: pieno = tint, il resto grigio-tinta iOS ── */
        .btn-primary { background: var(--hig-tint) !important; border: none !important; border-radius: 10px; box-shadow: none !important; }
        .btn-primary:hover { background: #0A628A !important; transform: none !important; box-shadow: none !important; }
        .btn-outline-primary, .btn-ghost { background: rgba(120,120,128,0.12) !important; color: var(--hig-testo) !important;
                                           border: none !important; border-radius: 10px; }
        .btn-outline-primary:hover, .btn-ghost:hover { background: rgba(120,120,128,0.2) !important; color: var(--hig-testo) !important; }
        .btn { box-shadow: none !important; }

        /* ── Campi: fondo bianco, hairline, anello di fuoco tint ── */
        .form-control, .form-select { background: var(--hig-card); border: 0.5px solid var(--hig-linea-forte);
                                      border-radius: 10px; color: var(--hig-testo); }
        .form-control:focus, .form-select:focus { border-color: var(--hig-tint); box-shadow: 0 0 0 3px var(--hig-tint-bg); }

        /* ── Navigazione a schede: testo quieto, attiva col tint ── */
        .planning-tab, .sub-tab-btn, .desktop-tab-btn { color: var(--hig-testo2); font-weight: 500; }
        .planning-tab.active, .sub-tab-btn.active, .desktop-tab-btn.active {
            color: var(--hig-tint); border-bottom-color: var(--hig-tint) !important; background: transparent; font-weight: 600; }
        .nav-pills .nav-link { color: var(--hig-testo2); border: none !important; box-shadow: none !important; }
        .nav-pills .nav-link.active { background: var(--hig-tint) !important; box-shadow: none !important; }

        /* ── Tabelloni: testate CHIARE, il colore sta solo nei valori ── */
        .table-cal thead th, .matrix-table thead th,
        .table-cal thead th.sticky-col, .matrix-table thead th.m-col-1,
        .matrix-table thead th.m-col-2, .matrix-table thead th.m-col-3 {
            background: #FBFBFD !important; color: var(--hig-testo2) !important;
            border-bottom: 0.5px solid var(--hig-linea) !important; font-weight: 600;
        }
        .month-header-row th, .month-header-row-plan th, .matrix-table thead tr:first-child th {
            background: var(--hig-bg) !important; color: var(--hig-testo3) !important;
            border-color: var(--hig-linea) !important; letter-spacing: 1.4px !important;
        }
        
        
        
        
        /* I giorni della settimana in testata: grigi, non arancio. L'unico
           giorno marcato e' OGGI, come nel Calendario di iOS. */
        .table-cal thead th .nome-giorno, .matrix-table thead th .nome-giorno,
        .table-cal thead th small, .matrix-table thead th small { color: var(--hig-testo3) !important; }
        .table-cal thead th.oggi-col, .matrix-table thead th.oggi-col {
            background: var(--hig-tint) !important; color: #fff !important; box-shadow: none !important; }
        .table-cal thead th.oggi-col *, .matrix-table thead th.oggi-col * { color: #fff !important; }

        /* Testata del planning distinta dai dati: fondo grigio velato e
           bordo marcato sotto l'ultima riga. Prima testata e dati erano
           entrambi bianchi e si confondevano. */
        .matrix-table thead th.th-avail, .matrix-table thead th.th-need,
        .matrix-table thead th.th-delta, .matrix-table thead th.th-liberi,
        .matrix-table thead th.th-avail.m-col-1, .matrix-table thead th.th-avail.m-col-2, .matrix-table thead th.th-avail.m-col-3,
        .matrix-table thead th.th-need.m-col-1, .matrix-table thead th.th-need.m-col-2, .matrix-table thead th.th-need.m-col-3,
        .matrix-table thead th.th-delta.m-col-1, .matrix-table thead th.th-delta.m-col-2, .matrix-table thead th.th-delta.m-col-3,
        .matrix-table thead th.th-liberi.m-col-1, .matrix-table thead th.th-liberi.m-col-2, .matrix-table thead th.th-liberi.m-col-3 {
            background: #EFEFF2 !important; font-size: 0.78rem !important;
        }
        
        

        /* Aria fra le righe: piu' padding, hairline sotto ogni riga, riga
           del progetto su fondo velato per distinguerla dalle sotto-righe. */
        .matrix-table tbody td { padding-top: 9px !important; padding-bottom: 9px !important;
                                 border-bottom: 0.5px solid var(--hig-linea) !important; }
        
        /* Le colonne fisse stanno SEMPRE sopra i giorni che scorrono:
           senza z-index e fondo opaco, i numeri passavano sopra ai nomi. */
        .matrix-table tbody td.m-col-1, .matrix-table tbody td.m-col-2, .matrix-table tbody td.m-col-3 {
            z-index: 22 !important; background-color: #fff; }
        /* Geometria dichiarata PER COSTRUZIONE: larghezza e scostamento di
           ogni colonna fissa combaciano per definizione, cosi' non restano
           fessure da cui si vedono i numeri che scorrono sotto.
           QUESTA E' L'UNICA SORGENTE degli scostamenti: il blocco card in
           fondo prova a ridichiararli con '.matrix-table .m-col-N' (2,0),
           che PERDE contro '.matrix-table td.m-col-N' (2,1). Somma 108+132+96
           = 336, ed e' la larghezza di th-data e th-mese-lab (colspan 3).
           Gli scostamenti partono da ZERO: l'aria dal bordo NON si ricava
           qui dentro (vedi il BORDO del contenitore in fondo al file). */
        .matrix-table td.m-col-1, .matrix-table th.m-col-1 {
            position: sticky !important; left: 0 !important;
            min-width: 108px !important; max-width: 108px !important;
            overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        .matrix-table td.m-col-2, .matrix-table th.m-col-2 {
            position: sticky !important; left: 108px !important;
            min-width: 132px !important; max-width: 132px !important;
            overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        .matrix-table td.m-col-3, .matrix-table th.m-col-3 {
            position: sticky !important; left: 240px !important;
            min-width: 96px !important; max-width: 96px !important;
            overflow: hidden; white-space: nowrap; }
        
        
        
        /* La riga APERTA usava un'evidenza trasparente: sulle colonne fisse
           faceva da vetro e i numeri in scorrimento si vedevano attraverso.
           Qui serve il colore equivalente ma PIENO. */
        

        /* ── Blocchi sospesi ────────────────────────────────────────────
           Ogni progetto (e ogni persona nel tabellone presenze) e' una
           card BIANCA sul fondo grigio, staccata da un CANALE piu' scuro.
           L'ombra non si puo' appoggiare sotto la card (in una tabella
           collassata la riga successiva la coprirebbe): la disegna la
           riga successiva DENTRO il proprio canale, con un gradiente che
           parte scuro sotto la card sopra e muore nel canale. Cosi'
           l'ombra sta nello spazio fra le righe, mai sul contenuto. */
        /* FIX 10/8/26: la matrix-table NON usa piu' il canale finto. Il canale
           vero e' 'border-spacing: 0 6px' (blocco card in fondo). Questo
           border-top da 8px stava DENTRO il box della cella: il border-radius
           lo arrotondava e la box-shadow ci girava intorno, quindi ogni card
           portava un cappello grigio dentro la propria sagoma e il canale
           risultava 6+8=14px. Resta solo per .table-cal, che il rifacimento
           non ha ancora toccato e disegna ancora il canale a mano. */
        .table-cal tr.tabellone-row > td {
            border-top: 8px solid #E4E4E8 !important;
        }
        .table-cal tbody tr > td:not(.sticky-col){ position: relative; }
        /* la striscia d'ombra nel canale (celle normali e sticky senza pseudo occupato) */
        .table-cal tr.tabellone-row > td:not(.sticky-col)::before{
            content: ''; position: absolute; left: 0; right: 0; top: -8px; height: 8px;
            background: linear-gradient(180deg, rgba(8,24,37,0.16) 0, rgba(8,24,37,0.04) 4px, rgba(8,24,37,0) 7px);
            pointer-events: none;
        }

        /* ── Angolo anteriore smussato + carta bianca sulle celle sticky ──
           border-radius non lavora nelle tabelle collassate: il tondo lo
           fa un doppio strato opaco dentro la cella sticky. ::after fa da
           fondale (canale con l'ombra in testa, e colore-canale dove il
           tondo scopre l'angolo); ::before e' la carta con l'angolo. */
        .table-cal tr.tabellone-row > td.sticky-col{
            background: transparent !important;
        }
        .table-cal tr.tabellone-row > td.sticky-col { z-index: 15; }
        .table-cal tr.tabellone-row > td.sticky-col::after{
            content: ''; position: absolute; left: 0; right: 0; top: -8px; bottom: 0; z-index: -2;
            /* l'ombra in testa parte DOPO la colonnina d'aria (8px): un tratto
               dritto che l'attraversava non aveva nessuna carta a proiettarlo */
            background: linear-gradient(180deg, #CFD0D5 0, #DCDDE2 4px, #E4E4E8 8px, #E4E4E8 100%) 8px 0 / calc(100% - 8px) 100% no-repeat, #E4E4E8;
        }
        
        
        
        
        .table-cal tr.tabellone-row > td.sticky-col::before {
            content: ''; position: absolute; inset: 0; z-index: -1;
            background: #fff;
            border-top-left-radius: 10px; border-bottom-left-radius: 10px;
        }
        /* La lineetta del carico: la cella e' alta 1 FTE, la linea sta
           al livello del carico assegnato quel giorno (rossa oltre 1). */
        /* Il livello del carico e' un LIQUIDO: sotto la linea la cella
           e' lucida (velo chiaro), sopra resta opaca com'e'. La linea
           grigia e' il pelo del liquido; rossa se il carico supera 1. */
        .table-cal td .cg {
            position: absolute; left: 0; right: 0; bottom: 0;
            border-top: 1.5px solid #B9BAC0;
            background: linear-gradient(180deg, rgba(255,255,255,0.55), rgba(255,255,255,0.30));
            pointer-events: none;
        }
        .table-cal td .cg.cg-over { border-top-color: #D70015; }
        /* IL TRIANGOLO DELLA GIORNATA INCOMPLETA. Sta nell'angolo in alto a
           destra della cella e non copre il codice del giorno: e' un
           avvertimento, non un'informazione al posto di un'altra. Ha
           `pointer-events: auto` perche' e' l'unica cosa cliccabile dentro
           una cella che ha gia' un suo onclick — il click sul triangolo apre
           la correzione, quello sulla cella la timbratura. */
        .table-cal td .cella-incompleta {
            position: absolute; top: 1px; right: 2px;
            font-size: .62rem; line-height: 1;
            color: #D70015; text-shadow: 0 0 2px rgba(255,255,255,0.9);
            pointer-events: auto; cursor: pointer; z-index: 3;
        }
        /* ── Modalita' progetto: i compagni si SOLLEVANO dal tabellone ──
           Le righe di chi sta sul progetto restano piene e prendono il
           colore del progetto (barra sul nome, quote sui giorni); tutte
           le altre sfumano. Si esce dal banner o con Esc. */
        .prj-dim, .prj-dim td { opacity: 0.28; transition: opacity 300ms; }
        /* La stecca si INTERROMPE dove la persona non e' sul progetto:
           fuori dagli stint la cella si spegne, e riprende al tratto dopo. */
        .prj-lift td.prj-off { opacity: 0.16; }
        .prj-lift td.prj-on { box-shadow: inset 0 -2px 0 var(--prj-col, #095373); }
        .prj-lift td.sticky-col::before { box-shadow: inset 3px 0 0 var(--prj-col, #095373); }
        .prj-lift td.sticky-col, .prj-lift td { transition: opacity 300ms; }
        .prj-q {
            position: absolute; right: 2px; bottom: 1px;
            font-size: 8.5px; font-weight: 700; font-style: normal;
            color: var(--prj-col, #095373); pointer-events: none; line-height: 1;
        }
        .prj-l {
            position: absolute; left: 0; right: 0; bottom: 0;
            border-top: 2px solid var(--prj-col, #095373);
            pointer-events: none; opacity: .85;
        }
        #prjBanner {
            position: fixed; top: 16px; left: 50%; transform: translateX(-50%);
            z-index: 1300; background: #fff;
            border: 1.5px solid var(--prj-col, #095373);
            border-radius: 999px; padding: 8px 10px 8px 16px; font-size: .84rem; font-weight: 600;
            box-shadow: 0 16px 44px -10px rgba(8, 24, 37, 0.45);
            display: flex; align-items: center; gap: 9px;
            animation: prj-cala 420ms cubic-bezier(.2, .8, .25, 1);
        }
        @keyframes prj-cala {
            from { transform: translate(-50%, -160%); opacity: 0; }
        }
        #prjBanner .prj-esci {
            border: 1px solid var(--prj-col, #095373); background: var(--prj-col, #095373);
            color: #fff; font-weight: 700; font-size: .78rem;
            border-radius: 999px; padding: 3px 12px; line-height: 1.2;
        }
        .tab-carico-pop {
            position: fixed; z-index: 1200; width: 272px;
            background: #fff; border: 0.5px solid var(--hig-linea);
            border-radius: 12px; padding: 12px 14px; font-size: .78rem;
            box-shadow: 0 18px 50px -12px rgba(8, 24, 37, 0.35);
        }

        /* carta bianca anche sulle altre colonne fisse della riga progetto */
        
        
        
        

        /* La colonna di OGGI corre ininterrotta dalla testata ai dati. */
        
        /* Il bianco della cella OGGI vale solo per la riga delle date: nelle
           righe dei valori renderebbe i numeri invisibili sul fondo chiaro. */
        
        
        
        
        
        .matrix-table thead th.th-delta.oggi-col.delta-alert { color: var(--hig-rosso) !important; }
        .matrix-table thead th.th-liberi.oggi-col.lib-vuoto { color: transparent !important; }

        /* Stato del numero di progetto: viola = intento da coprire,
           verde = coperto dalle persone (o somma delle persone, senza budget). */
        .val-text.stato-viola { color: #8944AB !important; font-weight: 700; }
        .val-text.stato-verde { color: var(--hig-verde) !important; font-weight: 700; }

        .delta-ok { color: var(--hig-verde) !important; }
        .delta-warn { color: #B25000 !important; }
        .delta-alert { color: var(--hig-rosso) !important; }
        .lib-si { color: var(--hig-verde) !important; }
        .lib-zero { color: var(--hig-testo3) !important; }
        .lib-over { color: var(--hig-rosso) !important; }

        /* ═══ TOTALI IN NEGATIVO ═══════════════════════════════════════════
           Le quattro righe AVAIL/NEED/DELTA/NON ASSEGNATI sono TOTALI, non
           dati: blocco-card unico in negativo (fondo scuro, testi chiari),
           angolo anteriore tondo e canale di stacco come le card progetto. */
        
        /* SINGOLE (Massimo 10/8/26): ogni riga dei totali e' una card a se'.
           REGOLA DURA: nelle tabelle border-collapse i BORDI non viaggiano
           con le celle sticky (restano nel layout: finestre trasparenti al
           passaggio dei progetti). Quindi canali e ombre stanno DENTRO le
           celle, come fasce di sfondo: quelle si incollano per definizione. */
        .matrix-table thead th.th-avail, .matrix-table thead th.th-avail.m-col-1,
        .matrix-table thead th.th-avail.m-col-2, .matrix-table thead th.th-avail.m-col-3,
        .matrix-table thead th.th-need, .matrix-table thead th.th-need.m-col-1,
        .matrix-table thead th.th-need.m-col-2, .matrix-table thead th.th-need.m-col-3,
        .matrix-table thead th.th-delta, .matrix-table thead th.th-delta.m-col-1,
        .matrix-table thead th.th-delta.m-col-2, .matrix-table thead th.th-delta.m-col-3,
        .matrix-table thead th.th-liberi, .matrix-table thead th.th-liberi.m-col-1,
        .matrix-table thead th.th-liberi.m-col-2, .matrix-table thead th.th-liberi.m-col-3 {
            border: 0 !important;
        }
        /* UNA SOLA RICETTA per tutte e quattro (Massimo: spessori diversi a
           video): stessa altezza, stessa fascia, non POSSONO differire.
           Il canale sopra il gruppo sta nel fondo della riga date. */
        .matrix-table thead th.th-avail { top: 68px !important; height: 40px; }
        .matrix-table thead th.th-need { top: 108px; height: 40px; }
        .matrix-table thead th.th-delta { top: 148px; height: 40px; }
        .matrix-table thead th.th-liberi { top: 188px; height: 40px; }
        
        /* le due testate sono CARD anche loro: carta bianca, ombra nel
           proprio fondo, angolo anteriore tondo (Massimo 10/8/26) */
        .matrix-table thead tr:nth-child(2) th.th-day, .matrix-table thead th.th-etic {
            background: linear-gradient(180deg, #FBFBFD 0 calc(100% - 10px), #999CA5 calc(100% - 10px), #C9CBD0 calc(100% - 5px), #E4E4E8 calc(100% - 1px)) !important;
            height: 44px; padding-top: 2px !important; padding-bottom: 2px !important;
            vertical-align: middle;
        }
        /* FIX 10/8/26: tinte PIATTE. Questi due selettori arrivano a (5,3) e
           battevano i fondi piatti del blocco card in fondo: nella riga DATA e
           in CLIENTE/PROGETTO le celle normali erano piatte e quelle di OGGI e
           dei festivi tenevano ancora la fascia-ombra finta da 10px. Due
           materiali nella stessa riga. L'ombra ora la fa la box-shadow vera. */
        .matrix-table thead tr:nth-child(2) th.th-day.oggi-col, .matrix-table thead th.th-etic.oggi-col {
            background: var(--hig-tint) !important;
        }
        .matrix-table thead tr:nth-child(2) th.th-day.col-festa:not(.oggi-col), .matrix-table thead th.th-etic.col-festa:not(.oggi-col) {
            background: #F0EDEB !important;
        }
        /* il campo unico DATA: sticky largo quanto le tre colonne fisse */
        .matrix-table thead th.th-data {
            position: sticky; left: 0; z-index: 16 !important;
            /* 336 = 108+132+96, la somma VERA delle tre colonne fisse.
               Era 330 (vecchia geometria 120+120+90): la linguetta restava
               6px piu' stretta della campata che deve coprire. */
            min-width: 336px; max-width: 336px; width: 336px;
            text-align: center !important; vertical-align: middle;
            font-size: 0.72rem; font-weight: 700; letter-spacing: 1.4px;
            color: var(--hig-testo3) !important;
            background: linear-gradient(180deg, #E4E4E8 0 calc(100% - 10px), #999CA5 calc(100% - 10px), #C9CBD0 calc(100% - 5px), #E4E4E8 calc(100% - 1px)) !important;
        }
        
        /* angolo tondo anche sull'etichetta CLIENTE e testi centrati */
        
        
        .matrix-table thead th.th-etic.m-col-1, .matrix-table thead th.th-etic.m-col-2,
        .matrix-table thead th.th-etic.m-col-3 {
            text-align: center !important; vertical-align: middle;
            font-size: 0.72rem; font-weight: 600; letter-spacing: 0.4px;
            color: var(--hig-testo2, #3C3C43) !important;
        }
        /* LA TESTATA VINCE SEMPRE: le colonne sticky dei progetti hanno z 22
           e coprivano etichette e totali al passaggio (CLIENTE/PROGETTO
           'scomparivano', lo scoperto affiorava sopra AVAIL). Giorni a 25,
           colonne fisse della testata a 30. */
        .matrix-table thead th.th-day, .matrix-table thead th.th-avail, .matrix-table thead th.th-need,
        .matrix-table thead th.th-delta, .matrix-table thead th.th-liberi { z-index: 25 !important; }
        .matrix-table thead th.th-data,
        .matrix-table thead th.th-etic.m-col-1, .matrix-table thead th.th-etic.m-col-2, .matrix-table thead th.th-etic.m-col-3,
        .matrix-table thead th.th-avail.m-col-1, .matrix-table thead th.th-avail.m-col-2, .matrix-table thead th.th-avail.m-col-3,
        .matrix-table thead th.th-need.m-col-1, .matrix-table thead th.th-need.m-col-2, .matrix-table thead th.th-need.m-col-3,
        .matrix-table thead th.th-delta.m-col-1, .matrix-table thead th.th-delta.m-col-2, .matrix-table thead th.th-delta.m-col-3,
        .matrix-table thead th.th-liberi.m-col-1, .matrix-table thead th.th-liberi.m-col-2, .matrix-table thead th.th-liberi.m-col-3 {
            z-index: 30 !important;
        }
        /* angoli anteriori: doppio strato nella cella sticky, come le card */
        /* il fondale sta NELLO SFONDO della cella (niente ::after: su queste
           sticky di thead il secondo pseudo non renderizza affidabile).
           Fasce a STOP verticali come nelle altre celle, cosi' l'ombra
           corre sotto TUTTA la card, moncone tondo compreso. */
        
        /* riga etichette/date CLIENTE-PROGETTO: sta SOTTO i totali, attaccata
           ai progetti; e' un CLONE della testata superiore (stesse classi
           th-day), cambia solo l'attacco sticky */
        /* FIX 10/8/26: z-index 25/30 come TUTTA l'altra testata. Erano rimasti
           a 14/16, cioe' SOTTO il 22 delle colonne fisse del corpo: scorrendo,
           CLIENTE/PROGETTO spariva sotto le righe progetto — proprio il bug che
           il commento qui sopra dichiara risolto. Il 'top' e' indicativo:
           lo riscrive impilaTestate misurando le altezze vere. */
        
        
        /* le celle dei totali NON devono crescere oltre le altezze dichiarate:
           il padding le gonfiava e le card si accavallavano da ferme
           (avail piu' fina, delta fusa con la vicina) */
        .matrix-table thead th.th-avail, .matrix-table thead th.th-avail.m-col-1,
        .matrix-table thead th.th-avail.m-col-2, .matrix-table thead th.th-avail.m-col-3,
        .matrix-table thead th.th-need, .matrix-table thead th.th-need.m-col-1,
        .matrix-table thead th.th-need.m-col-2, .matrix-table thead th.th-need.m-col-3,
        .matrix-table thead th.th-delta, .matrix-table thead th.th-delta.m-col-1,
        .matrix-table thead th.th-delta.m-col-2, .matrix-table thead th.th-delta.m-col-3,
        .matrix-table thead th.th-liberi, .matrix-table thead th.th-liberi.m-col-1,
        .matrix-table thead th.th-liberi.m-col-2, .matrix-table thead th.th-liberi.m-col-3 {
            padding-top: 0 !important; padding-bottom: 0 !important;
            line-height: 1.1 !important;
        }
        
        
        
        
        
        /* la carta scura si ritira dalle fasce-canale (DEVE stare dopo la
           base inset:0, o viene riazzerata); l'ombra sta nel fondale ::after */
        
        /* testi chiari, in famiglia coi colori semantici delle righe */
        .matrix-table thead th.th-avail, .matrix-table thead th.th-avail.m-col-2, .matrix-table thead th.th-avail.m-col-3,
        .matrix-table thead th.th-avail.oggi-col { color: #9BD8F0 !important; }
        .matrix-table thead th.th-need, .matrix-table thead th.th-need.m-col-2, .matrix-table thead th.th-need.m-col-3,
        .matrix-table thead th.th-need.oggi-col { color: #FFA895 !important; }
        .matrix-table thead th.th-delta, .matrix-table thead th.th-delta.m-col-2, .matrix-table thead th.th-delta.m-col-3,
        .matrix-table thead th.th-delta.oggi-col { color: #DFE8EE !important; }
        .matrix-table thead th.th-liberi, .matrix-table thead th.th-liberi.m-col-2, .matrix-table thead th.th-liberi.m-col-3,
        .matrix-table thead th.th-liberi.oggi-col { color: #8FE3B8 !important; }
        .matrix-table thead th.th-delta.delta-ok, .matrix-table thead th.th-delta.oggi-col.delta-ok { color: #7FD8A6 !important; }
        .matrix-table thead th.th-delta.delta-warn { color: #FFB570 !important; }
        .matrix-table thead th.th-delta.delta-alert, .matrix-table thead th.th-delta.oggi-col.delta-alert { color: #FF8E80 !important; }
        .matrix-table thead th.th-liberi.lib-zero { color: rgba(255,255,255,0.38) !important; }
        .matrix-table thead th.th-liberi.lib-over { color: #FF8E80 !important; }
        .matrix-table thead th.th-liberi.lib-vuoto, .matrix-table thead th.th-liberi.oggi-col.lib-vuoto { color: transparent !important; }
        /* festivi dentro il negativo: scuro un filo piu' chiaro, non beige */
        
        /* la colonna di OGGI nel negativo: tinta PIENA piu' chiara (un velo
           trasparente comporrebbe sul bianco della pagina, non sul blocco) */
        
        .matrix-table thead th.th-avail.oggi-col, .matrix-table thead th.th-need.oggi-col,
        .matrix-table thead th.th-delta.oggi-col, .matrix-table thead th.th-liberi.oggi-col {
            box-shadow: inset 1px 0 0 rgba(255,255,255,0.4), inset -1px 0 0 rgba(255,255,255,0.4) !important;
        }

        /* ═══ LINGUETTA DEL PROGETTO APERTO ════════════════════════════════
           Aperta, la card non si spezza: la riga progetto e' il tetto (angolo
           alto tondo), le sottorighe persone proseguono la stessa carta coi
           fianchi continui, e l'ultima riga (assegna persona) chiude col
           fondo tondo. Un'unica linguetta, come da schizzo di Massimo. */
        /* Corpo RIENTRATO (schizzo di Massimo): sotto il tetto la colonna
           CLIENTE torna canale, la carta riprende dal bordo dei nomi. */
        /* fianco del corpo PULITO: l'ombra la fa il TETTO, non il corpo
           (Massimo: freccia verde e 'no', 10/8/26) */
        
        
        
        
        /* niente filo colorato sul fianco: seguendo l'angolo tondo diventava
           un archetto scuro — l'ennesima 'riga sottile' (Massimo 10/8/26) */
        
        /* Il PIEDE: 'assegna persona' NON e' una riga — e' solo la linguetta
           del bottone. Tutto il resto della riga sparisce nel canale: niente
           striscia bianca di fianco, niente celle vuote lungo i giorni. */
        /* sotto il corpo la fascia porta l'ombra DELLA linguetta: morbida,
           lunga, mai un filo (frecce rosse di Massimo, 10/8/26) */
        /* FIX 10/8/26: canale piatto. Questo selettore e' (4,2) e batteva il
           '#E4E4E8 !important' (2,2) del blocco card: sotto il corpo restava
           la vecchia sfumatura d'ombra dipinta, che ora ha per padrone la
           box-shadow vera dell'ultima riga persone. */
        
        /* il piede non ha NESSUN bordo: la fascia e' canale, non una riga */
        
        .matrix-table tr.riga-aggiungi > td { padding-top: 4px !important; padding-bottom: 4px !important; }
        /* niente ombra sulla colonna cliente della fascia: sopra c'e' canale
           aperto, non il corpo — un'ombra li' era una riga senza padrone */
        
        
        
        /* ATTENZIONE: .m-col-2 ha overflow:hidden — la carta DEVE stare nei
           212px della cella, o viene mozzata (gola destra sparita, 10/8/26) */
        
        /* due GOLE, una per lato: il piede e' piu' stretto del corpo */
        /* niente GOLE sul piede (Massimo 10/8/26: 'non hanno senso'). Il
           fondale del piede e' canale liscio: l'ombra del corpo qui la
           porta la box-shadow VERA dell'ultima riga, che sconfina libera. */
        
        
        /* l'ultima riga del corpo (scoperto, o l'ultima persona) chiude tonda
           sul gradino che il piede lascia scoperto, senza hairline che taglia */
        /* STESSA TECNICA DEL PIEDE (intuizione di Massimo: 'la' e' venuta
           bene, cosa cambia?'): ombra VERA che segue l'arco da sola, niente
           mosaici di gradienti che si spaccano sui bordi cella. Su queste
           due celle l'overflow:hidden non serve (testi corti, no ellipsis)
           e va aperto, o l'ombra viene ghigliottinata. */
        .matrix-table tr.riga-persona:has(+ tr.riga-aggiungi) > td.m-col-2,
        .matrix-table tr.riga-aggiungi > td.m-col-2 { overflow: visible; }
        
        
        /* niente righine grigie sotto l'ultima riga del corpo: il bordo della
           carta chiude da solo, l'hairline sporcava (rosso di Massimo) */
        

        /* ARIA dal riquadro (2mm): le linguette non toccano il bordo della card */
        
        .matrix-table tr.riga-progetto > td.m-col-1 { padding-left: 16px !important; }
        /* il tetto, piu' largo del corpo, riprende il suo angolo basso tondo */
        
        /* la GOLA della linguetta: raccordo concavo dove il tetto incontra il
           corpo rientrato. Un quarto di cerchio dipinto nel primo rigo persone:
           dentro l'arco il canale, fuori la carta che scende dal tetto. */
        /* NIENTE gola fra tetto e corpo (Massimo 10/8/26): sono due elementi
           diversi e il raccordo li fonderebbe. Li separa un'OMBRA: il tetto
           del progetto copre la squadra, come le card coprono il canale. */
        /* l'ombra del tetto cade sulla CARTA della squadra, non sulla
           colonnina di canale: li' faceva un angolino sporco (puntini verdi) */
        
        
        /* niente ombra sul fianco sinistro del tetto (Massimo: 'no'):
           resta solo quella di testata, che e' delle card sopra */
        /* il tetto aperto non ha hairline sotto (correva fino al bordo
           dell'area, attraversando aria e canale) e la sua carta sticky
           proietta un'ombra VERA che segue l'angolo tondo da sola */
        
        .matrix-table tr.riga-progetto.aperta > td.m-col-1 { overflow: visible; }
        
        /* niente hairline sotto l'ultima riga: chiude il canale, non una riga */
        
        .lib-vuoto { color: transparent !important; }
        /* FIX 10/8/26: l'anello di OGGI vale per il tabellone presenze e per
           l'overlay dei grafici, NON per la matrix-table. Come '.oggi-col'
           nudo aveva specificita' (1,0) ma !important, e batteva tutte le
           box-shadow del blocco card (che !important non ce l'hanno): la
           colonna di oggi perdeva l'ombra e prendeva un anellino per cella,
           bucando la fila di card. Nella griglia oggi si segna con la tinta. */
        .table-cal .oggi-col, div.oggi-col { box-shadow: inset 0 0 0 1px var(--hig-tint) !important; }

        /* ── Origami: testata chiara anche qui ── */
        .asg-testata { background: rgba(255,255,255,0.92); color: var(--hig-testo);
                       backdrop-filter: blur(20px); border-bottom: 0.5px solid var(--hig-linea); }
        .asg-testata .tit p { color: var(--hig-testo2); opacity: 1; }
        .asg-testata .chiudi { color: var(--hig-testo2); }
        .asg-periodo label { color: var(--hig-testo3); }
        .asg-periodo input { background: var(--hig-card); border: 0.5px solid var(--hig-linea-forte); color: var(--hig-testo); }
        .asg-kpi span { color: var(--hig-testo3); }
        .asg-kpi.rosso b { color: var(--hig-rosso); } .asg-kpi.verde b { color: var(--hig-verde); }
        .asg-stage { background: var(--hig-bg); }
        /* Hover sulla tessera: si solleva e si avvicina (+22%), con ombra */
        .asg-tess { transition: transform 220ms cubic-bezier(.2,.8,.25,1), box-shadow 220ms; }
        .asg-tess:hover {
            transform: scale(1.22); z-index: 40; position: relative;
            box-shadow: 0 18px 40px -10px rgba(8, 24, 37, 0.35);
        }
        /* Il grafico MP del progetto resta IN VISTA mentre si scorre */
        #asgWrapProg {
            position: sticky; top: 0; z-index: 45;
            background: var(--hig-bg); padding-top: 4px;
        }
        .asg-tess { border: 0.5px solid var(--hig-linea); }
        /* LE TRE FAMIGLIE DELLA CLASSIFICA. Prima erano tre livelli di verde
           soli (.asg-disp-1/2/3), dati da soglie assolute sul margine. Adesso
           il colore E' la posizione in classifica: verde la meta' migliore,
           giallo l'altra, rosso chi nel tratto e' gia' al 100% almeno un
           giorno. Il tono 0 e' sempre il piu' intenso della sua famiglia.
           Gli stessi colori stanno in ASG_FASCE dentro admin.html — li' per i
           badge e i bottoni, qui per il contorno della card: chi li cambia li
           cambia in tutti e due i posti, e tests/test_planning_punto3.py
           controlla che le nove classi esistano. */
        .asg-f-verde  { background: #F2FBF7 !important; }
        .asg-f-giallo { background: #FDF9EE !important; }
        .asg-f-rosso  { background: #FDF1F2 !important; }
        .asg-f-verde-0 { outline: 2.5px solid #0F6E56 !important; box-shadow: 0 12px 28px -10px rgba(15,110,86,.5); }
        .asg-f-verde-1 { outline: 2px solid #1D9E75 !important; box-shadow: 0 8px 20px -10px rgba(29,158,117,.4); }
        .asg-f-verde-2 { outline: 1.5px dashed #5DCAA5 !important; }
        .asg-f-giallo-0 { outline: 2.5px solid #7A5600 !important; box-shadow: 0 12px 28px -10px rgba(122,86,0,.45); }
        .asg-f-giallo-1 { outline: 2px solid #9E7100 !important; box-shadow: 0 8px 20px -10px rgba(158,113,0,.35); }
        .asg-f-giallo-2 { outline: 1.5px dashed #C08A00 !important; }
        .asg-f-rosso-0 { outline: 2.5px solid #8E0410 !important; box-shadow: 0 12px 28px -10px rgba(142,4,16,.45); }
        .asg-f-rosso-1 { outline: 2px solid #C21020 !important; box-shadow: 0 8px 20px -10px rgba(194,16,32,.35); }
        .asg-f-rosso-2 { outline: 1.5px dashed #E05561 !important; }
        .asg-badge-lib {
            position: absolute; top: 6px; right: 6px; z-index: 3;
            font-size: .58rem; font-weight: 700; color: #fff;
            border-radius: 999px; padding: 2px 7px; letter-spacing: .02em;
        }
        .asg-tess { position: relative; }
        #asgSelBar {
            position: sticky; top: 0; z-index: 46; margin: 0 0 8px;
            background: #E9F7F1; border: 1px solid #1D9E75; border-radius: 10px;
            padding: 7px 12px; font-size: .78rem; display: flex; align-items: center; gap: 10px;
        }
        .asg-tess-viva {
            transform: scale(1.12) !important; position: relative; z-index: 35;
            box-shadow: 0 14px 30px -8px rgba(8, 24, 37, 0.3);
            outline: 1.5px solid #095373;
        }
        .asg-tess:hover { box-shadow: 0 8px 24px rgba(0,0,0,0.08); border-color: var(--hig-linea-forte); }
        .asg-tess.dentro { border: 1.5px solid var(--hig-tint); background: #fff; }
        .asg-tess .badge-dentro { background: var(--hig-tint); }
        .asg-foglio { box-shadow: 0 12px 48px rgba(0,0,0,0.18); border: 0.5px solid var(--hig-linea); }
        .asg-of-chiudi { background: var(--hig-testo); }
        .asg-btn { background: var(--hig-tint); border-radius: 10px; }
        .asg-btn:hover { background: #0A628A; }
        .asg-btn.togli { color: var(--hig-rosso); border-color: rgba(215,0,21,0.3); }
        .asg-sofferenza.male { color: var(--hig-ambra); }
        .asg-sofferenza.ok { color: var(--hig-verde); }

        /* ── Vista colleghi: palette Salute-like, quieta ── */
        .pub-pres  { background: #E8F6EC; color: var(--hig-verde); }
        .pub-smart { background: #E9F2F8; color: var(--hig-tint); }
        .pub-miss  { background: #FBEFE3; color: var(--hig-ambra); }
        .pub-ass   { background: #F2F2F4; color: var(--hig-testo3); }

        /* ── Minuterie ── */
        .alert { border: 0.5px solid var(--hig-linea) !important; border-radius: 12px; box-shadow: none !important; }
        .badge { font-weight: 600; }
        .cop-ok   { background: #E8F6EC; color: var(--hig-verde); }
        .cop-parz { background: #FBEFE3; color: var(--hig-ambra); }
        .cop-zero { background: #FCE9EB; color: var(--hig-rosso); }
        ::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.18); }
        ::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.3); }
        .modal-content { border-radius: 16px !important; border: 0.5px solid var(--hig-linea) !important; }
        .modal-header { background: #fff !important; color: var(--hig-testo) !important;
                        border-bottom: 0.5px solid var(--hig-linea) !important; }
        .modal-header * { color: var(--hig-testo) !important; }

        /* ── Mobile: tocchi da 44px come da HIG ── */
        @media (max-width: 768px) {
            .btn, .form-control, .form-select { min-height: 44px; }
            .nav-item-dan { color: var(--hig-testo3); }
            .nav-item-dan.active { color: var(--hig-tint) !important; }
            .nav-item-dan.active .nav-icon { color: var(--hig-tint) !important; opacity: 1; }
        }
    
        /* IL CAMPO CHE LA LETTURA LOCALE NON HA RICAVATO. Sta nella revisione
           TISAR, e serve a dire DOVE guardare: un modulo di dodici caselle
           tutte uguali non lo dice, e chi rivede quindici documenti di fila
           smette di leggerle. Bordo e sfondo, non solo il bordo: su uno
           schermo poco contrastato il solo bordo sparisce. */
        .dan-campo-mancante {
            border: 2px solid #D70015 !important;
            background: #FFF6F5 !important;
        }
        .dan-campo-mancante:focus {
            box-shadow: 0 0 0 .2rem rgba(215, 0, 21, 0.15) !important;
        }
