/* ============================================================================
   BACK-OFFICE - guscio (LayoutBackoffice), elenchi ed entita'.
   Direzione "Blueprint Tecnico" (ADR-0006) portata sulla densita' interna (D83):
   rail navy + top-bar (D114), tabelle dense con scroll orizzontale (D115),
   schede entita' a due colonne (D116) e storico append-only a timeline.
   Decisioni D114-D123 / ADR-0012. I VALORI vengono dai token (tokens.css);
   qui solo composizione. Assorbe i fogli provvisori gestione-utenti.css (.gestione,
   S2.2) e audit.css (.registro-audit, S2.3): primitive ora generiche e DRY.
   ============================================================================ */

/* ===========================================================================
   1. GUSCIO - rail navy + top-bar (D114). App-shell a piena altezza: top-bar e
   rail restano fissi, solo il contenuto scorre. Sotto la soglia desktop il guscio
   torna a flusso normale e la rail diventa una barra orizzontale (zero JS, D85).
   =========================================================================== */
.bo {
  --bo-rail-larghezza: 232px;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  display: grid;
  grid-template-columns: var(--bo-rail-larghezza) minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas:
    "topbar topbar"
    "rail   main";
  background: var(--neutral-50);
}

.bo-topbar { grid-area: topbar; }
.bo-main {
  grid-area: main;
  min-width: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--space-6);
  /* Colonna flex: un elenco (.elenco) puo' prendere tutta l'altezza e far scorrere solo le
     righe; le altre pagine (schede, form) restano in flusso e, se sono piu' alte, scorre
     il main come prima (i figli flex non scendono sotto il proprio contenuto). */
  display: flex;
  flex-direction: column;
}

/* ---- Rail di navigazione (superficie scura) ---- */
.bo-rail {
  grid-area: rail;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-4) var(--space-3);
  background: var(--rail-bg);
  border-right: var(--border-width) solid var(--rail-bordo);
}
.bo-rail__sezione {
  margin: var(--space-4) var(--space-3) var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--fw-medium);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--rail-testo-muto);
}
.bo-rail__sezione:first-child { margin-top: 0; }
.bo-rail__voce {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 36px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  border-left: 2px solid transparent;
  color: var(--rail-testo);
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  transition: background-color var(--motion-fast), color var(--motion-fast);
}
/* Selettore qualificato con "a" (non solo la classe): deve pareggiare la specificita' di
   `a:not(.btn):hover` in base.css, altrimenti quella regola vince e il testo in hover diventa
   --primary-600 (blu medio, illeggibile sul rail scuro). A parita' di specificita' vince
   l'ordine di caricamento: backoffice.css arriva dopo base.css. */
a.bo-rail__voce:hover { background: var(--rail-hover-bg); color: var(--rail-attivo-testo); }
.bo-rail__voce[aria-current="page"] {
  background: var(--rail-attivo-bg);
  color: var(--rail-attivo-testo);
  border-left-color: var(--rail-attivo-barra);
}
.bo-rail__voce svg { flex: none; width: 18px; height: 18px; opacity: .82; }
.bo-rail__voce[aria-current="page"] svg { opacity: 1; }

/* ===========================================================================
   1-bis. SCALA DEI TITOLI - due soli gradini, rapporto 1.25 (D83).
   Il back-office distingue il titolo HERO (home e scheda di un'entita': la pagina
   parla di UNA cosa e la nomina) dal titolo di PAGINA (elenchi e form: la pagina e'
   uno strumento). Il gradino piu' grande porta la crenatura piu' stretta: a corpo
   grande la spaziatura normale apre il titolo e gli toglie compattezza.
   =========================================================================== */
/* Hero e' anche il default del back-office: un h1 senza classe e' quasi sempre il nome
   di cio' che la pagina mostra. Le testate di elenco/form lo riportano al gradino di
   pagina piu' sotto (stessa specificita', vince l'ordine). */
.bo h1,
.bo .titolo-hero,
/* Il gradino hero della scala (variante "decisa"): la scheda di un'entita' e il cruscotto della
   home, cioe' i due titoli che aprono una schermata invece di intestare un elenco. */
.scheda-identita h1,
.cruscotto-testata h1 {
  font-size: var(--text-3xl);
  line-height: var(--leading-3xl);
  letter-spacing: var(--tracking-titolo-hero);
  color: var(--neutral-900);
}
.bo .titolo-pagina,
.elenco-testata__titolo h1,
.scheda-testata__titolo h1 {
  font-size: var(--text-2xl);
  line-height: var(--leading-2xl);
  letter-spacing: var(--tracking-titolo);
  color: var(--neutral-900);
}

/* ===========================================================================
   2. ELENCO - testata, barra filtri, tabella densa, paginazione, stati (D117-D122)
   =========================================================================== */
/* ---- Elenco a piena altezza: la pagina sta nel 100% del main e l'unica cosa che scorre sono
   le righe dentro .tabella-wrap (thead sticky). Testata, toolbar e piede di paginazione restano
   sempre visibili. Min-height sulla card: su finestre bassissime l'elenco non si schiaccia a
   zero, e a quel punto e' il main a scorrere (fallback). ---- */
.elenco {
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.elenco > .tabella-card {
  /* 0 1 auto: con poche righe la card resta alta quanto il contenuto (niente bordo che
     incornicia il vuoto); si restringe solo quando le righe supererebbero lo schermo.
     Nessun min-height qui: con una riga sola lascerebbe vuoto fra righe e piede. */
  flex: 0 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  margin-bottom: 0;
}
.elenco > .tabella-card > .tabella-wrap {
  flex: 0 1 auto;
  min-height: 0;
  max-height: none;
}
/* Floor solo quando c'e' davvero da scorrere (almeno 4 righe): su finestre bassissime restano
   visibili ~4 righe e a quel punto scorre il main (fallback). Con 1-3 righe nessun minimo,
   altrimenti il vuoto finirebbe fra le righe e il piede. */
.elenco > .tabella-card > .tabella-wrap:has(tbody tr:nth-child(4)) { min-height: 10rem; }
.elenco > .tabella-card > .paginazione { flex: none; }

/* Titolo di elenco affiancato dall'icona (i) di aiuto in-app (InfoPopover): l'help ricco vive nel
   popover al click, non piu' in un paragrafo sempre-visibile sotto la testata. */
.elenco-titolo { display: flex; align-items: center; gap: var(--space-2); }

/* ---- Testata: titolo + sottotitolo + azioni ---- */
.elenco-testata {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}
/* Il corpo del titolo arriva dalla scala dei titoli (sezione 1-bis). */
.elenco-testata__titolo p {
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--neutral-500);
}
.elenco-testata__azioni { display: inline-flex; gap: var(--space-3); flex-wrap: wrap; }

/* ---- Selettore a pillole (D187): resta una nav a round-trip GET con aria-current, niente
   role=tab (la tastiera a frecce che prometterebbe non c'e', ADR-0013); e' lo stile a farlo
   leggere come "scegli una vista" invece che come link sparsi. Pillole staccate e non a bordi
   collassati: la pillola attiva e' piena e va riconosciuta come un oggetto a se', e senza
   margini negativi non serve piu' rialzare hover e attiva con z-index. Scroll orizzontale su
   stretto (D115) e MAI overflow:hidden: taglierebbe l'anello di focus. Il padding del
   contenitore e' proprio lo spazio che l'anello richiede (overflow-x:auto implica
   overflow-y:auto, quindi l'anello verrebbe rifilato sopra e sotto). ---- */
.segmented {
  /* Figlio di .elenco (flex column): con overflow-x:auto il min-height implicito e' 0 e la nav
     verrebbe schiacciata (pillole tagliate) quando le righe superano lo schermo. Mai restringere. */
  flex: none;
  display: flex;
  gap: var(--space-1);
  overflow-x: auto;
  padding: 2px;
  margin: -2px -2px var(--space-5);
}
.segmented__voce {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--pad-controllo-y) var(--space-4);
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  /* Altezza esplicita: senza conteggio (Requisiti) la pillola collasserebbe sul line box
     di Inter, col conteggio mono (Pratiche) si alzerebbe. Stessa altezza ovunque. */
  line-height: 1.5;
  min-height: 2.25rem;
  color: var(--neutral-600);
  background: var(--neutral-0);
  text-decoration: none;
  white-space: nowrap;
  border: var(--border-default);
  border-radius: var(--radius-md);
  transition: background-color var(--motion-fast), color var(--motion-fast), border-color var(--motion-fast);
}
.segmented__voce:hover { background: var(--neutral-100); color: var(--neutral-800); }
.segmented__voce[aria-current="page"] {
  background: var(--primary-700);
  border-color: var(--primary-700);
  color: var(--neutral-0);
  font-weight: var(--fw-semibold);
}
/* Il colore va ridichiarato in hover: `a:not(.btn):hover` (base.css) porterebbe il testo a
   --primary-600, cioe' lo stesso blu del fondo della pillola attiva, e l'etichetta sparirebbe. */
.segmented__voce[aria-current="page"]:hover {
  background: var(--primary-600);
  border-color: var(--primary-600);
  color: var(--neutral-0);
}
/* Quante righe ci sono dietro ogni pillola: mono tabellare, subordinato all'etichetta.
   Il numero e' un'anteprima del filtro, non l'etichetta stessa. */
.segmented__conteggio {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  opacity: .7;
}

/* Link di ritorno (dalla scheda all'elenco). Non e' un'azione ma una briciola di posizione: porta
   il nome dell'elenco da cui si arriva, non l'imperativo "torna a", e sta smorzato finche' non lo
   si punta. Il chevron e' un glifo di direzione, non una freccia di navigazione: il posto e' li'
   accanto, non un passo indietro nella storia del browser. */
.bo-ritorno {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-bottom: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--fw-medium);
  color: var(--neutral-500);
  text-decoration: none;
}
.bo-ritorno:hover { color: var(--primary-700); }
.bo-ritorno svg { flex: none; width: 12px; height: 12px; }

/* ---- Barra dei filtri di un elenco: una riga leggera, non un riquadro. Restringere una
   vista e' un gesto reversibile e lo stato vive nell'URL (D119): non merita la stessa cornice
   di un modulo. Il riquadro resta a .filtri (sotto), che nei cataloghi e' anche il contenitore
   dei moduli inline di creazione/modifica — li' la cornice dice "qui si scrive". ---- */
.toolbar {
  /* Un'altezza sola per tutti i controlli della riga: campi, gruppi etichettati, pastiglie
     e bottoni hanno scatole diverse (padding, bordi, contenuti) e senza un'altezza dichiarata
     si allineerebbero ognuno per conto suo. Ancorata alla densita', come il resto della scala. */
  --h-filtro: calc(var(--root-size) * 2.5);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.toolbar .campo { margin-bottom: 0; }
/* Il min-height 44px del bottone (D67) lo renderebbe piu' alto degli altri controlli. */
.toolbar .btn { min-height: 0; height: var(--h-filtro); line-height: var(--leading-base); }

/* ---- Barra dei filtri: UN oggetto, non N controlli affiancati. Restringono tutti la stessa
   vista, e i divisori dicono "stesso strumento, criteri diversi" invece di lasciare indovinare
   il rapporto fra scatole vicine. Nessun overflow:hidden per il raggio: taglierebbe l'anello di
   focus dei segmenti agli estremi; i due terminali si arrotondano da soli. ---- */
.filtro-barra {
  display: flex;
  align-items: stretch;
  flex: 1 1 40rem;
  max-width: 58rem;
  height: var(--h-filtro);
  background: var(--neutral-0);
  border: var(--border-strong);
  border-radius: var(--radius-md);
}
/* Barra a un solo controllo (la scelta del file di log): si stringe sul contenuto invece di
   tirarsi su 40rem lasciando mezza riga vuota. */
.filtro-barra--stretta { flex: 0 1 auto; }
.filtro-barra__sep {
  flex: none;
  width: 1px;
  align-self: stretch;
  background: var(--border-color);
}

/* Ricerca: la lente dice "cerca" senza spendere una label visibile (la label resta,
   nascosta, per il lettore di schermo) e il campo si prende lo spazio che avanza. */
.filtro-barra__cerca {
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
}
.filtro-barra__cerca > svg {
  flex: none;
  width: 15px;
  height: 15px;
  margin-left: var(--space-3);
  color: var(--neutral-400);
}
/* I campi dentro la barra sono nudi: la scatola la porta la barra. */
.filtro-barra input[type="search"] {
  height: 100%;
  font-size: var(--text-sm);
  color: var(--neutral-900);
  background: transparent;
  border: 0;
  border-radius: var(--radius-md);
}
.filtro-barra input[type="search"]:focus { outline-offset: calc(-1 * var(--ring-focus-width)); }
.filtro-barra__cerca input { width: 100%; padding: 0 var(--space-3) 0 var(--space-2); }
/* La partita IVA e' un numero da confrontare a colpo d'occhio: mono tabellare, e larghezza
   fissa perche' le cifre sono sempre undici. */
.filtro-barra__piva {
  flex: none;
  width: 9.5rem;
  padding: 0 var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
}

/* Elenco lungo dentro la barra (i 52 tipi di evento dell'audit, i file di log): resta un
   <select> nativo. La regola "un filtro non e' un <select>" vale per i criteri che hanno un
   linguaggio visivo proprio - gli stati, che vanno mostrati coi Badge veri - non per un elenco
   di nomi, dove il controllo nativo porta gratis scorrimento, tastiera e type-ahead che un
   menu di 52 collegamenti non avrebbe. Nudo come gli altri controlli: la scatola la fa la barra. */
.filtro-barra__select {
  flex: none;
  max-width: 15rem;
  height: 100%;
  padding: 0 var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  color: var(--neutral-700);
  background: transparent;
  border: 0;
}
.filtro-barra__select:focus-visible { outline-offset: calc(-1 * var(--ring-focus-width)); }

/* Periodo: due date sono un criterio solo, e le due paroline lo dicono meglio di due campi
   affiancati muti ("Dal ... al ..."). Le date sono mono tabellari come la partita IVA. */
.filtro-barra__periodo {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding-inline: var(--space-2);
  font-size: var(--text-xs);
  color: var(--neutral-500);
  white-space: nowrap;
}
.filtro-barra__data {
  flex: none;
  height: 100%;
  padding: 0 var(--space-1);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--neutral-900);
  background: transparent;
  border: 0;
}
.filtro-barra__data:focus-visible { outline-offset: calc(-1 * var(--ring-focus-width)); }

/* Segmento con menu: il trigger si accende quando il suo menu e' aperto. `:has` legge lo
   stato del popover senza una riga di JS. */
.filtro-barra__segmento { display: flex; }
.filtro-barra__scelta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 100%;
  padding: 0 var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  color: var(--neutral-700);
  background: transparent;
  border: 0;
  white-space: nowrap;
  transition: background-color var(--motion-fast), color var(--motion-fast);
}
.filtro-barra__scelta:hover { background: var(--neutral-100); }
.filtro-barra__segmento:has([popover]:popover-open) .filtro-barra__scelta {
  background: var(--primary-50);
  color: var(--primary-700);
}
.filtro-barra__scelta:focus-visible { outline-offset: calc(-1 * var(--ring-focus-width)); }
.filtro-barra__scelta > svg { flex: none; width: 13px; height: 13px; color: var(--neutral-400); }
.filtro-barra__valore { color: var(--neutral-600); }

/* Interruttore in coda alla barra: casella disegnata + etichetta, con la casella vera
   nascosta al solo occhio (non a display:none, che la toglierebbe anche al focus). */
.filtro-barra__spunta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 100%;
  padding: 0 var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  color: var(--neutral-600);
  white-space: nowrap;
  cursor: pointer;
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  transition: background-color var(--motion-fast), color var(--motion-fast);
}
.filtro-barra__spunta:hover { background: var(--neutral-100); }
.filtro-barra__box {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  background: var(--neutral-0);
  border: var(--border-strong);
  border-radius: 3px;
  transition: background-color var(--motion-fast), border-color var(--motion-fast);
}
.filtro-barra__box svg { width: 9px; height: 9px; color: var(--neutral-0); opacity: 0; }
.filtro-barra__casella:checked + .filtro-barra__spunta {
  background: var(--primary-50);
  color: var(--primary-700);
}
.filtro-barra__casella:checked + .filtro-barra__spunta .filtro-barra__box {
  background: var(--primary-700);
  border-color: var(--primary-700);
}
.filtro-barra__casella:checked + .filtro-barra__spunta .filtro-barra__box svg { opacity: 1; }
.filtro-barra__casella:focus-visible + .filtro-barra__spunta {
  outline: var(--ring-focus-width) solid var(--ring-focus-color);
  outline-offset: calc(-1 * var(--ring-focus-width));
}

/* ---- Menu di un filtro: piu' minuto del menu di azioni, perche' e' un elenco di valori da
   scorrere, non di comandi da leggere. La spunta chiude la riga a destra e dice quale criterio
   e' attivo senza affidarsi al solo sfondo evidenziato (mai colore da solo, D64). ---- */
.menu--filtro { width: auto; min-width: 11rem; }
.menu--stati { min-width: 13rem; }
/* Righe piu' serrate del menu di azioni: qui si scorre un elenco di valori a colpo d'occhio,
   non si leggono comandi. Il target da 36px del menu di azioni (D67) qui non serve: le voci
   sono poche e tutte adiacenti. */
.menu--filtro .menu__voce { gap: var(--space-2); min-height: 30px; padding: var(--space-1) var(--space-2); }
.menu__spunta { flex: none; width: 13px; height: 13px; margin-left: auto; color: var(--primary-700); }

/* Rimozione dei filtri: compare solo quando c'e' qualcosa da rimuovere, staccata dalla barra
   da un divisore perche' non e' un altro criterio ma cio' che li annulla tutti. */
.toolbar__stacco {
  flex: none;
  width: 1px;
  height: calc(var(--h-filtro) * .55);
  background: var(--border-color);
  margin-inline: var(--space-1);
}
.toolbar__azzera {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  color: var(--neutral-600);
  text-decoration: none;
  white-space: nowrap;
  border-radius: var(--radius-md);
}
.toolbar__azzera:hover { background: var(--neutral-100); color: var(--neutral-800); }
.toolbar__azzera svg { flex: none; width: 12px; height: 12px; }

/* Spinge a destra cio' che segue (il conteggio dei risultati). */
.toolbar__spazio { flex: 1 1 auto; }
.toolbar__conteggio {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--neutral-500);
  white-space: nowrap;
}

/* Export CSV accanto al conteggio (#214): bottone compatto a icona + testo, mai schiacciato dalla
   riga flex (niente shrink, niente a-capo), icona a misura del testo e freccia che scende al
   passaggio, come il primario la fa avanzare. */
.toolbar__esporta {
  flex: none;
  gap: var(--space-2);
  padding-inline: var(--space-3) var(--space-4);
  white-space: nowrap;
  text-decoration: none;
}
.toolbar__esporta svg { flex: none; width: 16px; height: 16px; }
.toolbar__esporta:hover svg { transform: translateY(2px); }

/* ---- Barra filtri a riquadro / modulo inline dei cataloghi (D119) ---- */
.filtri {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
  padding: var(--space-4);
  background: var(--neutral-50);
  border: var(--border-default);
  border-radius: var(--radius-md);
}
.filtri .campo { margin-bottom: 0; }
.filtri__cerca { flex: 1 1 16rem; }
.filtri select.campo__input { min-width: 11rem; }
/* Forza un a-capo nella riga flex: raggruppa i campi che seguono su una nuova riga logica
   (es. un'area di testo o un cluster di campi correlati in un modulo con piu' campi di
   Codice/Descrizione, come Tipi documento). */
.filtri__riga { flex-basis: 100%; }

/* Campo con un flag booleano: casella e etichetta sulla stessa riga (form del catalogo documentale). */
.campo--flag { display: flex; align-items: center; gap: var(--space-2); }
.campo--flag label { margin: 0; font-size: var(--text-sm); color: var(--neutral-700); }
/* Il bottone "Filtra" si allinea in altezza ai campi del filtro: senza, il min-height 44px del
   bottone lo rende piu' alto degli input (stessa padding e interlinea -> stessa altezza). */
.filtri .btn { min-height: 0; line-height: var(--leading-base); }

/* ---- Contenitore con scroll orizzontale per le tabelle larghe (D115) ----
   Bound dell'altezza: con `overflow-x: auto` il browser calcola anche `overflow-y: auto`,
   quindi il wrap diventa il contenitore di scroll a cui si ancora il thead sticky; senza
   un'altezza massima non scorrerebbe mai in verticale e lo sticky resterebbe inerte (ux 5).
   Limitando l'altezza, l'header resta incollato mentre le righe scorrono dentro il wrap. */
.tabella-wrap {
  overflow: auto;
  max-height: calc(100dvh - 13rem);
  border: var(--border-default);
  background: var(--neutral-0);
}

/* ---- Elenco in card: la tabella e la sua paginazione stanno DENTRO un contenitore
   bordato e arrotondato, cosi' l'elenco legge come un oggetto solo invece che come una
   griglia seguita da due bottoni sciolti.
   Il raggio NON puo' vivere sul contenitore di scroll: `overflow:hidden` lo simulerebbe
   ma spegnerebbe il thead sticky (ux 5, vedi .tabella-wrap). Si arrotondano quindi gli
   angoli reali — le celle d'angolo del thead e il piede — che e' l'unica ricetta che
   tiene insieme le due cose. ---- */
.tabella-card {
  background: var(--neutral-0);
  border: var(--border-default);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-5);
}
/* Dentro la card il bordo lo porta la card: quello del wrap raddoppierebbe la linea.
   Vale anche per .matrice (ruoli x permessi), che ha bordo e raggio propri quando sta da sola. */
.tabella-card > .tabella-wrap { border: 0; }
.tabella-wrap > .matrice { border: 0; border-radius: 0; }
.tabella-card :is(.tabella, .matrice) thead th:first-child { border-top-left-radius: var(--radius-md); }
.tabella-card :is(.tabella, .matrice) thead th:last-child { border-top-right-radius: var(--radius-md); }
/* Senza piede (elenco non paginato) e' l'ultima riga a chiudere la card. */
.tabella-card > .tabella-wrap:last-child :is(.tabella, .matrice) tbody tr:last-child td:first-child { border-bottom-left-radius: var(--radius-md); }
.tabella-card > .tabella-wrap:last-child :is(.tabella, .matrice) tbody tr:last-child td:last-child { border-bottom-right-radius: var(--radius-md); }

/* Tabella larga (molte colonne): larghezza minima oltre cui scrolla nel wrap.
   In classe (non inline) per non violare la guardia anti-style della CSP (D111). */
.tabella--larga { min-width: 56rem; }

/* Tabella stretta (aside a 20rem, Cadenze): celle a padding ridotto, intestazioni libere di
   andare a capo e nome/codice impilati nella prima cella, cosi' la tabella sta nella colonna
   senza scroll orizzontale; resta `overflow:auto` sul wrap come rete di sicurezza. */
.tabella.tabella--compatta thead th { white-space: normal; padding-inline: var(--space-3); }
.tabella.tabella--compatta tbody td { padding-inline: var(--space-3); }
.tabella.tabella--compatta .col-azioni { padding-inline-start: var(--space-1); }
.tabella.tabella--compatta td .principale { display: block; }
.tabella.tabella--compatta td .principale + .mono { display: block; margin-top: 1px; }

/* ---- Tabella densa. Bordi netti (niente raggio): il border-radius non si rende
   sulle tabelle border-collapse e l'overflow che lo simula spegnerebbe il thead
   sticky (ux 5). Gli angoli vivi rafforzano il "disegno tecnico" (ADR-0006);
   le card e i controlli mantengono il raggio. La tabella avvolta lascia il bordo
   al contenitore .tabella-wrap. ---- */
.tabella {
  width: 100%;
  border-collapse: collapse;
  background: var(--neutral-0);
  border: var(--border-default);
}
.tabella-wrap > .tabella { border: 0; }
/* Intestazioni in mono maiuscolo spaziato, come l'occhiello: sono etichette di struttura,
   non testo da leggere. La mono le separa nettamente dai dati sans della riga e le tiene
   riconoscibili anche quando restano incollate in cima allo scroll. */
.tabella thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  text-align: left;
  padding: var(--space-2) var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--neutral-500);
  background: var(--neutral-50);
  border-bottom: var(--border-default);
  white-space: nowrap;
}
.tabella tbody td {
  padding: var(--pad-riga-y) var(--space-4);
  font-size: var(--text-sm);
  color: var(--neutral-700);
  border-bottom: var(--border-default);
  vertical-align: middle;
}
.tabella tbody tr:last-child td { border-bottom: none; }
.tabella tbody tr { transition: background-color var(--motion-fast); }
.tabella tbody tr:hover { background: var(--neutral-100); }
/* Colonna azioni: larghezza-contenuto (width:1%) e cluster icone serrato a destra, coerente su
   tutti gli elenchi (cataloghi e /utenti). */
.tabella .col-azioni { width: 1%; text-align: right; white-space: nowrap; }
.tabella .col-azioni .azioni-riga { justify-content: flex-end; flex-wrap: nowrap; gap: var(--space-1); }
/* Cluster di badge nella cella Stato (#103): stato piu' eventuali indicatori (Monitorato, Note). */
.tabella .stato-riga { display: inline-flex; align-items: center; flex-wrap: wrap; gap: var(--space-1); }
/* Il tooltip CSS (.btn--tooltip::after, components.css) e' centrato sul bottone: la colonna azioni
   e' serrata a destra (justify-content:flex-end), quindi il tooltip centrato di QUALSIASI icona del
   cluster (non solo l'ultima) sporge oltre il bordo destro di .tabella-wrap anche da invisibile
   (opacity:0), gonfiando lo scrollWidth (overflow:auto) e mostrando una scrollbar orizzontale
   fantasma anche su tabelle strette. Riancorato col bordo destro allineato a quello del proprio
   bottone (right:0, cresce verso sinistra): ogni bottone e' dentro la tabella, quindi nessun
   tooltip aggiunge scroll orizzontale. Vale per tutte le icone della colonna, non solo l'ultima. */
.tabella .col-azioni .btn--tooltip::after {
  left: auto;
  right: 0;
  transform: none;
}
/* ---- Cella d'identita': il nome e, sotto, i codici che lo identificano. Recupera due
   colonne (P.IVA, CF) senza perdere l'informazione: la riga si scandaglia per nome, e i
   codici restano dove servono davvero, cioe' accanto al nome che qualificano. ---- */
.cella-doppia__nome {
  display: block;
  font-weight: var(--fw-semibold);
  color: var(--neutral-900);
}
.cella-doppia__sotto {
  display: block;
  margin-top: 1px;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--neutral-500);
}

.tabella td .principale { font-weight: var(--fw-medium); color: var(--neutral-800); }
.tabella td .secondario { color: var(--neutral-500); font-size: var(--text-xs); }
/* Codici e identificativi in mono funzionale (D63): P.IVA, protocolli, istanti, IP. */
.tabella .mono {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--neutral-600);
  white-space: nowrap;
}
/* Valore assente o attore non identificato: tono attenuato ma leggibile (AA). */
.testo-muto { color: var(--neutral-500); }

/* Celle con piu' colonne dense impilano in alto (registro audit). */
.tabella--alto tbody td { vertical-align: top; }

/* ---- Intestazione ordinabile (link GET, aria-sort, zero JS: D118) ---- */
.tabella th .ordina {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: inherit;
  text-decoration: none;
  letter-spacing: inherit;
}
.tabella th .ordina:hover { color: var(--neutral-700); }
.tabella th .ordina::after {
  content: "";
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  opacity: .35;
  transform: rotate(45deg);
}
.tabella th[aria-sort="ascending"] .ordina::after { opacity: .9; transform: rotate(-135deg); }
.tabella th[aria-sort="descending"] .ordina::after { opacity: .9; transform: rotate(45deg); }

/* ---- Dettagli non-PII in chip etichetta/valore (registro audit) ---- */
.dettagli-chip { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-2); }
.dettaglio-chip { font-size: var(--text-xs); color: var(--neutral-700); }
.dettaglio-chip__k { color: var(--neutral-500); font-weight: var(--fw-medium); }

/* ---- Paginazione server-side (D120) ---- */
.paginazione {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-5);
  font-size: var(--text-sm);
  color: var(--neutral-500);
}
.paginazione__controlli { display: inline-flex; gap: var(--space-2); }
/* Quanto c'e' e dove sei: mono tabellare, perche' e' un conteggio che cambia sotto gli occhi
   da una pagina all'altra e le cifre devono restare incolonnate. */
.paginazione__conteggio {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}
/* Variante a piede di card (dentro .tabella-card): la paginazione non e' piu' una riga
   sciolta sotto la tabella ma la chiude, sullo stesso fondo tenue del thead. */
.paginazione--piede {
  margin-top: 0;
  padding: var(--space-2) var(--space-4);
  background: var(--neutral-50);
  border-top: var(--border-default);
  border-bottom-left-radius: var(--radius-md);
  border-bottom-right-radius: var(--radius-md);
}

/* ---- Stato vuoto: distingue il vuoto positivo dal vuoto da riempire (D122) ----
   Tre toni, perche' "non c'e' niente" ha tre significati diversi e l'operatore deve capire
   subito quale: `positivo` = hai finito, non c'e' nulla in attesa di te; `filtro` = i criteri
   non pescano nulla, allargali; `da-riempire` = qui non e' mai stato messo niente, comincia tu.
   L'icona porta il tono, il testo porta il significato. ---- */
.elenco-vuoto {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-12) var(--space-6);
  text-align: center;
  color: var(--neutral-500);
  background: var(--neutral-0);
  border: var(--border-default);
  border-radius: var(--radius-md);
}
.elenco-vuoto__icona {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin-bottom: var(--space-2);
  border-radius: var(--radius-full);
  background: var(--neutral-100);
  color: var(--neutral-500);
}
.elenco-vuoto__icona svg { width: 20px; height: 20px; }
.elenco-vuoto--positivo .elenco-vuoto__icona { background: var(--success-bg); color: var(--success); }
.elenco-vuoto--filtro .elenco-vuoto__icona { background: var(--info-bg); color: var(--info); }
.elenco-vuoto__titolo {
  font-size: var(--text-md);
  font-weight: var(--fw-semibold);
  color: var(--neutral-800);
}
.elenco-vuoto__corpo {
  max-width: 44ch;
  font-size: var(--text-sm);
  color: var(--neutral-500);
}
/* Variante compatta: l'entita' non esiste (link stantio, id a mano). Non e' un elenco vuoto —
   non c'e' una vista da riempire ne' un filtro da allargare — quindi non merita la stessa
   presenza in pagina: e' una constatazione, e sta in una riga. */
.elenco-vuoto--compatto { padding: var(--space-6); }

/* ===========================================================================
   3. SCHEDA ENTITA' - header + corpo a due colonne + sezioni (D116/D121)
   =========================================================================== */
.scheda { width: 100%; }
/* Scheda a colonna stretta per le pagine-form (invito, editor a campo singolo):
   un form non deve stirarsi su tutta la larghezza del back-office. */
.scheda--stretta { max-width: 44rem; }

/* Niente filetto sotto la testata: il titolo e cio' che lo riassume (striscia, tab, prima card)
   sono la stessa cosa vista da vicino e da lontano, e una riga li dividerebbe in due pagine.
   L'allineamento e' `flex-end` come nel mock: il cluster delle azioni si posa sulla riga meta,
   non in cima al titolo hero. */
.scheda-testata {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.scheda-testata__titolo { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.scheda-testata__azioni { display: inline-flex; gap: var(--space-3); flex-wrap: wrap; }

/* Corpo: colonna principale + aside sticky a destra. */
.scheda-corpo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 400px;
  gap: var(--space-4);
  align-items: start;
}
/* Senza colonna di contesto la seconda traccia non va lasciata vuota: sarebbe 20rem di niente
   accanto a una timeline che ne avrebbe bisogno. */
.scheda-corpo--pieno { grid-template-columns: minmax(0, 1fr); }
.scheda-main { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.scheda-aside {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  position: sticky;
  top: var(--space-5);
}

/* ---- Sezione (card bordata) ----
   Anatomia del mock "Nuova UI": guscio senza padding + banda di testata + corpo. Il titolo non e'
   una riga di testo piu' grande dentro la card ma la sua *intestazione*: mono maiuscola minuta su
   fondo pieno, separata dal corpo da un filetto. E' la stessa grammatica del `thead` di
   `.tabella-card` e dell'`.occhiello` degli elenchi — una card e' un oggetto etichettato, e
   l'etichetta non compete col contenuto.

   Il corpo non ha un contenitore proprio: il padding lo prendono i figli diretti, cosi' le 8 pagine
   che usano `.scheda-sezione` non cambiano una riga di markup. Chi deve andare a filo dei bordi
   (`.dati`, `.checklist`) lo dichiara annullando il margine — vedi sotto. ---- */
.scheda-sezione {
  background: var(--neutral-0);
  border: var(--border-default);
  border-radius: var(--radius-md);
  /* Fa combaciare gli angoli della banda e delle righe a filo col raggio della card. Innocuo:
     qui dentro non c'e' nulla di sticky (i popover vivono nel top layer, non nel flusso). */
  overflow: hidden;
}
.scheda-sezione > h2 {
  /* Flex e non block: la (i) di InfoPopover e i badge di stato stanno sulla riga del titolo. */
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  padding: 10px var(--space-4);
  background: var(--neutral-50);
  border-bottom: var(--border-width) solid var(--neutral-100);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--fw-medium);
  line-height: var(--leading-sm);
  letter-spacing: var(--tracking-occhiello);
  text-transform: uppercase;
  color: var(--neutral-600);
}
/* Cio' che nella banda sta a destra del titolo (conteggio, badge di stato): lo stacco lo fa uno
   spaziatore elastico, non un `justify-content` — il titolo puo' avere la (i) attaccata. */
.scheda-sezione > h2 .scheda-sezione__spazio { flex: 1; }
/* Pastiglie e bottoni nella banda restano oggetti propri: non ereditano il mono maiuscolo del titolo. */
.scheda-sezione > h2 :is(.badge, .btn) { font-family: var(--font-sans); letter-spacing: normal; text-transform: none; }
.scheda-sezione > h2 .scheda-sezione__conteggio {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  letter-spacing: normal;
  text-transform: none;
  color: var(--neutral-500);
}

/* Il corpo: padding sui figli diretti (nessun wrapper nel markup) e ritmo verticale fra blocchi. */
.scheda-sezione > :not(h2) { margin-inline: var(--space-5); }
.scheda-sezione > :not(h2):first-child { margin-block-start: var(--space-5); }
.scheda-sezione > h2 + :not(h2) { margin-block-start: var(--space-5); }
.scheda-sezione > :not(h2) + :not(h2) { margin-block-start: var(--space-4); }
.scheda-sezione > :not(h2):last-child { margin-block-end: var(--space-5); }

/* A filo dei bordi: le liste che portano i propri divisori di riga. Un margine laterale le
   staccherebbe dal bordo della card e i filetti finirebbero a mezz'aria. */
.scheda-sezione > :is(.dati, .checklist) { margin: 0; }
.scheda-sezione > .checklist { border-inline: 0; border-block-start: 0; border-radius: 0; }
.scheda-sezione > .checklist:last-child { border-block-end: 0; }
/* Il titolo di gruppo della checklist prende il ritmo della card e non il suo margine storico:
   `.checklist-gruppo:first-of-type { margin-top: 0 }` nasceva quando il titolo della sezione era
   testo dentro il padding — sotto una banda a filetto incollerebbe il primo gruppo alla riga. */
.scheda-sezione > .checklist-gruppo { margin-block: 0; }
.scheda-sezione > h2 + .checklist-gruppo { margin-block-start: var(--space-5); }
.scheda-sezione > :not(h2) + .checklist-gruppo { margin-block-start: var(--space-4); }

.scheda-sezione > p.aiuto {
  font-size: var(--text-sm);
  color: var(--neutral-500);
}
/* aiuto.css definisce un .aiuto a tutta altezza (il guscio delle pagine guida); nel back-office
   .aiuto e' una riga di aiuto sotto un campo o una sezione. Si confina quella collisione qui, cosi'
   un p.aiuto resta una riga di testo e non un blocco a tutta finestra. */
.bo p.aiuto {
  display: block;
  min-height: 0;
  background: none;
  font-size: var(--text-sm);
  color: var(--neutral-500);
}

/* Coppie etichetta/valore (metadati). */
.dati {
  display: grid;
  grid-template-columns: minmax(8rem, max-content) 1fr;
  gap: var(--space-2) var(--space-5);
  font-size: var(--text-sm);
}
.dati dt { color: var(--neutral-500); }
/* La (i) resta sulla riga dell'etichetta: nella colonna destra (22rem) la colonna dei dt viene
   compressa e un bottone inline andrebbe a capo da solo, leggendosi come un secondo dato. In flex
   e' l'etichetta a mandare a capo il testo, l'icona non si stacca mai. */
.dati dt:has(.aiuto-info) { display: flex; align-items: baseline; gap: var(--space-1); }
.dati dt .aiuto-info { flex: none; }
.dati dd { color: var(--neutral-800); font-weight: var(--fw-medium); }
/* Email e collegamenti lunghi: in una card stretta un indirizzo non spezzabile sfonda il bordo. */
.dati dd :is(.ent, .contatto) { overflow-wrap: anywhere; }
.dati dd.mono { font-family: var(--font-mono); font-weight: var(--fw-regular); letter-spacing: .02em; }

/* ---- .dati dentro una card: righe, non coppie sparse. Con la banda di testata la card e' un
   piccolo elenco chiave/valore, e un elenco si legge se le righe sono separate: il filetto dice
   dove finisce un dato e dove comincia il successivo. Il filetto e' piu' chiaro di quello della
   banda — divide dentro lo stesso blocco, non due parti della card. ---- */
.scheda-sezione > .dati {
  grid-template-columns: 150px minmax(0, 1fr);
  gap: 0;
}
.scheda-sezione > .dati > :is(dt, dd) {
  padding: 9px var(--space-4);
  border-block-end: var(--border-width) solid color-mix(in srgb, var(--neutral-100) 60%, var(--neutral-0));
}
/* L'ultima riga non porta il filetto: sotto c'e' gia' il bordo della card. */
.scheda-sezione > .dati > dt:last-of-type,
.scheda-sezione > .dati > dd:last-of-type { border-block-end: 0; }

/* Nella colonna di contesto (20rem) due colonne non ci stanno: l'etichetta va sopra il valore e
   diventa mono maiuscola minuta, come le chiavi della striscia. Niente filetti — i campi di una
   card di contesto sono pochi e il divisore li farebbe sembrare una tabella. */
.scheda-aside .scheda-sezione > .dati {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.scheda-aside .scheda-sezione > .dati > dt {
  padding: var(--space-3) var(--space-4) 0;
  border-block-end: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--tracking-occhiello);
  text-transform: uppercase;
  line-height: var(--leading-xs);
  color: var(--neutral-500);
}
.scheda-aside .scheda-sezione > .dati > dd {
  padding: var(--space-1) var(--space-4) 0;
  border-block-end: 0;
}
.scheda-aside .scheda-sezione > .dati > dd:last-of-type { padding-block-end: var(--space-4); }

/* Gruppo di azioni (ogni azione e' un form SSR). */
.azioni-riga { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.azioni-riga form { display: inline-flex; margin: 0; }

/* Righe ruolo (toggle assegna/revoca). */
.ruoli-lista { display: flex; flex-direction: column; gap: var(--space-2); }
.ruolo-riga {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-2) var(--space-3);
  border: var(--border-default);
  border-radius: var(--radius-sm);
}
.ruolo-riga[data-assegnato="true"] { background: var(--primary-50); border-color: color-mix(in srgb, var(--primary-700) 25%, var(--neutral-200)); }
.ruolo-riga__nome { font-size: var(--text-sm); font-weight: var(--fw-medium); color: var(--neutral-800); }
.ruolo-riga__nome small { display: block; font-weight: var(--fw-regular); color: var(--neutral-500); }

/* ---- Cruscotto della Home: testata hero, tre misure, griglia delle funzioni ----
   La home non e' una pagina di benvenuto ma il primo sguardo della giornata: dice cosa aspetta
   un'azione prima di dire dove si va. ---- */
.cruscotto { width: 100%; max-width: 74rem; }
.cruscotto-testata { margin-bottom: var(--space-6); }
.cruscotto-testata p { margin-top: var(--space-2); max-width: 56ch; color: var(--neutral-600); }
/* L'occhiello "Le tue funzioni" non e' la testata di pagina: gli serve aria sopra, non sotto. */
.cruscotto > .occhiello { margin-bottom: var(--space-2); }

/* Le misure. Tre colonne finche' ci stanno; sotto, una sola: una misura mezza tagliata non si
   legge a colpo d'occhio, che e' l'unica cosa che le si chiede. */
.kpi {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}
.kpi__card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-4) var(--space-4);
  background: var(--neutral-0);
  border: var(--border-default);
  /* Il filetto in cima porta il tono: e' l'unico punto colorato della card, cosi' tre misure
     affiancate si distinguono prima di leggerle. Spessore in cima e non tutto attorno per non
     trasformare "c'e' da lavorare" in un allarme. */
  border-top: 3px solid var(--neutral-300);
  border-radius: var(--radius-md);
  text-decoration: none;
  transition: border-color var(--motion-fast), box-shadow var(--motion-fast);
}
.kpi__card:hover { border-color: var(--neutral-400); box-shadow: var(--elev-1); }
.kpi__card--attesa { border-top-color: var(--warning); }
.kpi__card--allarme { border-top-color: var(--danger); }
/* Zero: la misura resta, il tono si spegne. Il numero in grigio dice "niente da fare" senza una
   parola in piu' - ed e' il caso in cui la card NON deve tirare l'occhio. */
.kpi__card--quieto { border-top-color: var(--neutral-300); }
.kpi__etichetta {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--tracking-occhiello);
  text-transform: uppercase;
  color: var(--neutral-500);
}
.kpi__misura { display: flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap; }
.kpi__numero {
  font-family: var(--font-mono);
  font-size: var(--text-3xl);
  font-weight: var(--fw-medium);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--neutral-900);
}
.kpi__card--quieto .kpi__numero { color: var(--neutral-400); }
.kpi__unita { font-size: var(--text-sm); color: var(--neutral-600); }
.kpi__nota { font-size: var(--text-xs); color: var(--neutral-500); }
.kpi__card--attesa .kpi__nota { color: var(--warning-text); }
.kpi__card--allarme .kpi__nota { color: var(--danger-text); }

/* Le funzioni: un blocco solo con divisori a un pixel (il fondo si vede attraverso il gap della
   griglia), non N riquadri sciolti. Qui l'overflow:hidden e' innocuo - non c'e' niente di sticky
   dentro - ed e' cio' che fa combaciare gli angoli delle celle col raggio del blocco. */
.funzioni {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  gap: var(--border-width);
  margin-bottom: var(--space-6);
  background: var(--border-color);
  border: var(--border-default);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.funzioni__voce {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--neutral-0);
  text-decoration: none;
  transition: background-color var(--motion-fast);
}
.funzioni__voce:hover { background: var(--neutral-50); }
.funzioni__icona {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: var(--radius-md);
  background: var(--primary-50);
  color: var(--primary-700);
}
.funzioni__icona svg { width: 16px; height: 16px; }
.funzioni__testo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.funzioni__nome { font-size: var(--text-sm); font-weight: var(--fw-semibold); color: var(--neutral-800); }
.funzioni__descrizione { font-size: var(--text-xs); color: var(--neutral-500); }
.funzioni__freccia {
  flex: none;
  width: 16px;
  height: 16px;
  color: var(--neutral-300);
  transition: transform var(--motion-fast), color var(--motion-fast);
}
.funzioni__voce:hover .funzioni__freccia { transform: translateX(2px); color: var(--primary-700); }
@media (prefers-reduced-motion: reduce) {
  .funzioni__voce:hover .funzioni__freccia { transform: none; }
}

/* ---- Avvio rapido (#96): le destinazioni come righe-link, in colonna. Nato sulla Home, che ora
   ha la griglia delle funzioni; resta l'indice delle utility di supporto. ---- */
.avvio { display: flex; flex-direction: column; gap: var(--space-2); margin: var(--space-5) 0; }
.avvio__voce {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--neutral-0);
  border: var(--border-default);
  border-radius: var(--radius-md);
  text-decoration: none;
  transition: border-color var(--motion-fast), background-color var(--motion-fast);
}
.avvio__voce:hover { border-color: var(--neutral-400); background: var(--neutral-50); }
.avvio__testo { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.avvio__nome { font-size: var(--text-md); font-weight: var(--fw-semibold); color: var(--primary-700); }
.avvio__descrizione { font-size: var(--text-sm); color: var(--neutral-600); }
.avvio__freccia { flex: none; color: var(--neutral-400); transition: transform var(--motion-fast), color var(--motion-fast); }
.avvio__voce:hover .avvio__freccia { transform: translateX(2px); color: var(--primary-700); }
@media (prefers-reduced-motion: reduce) {
  .avvio__voce:hover .avvio__freccia { transform: none; }
}

/* ===========================================================================
   4. MATRICE (ruolo x permesso) - tabella di toggle
   =========================================================================== */
.matrice {
  width: 100%;
  border-collapse: collapse;
  background: var(--neutral-0);
  border: var(--border-default);
  border-radius: var(--radius-md);
}
.matrice th, .matrice td {
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  border-bottom: var(--border-default);
  text-align: left;
}
/* Sticky come il thead della tabella: dentro il wrap la matrice scorre, e i nomi dei permessi
   devono restare leggibili mentre si cerca la cella giusta. */
.matrice thead th { position: sticky; top: 0; z-index: 1; background: var(--neutral-50); color: var(--neutral-600); font-weight: var(--fw-semibold); border-bottom: var(--border-strong); }
.matrice tbody tr:last-child td { border-bottom: none; }
.matrice td.cella-permesso { text-align: center; }
.matrice .ruolo-nome { font-weight: var(--fw-medium); color: var(--neutral-800); }
.matrice form { margin: 0; }

.toggle-permesso {
  min-width: 7.5rem;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: .03em;
}
.toggle-permesso[data-concesso="true"] { color: var(--success-text); border-color: color-mix(in srgb, var(--success) 45%, var(--neutral-200)); background: var(--success-bg); }
.toggle-permesso[data-bloccato="true"] { opacity: .55; cursor: not-allowed; }

/* ===========================================================================
   5. STORICO - timeline verticale append-only (D116/ADR-0009/0010).
   Nodi quadrati e righello sottile: feel "disegno tecnico" del Blueprint.
   Primitiva del sistema per gli storici di entita' (stati fornitore,
   provvedimenti, revoche) di Sprint 3.
   =========================================================================== */
.storico { display: flex; flex-direction: column; }
.storico__voce {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-3);
  padding-bottom: var(--space-4);
}
.storico__voce:last-child { padding-bottom: 0; }
.storico__marker { position: relative; display: flex; justify-content: center; width: 12px; }
.storico__marker::before {
  content: "";
  position: absolute;
  top: 6px;
  bottom: calc(-1 * var(--space-4));
  width: 2px;
  background: var(--neutral-200);
}
.storico__voce:last-child .storico__marker::before { display: none; }
.storico__nodo {
  position: relative;
  z-index: 1;
  width: 10px;
  height: 10px;
  margin-top: 2px;
  background: var(--neutral-0);
  border: 2px solid var(--primary-700);
  border-radius: 2px;
}
.storico__corpo { min-width: 0; }
.storico__quando {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--neutral-500);
}
.storico__titolo { font-size: var(--text-sm); font-weight: var(--fw-medium); color: var(--neutral-800); }
.storico__dettaglio { font-size: var(--text-xs); color: var(--neutral-500); }

/* ===========================================================================
   6. RESPONSIVE - sotto la soglia desktop il guscio torna a flusso normale e
   la rail collassa in barra orizzontale scorrevole (back-office desktop-first,
   ux-principles 1/4: nessun caso d'uso mobile, ma non si rompe).
   =========================================================================== */
@media (max-width: 880px) {
  .bo {
    height: auto;
    overflow: visible;
    grid-template-columns: 1fr;
    grid-template-rows: auto auto minmax(0, 1fr);
    grid-template-areas:
      "topbar"
      "rail"
      "main";
  }
  .bo-rail, .bo-main { overflow: visible; }
  .bo-rail {
    flex-direction: row;
    gap: var(--space-1);
    overflow-x: auto;
    padding: var(--space-2) var(--space-3);
    border-right: none;
    border-bottom: var(--border-width) solid var(--rail-bordo);
  }
  .bo-rail__sezione { display: none; }
  .bo-rail__voce {
    white-space: nowrap;
    border-left: none;
    border-bottom: 2px solid transparent;
  }
  .bo-rail__voce[aria-current="page"] { border-left-color: transparent; border-bottom-color: var(--rail-attivo-barra); }
  .bo-main { padding: var(--space-5); }
}

@media (max-width: 1024px) {
  .scheda-corpo { grid-template-columns: 1fr; }
  .scheda-aside { position: static; }
}

/* ===========================================================================
   7. SCHEDA ENTITA' RICCA - affinamento (D124-D138 / ADR-0012 esteso).
   Banco di prova: scheda Fornitore. Testata a banda identita', stato primario
   + sotto-stato + banner critico, indice ad ancore, checklist documentale,
   provvedimenti, storico arricchito, menu overflow. I VALORI vengono dai token.
   =========================================================================== */

/* ---- Testata: banda identita' (D125) a sinistra, cluster stato/azioni (D126/D127) a destra.
   La .scheda-testata (sopra) resta il contenitore flex space-between con bordo. ---- */
/* Il titolo dell'entita' e' un titolo hero: il corpo arriva dalla scala (sezione 1-bis). */
.scheda-identita { min-width: 0; }
.scheda-identita__codici {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--neutral-500);
}
.scheda-identita__codici .mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: .02em; color: var(--neutral-700); }
.scheda-identita__codici .sep { color: var(--neutral-300); }

.scheda-cluster { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-3); }
.scheda-stato { display: inline-flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; justify-content: flex-end; }
.scheda-stato__sotto { font-size: var(--text-xs); color: var(--neutral-500); }

/* ---- Tab della scheda entita': sottolineatura, non pillole. Le pillole del `.segmented`
   scelgono un criterio dentro la stessa vista (il tipo fornitore nei requisiti); qui si cambia
   proprio cio' che si sta guardando, e la sottolineatura lo dice restando ancorata al filo che
   separa la testata dal corpo. Nav a round-trip GET con `aria-current`, mai `role=tab`: senza
   JavaScript la semantica di tastiera dei tab (frecce, Home/End) non c'e' (ADR-0013). ---- */
.tab-scheda {
  display: flex;
  gap: 2px;
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
  border-bottom: var(--border-default);
}
.tab-scheda__voce {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 0 13px;
  font-size: var(--text-xs);
  font-weight: var(--fw-medium);
  color: var(--neutral-500);
  text-decoration: none;
  /* Il filetto e' sempre presente e trasparente: al cambio di tab la riga non si sposta di 2px. */
  border-bottom: 2px solid transparent;
  margin-bottom: calc(-1 * var(--border-width));
  transition: color var(--motion-fast), border-color var(--motion-fast);
}
.tab-scheda__voce:hover { color: var(--neutral-800); }
.tab-scheda__voce[aria-current="page"] {
  color: var(--primary-700);
  font-weight: var(--fw-semibold);
  border-bottom-color: var(--primary-700);
}
/* Quanto c'e' dietro il tab, non un badge di allarme: mono minuta e smorzata. */
.tab-scheda__conteggio {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--neutral-400);
}
.tab-scheda__voce[aria-current="page"] .tab-scheda__conteggio { color: var(--primary-700); opacity: .7; }

/* ---- Striscia riassuntiva della scheda: le sei domande a cui rispondere prima di leggere.
   Un oggetto solo con divisori interni, non sei riquadri: sono facce dello stesso fornitore.
   Le colonne si riducono su stretto invece di comprimersi: sei celle da 3rem non si leggono.
   `overflow:hidden` qui e' innocuo - non c'e' niente di sticky dentro - ed e' cio' che fa
   combaciare gli angoli delle celle col raggio della striscia. ---- */
.striscia {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  margin-bottom: var(--space-5);
  background: var(--neutral-0);
  border: var(--border-default);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.striscia__cella {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-4);
  /* Il divisore lo porta la cella, non il gap: cosi' l'ultima di ogni riga non lascia una
     riga di fondo scoperta quando la griglia va a capo. */
  border-inline-end: var(--border-width) solid var(--neutral-100);
}
.striscia__cella:last-child { border-inline-end: 0; }
.striscia__k {
  font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--fw-medium);
    letter-spacing: var(--tracking-meta);
    text-transform: uppercase;
    color: var(--neutral-500);
}
.striscia__v { font-size: var(--text-sm); font-weight: var(--fw-semibold); color: var(--neutral-900); }
/* Il tono della cella dice se quel valore chiede un'azione. Il default e' il testo pieno: e'
   "va bene", non "non ho niente da dire". Il muto e' per il dato che non esiste ancora. */
.striscia__v--ok { color: var(--success-text); }
.striscia__v--attesa { color: var(--warning-text); }
.striscia__v--allarme { color: var(--danger-text); }
.striscia__v--muto { color: var(--neutral-500); font-weight: var(--fw-regular); }
/* La chiave puo' portare la sua (i): l'aiuto sta accanto alla domanda, non accanto alla risposta. */
.striscia__k { display: flex; align-items: center; gap: var(--space-1); }
.striscia__k .aiuto-info { flex: none; }
/* Una cella il cui valore e' un oggetto (badge, interruttore) e non una parola: il valore non
   eredita il peso del testo, se lo porta gia' dentro. */
.striscia__v--oggetto { display: flex; align-items: center; }

/* ---- Interruttore: un bottone di invio vestito da switch (ADR-0013, zero JavaScript).
   Non e' una checkbox: una checkbox senza JavaScript non manda niente, e con il JavaScript che la
   invia al `change` resterebbe accesa mentre il server dice di no. Qui il click e' un POST e lo
   stato lo ridisegna la risposta — quello che si vede e' sempre quello che c'e' a database.
   `role="switch"` + `aria-checked` danno a tastiera e screen reader la stessa promessa. ---- */
.interruttore {
  flex: none;
  display: inline-flex;
  align-items: center;
  width: 34px;
  height: 18px;
  padding: 2px;
  background: var(--neutral-300);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-full);
  transition: background var(--motion-fast);
}
.interruttore::before {
  content: "";
  width: 12px;
  height: 12px;
  background: var(--neutral-0);
  border-radius: var(--radius-full);
  box-shadow: 0 1px 2px rgb(20 32 46 / 25%);
  transition: translate var(--motion-fast);
}
.interruttore[aria-checked="true"] { background: var(--primary-700); }
.interruttore[aria-checked="true"]::before { translate: 16px 0; }
.interruttore:hover { background: color-mix(in srgb, var(--neutral-900) 12%, var(--neutral-300)); }
.interruttore[aria-checked="true"]:hover { background: var(--primary-900); }
/* La parola resta: un interruttore nudo dice "acceso/spento", non *che cosa* e' acceso, e la
   striscia si legge in diagonale per valori, non per forme. */
.interruttore-riga { display: flex; align-items: center; gap: var(--space-2); }
.interruttore-riga form { display: inline-flex; margin: 0; }

/* ---- Banner critico (D126): esclusione attiva o documento bloccante scaduto.
   Piu' forte di .avviso, a tutta larghezza sotto la testata. ---- */
.scheda-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: 11px var(--space-4);
  margin-bottom: var(--space-4);
  border: var(--border-width) solid;
  border-left-width: 3px;
  border-radius: var(--radius-md);
}
.scheda-banner__icona { flex: none; margin-top: 1px; }
.scheda-banner__corpo { flex: 1; min-width: 0; }
.scheda-banner__titolo { font-size: var(--text-xs); font-weight: var(--fw-semibold); }
.scheda-banner__dettaglio { margin-top: 1px; font-size: var(--text-xs); }
/* L'azione del banner e' un bottone bianco nel tono del banner: porta dove la causa si legge. */
.scheda-banner__azione {
  flex: none;
  align-self: center;
  min-height: 26px;
  padding: 0 10px;
  font-size: var(--text-xs);
  font-weight: var(--fw-semibold);
  color: inherit;
  background: var(--neutral-0);
  border: var(--border-width) solid currentColor;
  border-radius: 5px;
  text-decoration: none;
}
.scheda-banner--danger .scheda-banner__azione { border-color: color-mix(in srgb, var(--danger) 45%, var(--danger-bg)); }
.scheda-banner--danger .scheda-banner__azione:hover { background: var(--danger-bg); }
.scheda-banner--danger  { background: var(--danger-bg);  border-color: color-mix(in srgb, var(--danger) 45%, var(--danger-bg));   border-left-color: var(--danger);  color: var(--danger-text); }
.scheda-banner--warning { background: var(--warning-bg); border-color: color-mix(in srgb, var(--warning) 45%, var(--warning-bg)); border-left-color: var(--warning); color: var(--warning-text); }

/* ---- Header di sezione con azione (per l'edit inline a toggle di sezione, D134) ---- */
.scheda-sezione__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-4); }
.scheda-sezione__head h2 { margin-bottom: 0; }
.scheda-sezione__head a { font-size: var(--text-sm); font-weight: var(--fw-medium); }
.scheda-sezione__sintesi { font-size: var(--text-sm); color: var(--neutral-500); }

/* Meta-header della Pratica corrente: chip di contesto sopra la checklist (D129). */
.pratica-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: var(--border-default);
  font-size: var(--text-sm);
  color: var(--neutral-600);
}
.pratica-meta b { color: var(--neutral-800); font-weight: var(--fw-medium); }
.pratica-meta .mono { font-family: var(--font-mono); }

/* ---- Chip: etichette brevi (obbligatorio/facoltativo, ambito, categoria) ---- */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 3px var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--fw-medium);
  line-height: 1.5;
  white-space: nowrap;
  color: var(--neutral-600);
  background: var(--neutral-100);
  border: var(--border-default);
  border-radius: var(--radius-sm);
}
.chip svg { flex: none; width: 13px; height: 13px; }
.chip--obbligatorio { color: var(--primary-700); background: var(--primary-50); border-color: color-mix(in srgb, var(--primary-700) 25%, var(--neutral-200)); }
/* Livello intermedio (D188): contorno pieno ma senza riempimento, tra il ghost di .chip
   e il tinta-piena di --obbligatorio. Niente rosso/ambra: e' uno stato di configurazione,
   non un allarme, e la maggior parte delle righe di una checklist e' spesso obbligatoria. */
.chip--facoltativo { color: var(--primary-700); background: var(--neutral-0); border-color: color-mix(in srgb, var(--primary-700) 35%, var(--neutral-200)); }

/* ---- Recap dei requisiti del tipo attivo (D190): conteggio a colpo d'occhio a piede della
   card dell'elenco, dati gia' in pagina (zero query nuove). Non interattivo: il filtro
   click-per-stato resta un'estensione futura. Stesse icone della colonna Requisito:
   il linguaggio visivo si impara una volta e vale in tutta la pagina. ---- */
.requisiti-recap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
  font-size: var(--text-sm);
  color: var(--neutral-600);
}
/* A piede di card il margine lo porta gia' il piede: il recap chiude la tabella, non precede
   qualcos'altro. */
.requisiti-recap--piede { margin-bottom: 0; font-size: var(--text-xs); }
.requisiti-recap__voce { display: inline-flex; align-items: center; gap: var(--space-1); }
.requisiti-recap__voce:not(:first-child)::before { content: "\00b7"; margin-right: var(--space-4); color: var(--neutral-300); }
.requisiti-recap__voce b { font-weight: var(--fw-semibold); color: var(--neutral-900); }
.requisiti-recap__voce svg { flex: none; width: 14px; height: 14px; }
.requisiti-recap__voce--obbligatorio svg { color: var(--primary-700); }
.requisiti-recap__voce--facoltativo svg { color: var(--neutral-500); }
.requisiti-recap__voce--non-richiesto svg { color: var(--neutral-400); }

/* ---- Checklist documentale (D130): sotto-componente cardine, lista-righe.
   Riga = documento: icona-stato | nome+meta | scadenza | azione, con la
   motivazione del rifiuto inline sotto. Dual-mode (D136) in fondo. ---- */
.checklist { display: flex; flex-direction: column; background: var(--neutral-0); border: var(--border-default); border-radius: var(--radius-md); padding-inline-start: 0px; }
.checklist__riga {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border-default);
}
.checklist__riga:last-child { border-bottom: none; }
.checklist__riga:hover { background: var(--neutral-50); }
.checklist__stato { display: inline-flex; }
.checklist__doc { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.checklist__nome { font-size: var(--text-sm); font-weight: var(--fw-medium); color: var(--neutral-800); }
/* neutral-600 (non 500): la meta puo' trovarsi sull'hover di riga (neutral-50), dove
   neutral-500 scenderebbe a 4.19:1; neutral-600 resta sopra 7:1 sia su bianco sia su neutral-50. */
.checklist__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--neutral-600); }
.checklist__scadenza { font-size: var(--text-xs); white-space: nowrap; }
.checklist__flag { font-size: var(--text-xs); white-space: nowrap; }
.checklist__azione { justify-self: end; display: inline-flex; gap: var(--space-2); }
/* Checklist in sola lettura (scheda pratica S4.1): nome documento a sinistra, stato a destra,
   senza le colonne di scadenza/azione della verifica interattiva. */
.checklist--lettura .checklist__riga { grid-template-columns: minmax(0, 1fr) auto; }
.checklist-gruppo { margin: var(--space-4) 0 var(--space-2); font-size: var(--text-sm); font-weight: var(--fw-semibold); color: var(--neutral-700); }
.checklist-gruppo:first-of-type { margin-top: 0; }
/* Motivazione del rifiuto: sempre visibile (espansa) sotto la riga, indentata
   sotto il nome del documento. Tono d'allerta (D130). */
.checklist__motivazione {
  grid-column: 2 / -1;
  margin-top: var(--space-1);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-xs);
  color: var(--danger-text);
  /* Sola tinta di fondo, senza banda a sinistra: era l'unico punto con la banda
     senza bordo perimetrale (#163) — avvisi e banner la portano su un riquadro
     bordato, un pattern diverso. */
  background: var(--danger-bg);
  border-radius: var(--radius-sm);
}
/* Stato vuoto delle sezioni della scheda (D135). */
.checklist-vuoto { padding: var(--space-8) var(--space-5); text-align: center; color: var(--neutral-500); }
.checklist-vuoto > * + * { margin-top: var(--space-2); }

/* ---- Workspace di verifica (S4.3, rifinito #96): riga = stato | documento | azioni.
   Tre colonne piene (niente colonna fantasma della 4-col di default) e cluster di azioni
   compatto a destra; il modulo di respingimento vive in un dialog popover (.modale) per
   documento, non piu' in una textarea sempre aperta dentro la riga. ---- */
.checklist--verifica .checklist__riga { grid-template-columns: auto minmax(0, 1fr) auto; }
.checklist--verifica .checklist__azione { flex-wrap: wrap; justify-content: flex-end; }

/* Caricamento per conto del fornitore (#107, D250): fuori dalla verifica la checklist e' in sola
   lettura (documento | stato) e guadagna la terza colonna d'azione con il campo file; in verifica la
   colonna c'e' gia' e il form si affianca ai bottoni di revisione. */
.checklist--caricabile .checklist__riga { grid-template-columns: minmax(0, 1fr) auto auto; }
.checklist__upload { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.checklist__upload .campo-file { width: 13rem; max-width: 100%; }

/* Barra d'azione in coda a una sezione di scheda, separata da un bordo: guida o campo
   a sinistra, azione a destra (conclusione verifica, upload visura della due-diligence). */
.sezione-azioni {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3) var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: var(--border-default);
}
/* Il testo-guida si comprime (flex-basis contenuta): l'azione resta sulla stessa riga
   e va a capo solo su spazi davvero stretti. */
.sezione-azioni p { flex: 1 1 18rem; max-width: 60ch; margin: 0; }

/* Colonna-stato a larghezza stabile nella verifica: i badge variano ("Da caricare",
   "Approvato"...), il nome del documento parte sempre alla stessa x. */
.checklist--verifica .checklist__stato { min-width: 7rem; }

/* ---- Scelta del Flag di rischio (S4.4, #96): radiogroup a schede. Radio nativa
   visibile (nessun controllo reinventato), scheda bordata che si accende col
   semaforo alla selezione (:has). Il colore rinforza: significato = radio + testo
   + nota (D64/WCAG 1.4.1). ---- */
.scelta-rischio {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
  margin: 0 0 var(--space-4);
  padding: 0;
  border: 0;
}
.scelta-rischio__voce {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--neutral-0);
  border: var(--border-strong);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color var(--motion-fast), background-color var(--motion-fast);
}
.scelta-rischio__voce:hover { border-color: var(--neutral-400); }
/* L'anello di focus sta sulla scheda intera (la radio e' piccola e decentrata). */
.scelta-rischio__voce:has(input:focus-visible) { outline: var(--ring-focus-width) solid var(--ring-focus-color); outline-offset: var(--ring-focus-offset); }
.scelta-rischio__voce input { margin-top: 3px; }
.scelta-rischio__voce input:focus-visible { outline: none; }
.scelta-rischio__nome { display: block; font-size: var(--text-sm); font-weight: var(--fw-semibold); color: var(--neutral-800); }
.scelta-rischio__nota { display: block; margin-top: 2px; font-size: var(--text-xs); color: var(--neutral-600); }
.scelta-rischio__voce--verde  input { accent-color: var(--success); }
.scelta-rischio__voce--giallo input { accent-color: var(--warning); }
.scelta-rischio__voce--rosso  input { accent-color: var(--danger); }
.scelta-rischio__voce--verde:has(input:checked)  { border-color: var(--success); background: var(--success-bg); }
.scelta-rischio__voce--giallo:has(input:checked) { border-color: var(--warning); background: var(--warning-bg); }
.scelta-rischio__voce--rosso:has(input:checked)  { border-color: var(--danger);  background: var(--danger-bg); }
.scelta-rischio__voce--verde:has(input:checked)  :is(.scelta-rischio__nome, .scelta-rischio__nota) { color: var(--success-text); }
.scelta-rischio__voce--giallo:has(input:checked) :is(.scelta-rischio__nome, .scelta-rischio__nota) { color: var(--warning-text); }
.scelta-rischio__voce--rosso:has(input:checked)  :is(.scelta-rischio__nome, .scelta-rischio__nota) { color: var(--danger-text); }

/* ---- Provvedimenti (ADR-0010): record append-only, blocco bordato. La revoca
   e' un record separato; il bordo sinistro segnala l'attivita'. ---- */
.provv { border: var(--border-default); border-radius: var(--radius-md); border-left: 4px solid var(--danger); background: var(--neutral-0); }
.provv + .provv { margin-top: var(--space-3); }
.provv--revocato { border-left-color: var(--neutral-300); opacity: .72; }
.provv__head { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; padding: var(--space-3) var(--space-4); border-bottom: var(--border-default); }
.provv__quando { font-size: var(--text-sm); color: var(--neutral-500); }
.provv__azione { margin-left: auto; }
.provv__corpo { padding: var(--space-4); }

/* ---- Storico arricchito (D131): attore + causale + nodo tipizzato per categoria.
   Estende la primitiva .storico (sezione 5). Il colore del nodo rinforza, il
   titolo porta il significato (icona+testo, ux 3). ---- */
.storico__attore { font-size: var(--text-xs); color: var(--neutral-600); }
.storico__attore b { font-weight: var(--fw-medium); color: var(--neutral-700); }
.storico__causale { font-size: var(--text-xs); color: var(--neutral-500); }
.storico__cat { display: inline-block; margin-left: var(--space-2); font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em; text-transform: uppercase; color: var(--neutral-500); }
.storico__voce--stato         .storico__nodo { border-color: var(--primary-700); }
.storico__voce--provvedimento .storico__nodo { border-color: var(--danger);  background: var(--danger-bg); }
.storico__voce--comunicazione .storico__nodo { border-color: var(--info); }
.storico__voce--esito         .storico__nodo { border-color: var(--success); background: var(--success-bg); }

/* ---- Riqualifica automatica: valore + azione di toggle sulla stessa riga del dato (aside scheda). ---- */
.riqualifica { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }

/* ---- Menu overflow (D124/D127): Popover API nativa ancorata al bottone 3-puntini.
   Una sola overflow per scheda: anchor-name fisso (niente style inline, CSP D111).
   Con anchor positioning (Baseline 2024) si ancora sotto il bottone; senza, il
   reset * { margin:0 } (base.css) ancorerebbe il popover in alto a sinistra, quindi
   ripristiniamo margin:auto come fallback (action-sheet centrato). ---- */
.scheda-overflow { anchor-name: --scheda-overflow; }
.menu {
  width: min(20rem, calc(100vw - var(--space-8)));
  padding: var(--space-2);
  background: var(--neutral-0);
  border: var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--elev-2);
  margin: auto;
}
@supports (position-area: bottom span-left) {
  /* inset:auto annulla l'inset:0 dello UA stylesheet del popover: senza, l'inset
     ereditato diventa offset rispetto alla position-area e sovra-vincola il box
     (reset canonico MDN per i popover ancorati). Cosi' e' la sola position-area
     a collocare il menu sotto il bottone, allineato a destra (span-left). */
  .menu { margin: 0; inset: auto; margin-top: var(--space-1); position-anchor: --scheda-overflow; position-area: bottom span-left; }
}
.menu:popover-open { animation: menu-entra var(--motion-fast) both; }
@keyframes menu-entra { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .menu:popover-open { animation: none; } }

/* ---- Variante di riga (D189, tabella Requisiti documentali): N popover indipendenti per
   pagina, uno per riga. L'anchor-name fisso di .scheda-overflow non scala (per spec, piu'
   elementi con lo stesso anchor-name risolvono tutti all'ULTIMO nel DOM): niente anchor-name
   esplicito, si sfrutta l'anchor implicito nativo (popovertarget+id, gia' presente senza
   dichiarazioni CSS) e si azzera solo il position-anchor ereditato da .menu. Senza supporto
   all'anchor implicito, position-area non ha effetto (nessun anchor risolto) e si degrada
   allo stesso fallback centrato di .menu.
   Stessa ricetta per il menu del conto (top-bar): l'anchor-name di .scheda-overflow non esiste
   sulle pagine senza overflow, quindi il position-anchor ereditato non risolverebbe nulla. ---- */
@supports (position-area: bottom span-left) {
  .menu--riga,
  .menu--conto { position-anchor: auto; }
  /* I menu di filtro scendono allineati al BORDO SINISTRO del proprio segmento (span-right),
     non a quello destro: il segmento e' stretto e il menu piu' largo, quindi allineandolo a
     destra sborderebbe verso sinistra sopra il filtro precedente. */
  .menu--filtro { position-anchor: auto; position-area: bottom span-right; }
}

/* Il menu del conto e' stretto: dentro c'e' un indirizzo e una voce, non un elenco di azioni. */
.menu--conto { width: min(17rem, calc(100vw - var(--space-8))); }
.menu__identita {
  padding: 0 var(--space-3) var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  color: var(--neutral-800);
  overflow-wrap: anywhere;
}

/* ============================================================================
   RIVELAZIONE: entita' collegate e aiuto contestuale (ADR-0021, D264-D266).
   Il linguaggio con cui una pagina nomina un'altra entita' e la rivela al
   passaggio. Regole normative in ADR-0021, craft in design-system.md.
   ============================================================================ */

/* ---- Il collegamento a entita' (D264): un solo vestito per tutto il back-office, scheda ed
   elenco, senza rinforzi tarati per contesto. Il valore mantiene colore e peso del dato accanto:
   cambia l'affordance, non la gerarchia. A dodici collegamenti per schermata un rinforzo in piu'
   diventa rumore che l'occhio conta prima di leggere i dati. ---- */
.ent {
  color: inherit;
  cursor: pointer;
  border-radius: var(--radius-sm);
  text-decoration: underline dashed 1px;
  text-decoration-color: var(--neutral-300);
  text-underline-offset: 3px;
}
.ent:hover, .ent:focus-visible { color: var(--primary-700); text-decoration-style: solid; text-decoration-color: currentColor; }
.ent:focus-visible { outline: var(--ring-focus-width) solid var(--ring-focus-color); outline-offset: var(--ring-focus-offset); }
/* Senza il permesso di aprire la destinazione si rende <span>, non <a> (ADR-0021): il tratteggio si
   smorza e il cursore non mente, ma l'anteprima resta. Il permesso governa la navigazione, mai la
   rivelazione. */
.ent:not([href]) { cursor: default; text-decoration-color: var(--neutral-200); }
.ent:not([href]):hover { color: inherit; text-decoration-style: dashed; text-decoration-color: var(--neutral-200); }

/* ---- Recapiti (mailto:/tel:): vestito deliberatamente estraneo (D264). Non sono entita' del
   dominio ma azioni verso l'esterno, e nella stessa card convivono a poche righe dal collegamento a
   entita' (l'email dell'account portale e' un'entita', quella di contatto no). Il glifo fa il
   lavoro: dice "esce dall'applicazione" prima che il colore dica qualsiasi cosa. ---- */
.contatto { color: var(--neutral-800); text-decoration: none; border-bottom: 1px solid var(--neutral-300); }
.contatto::before {
  content: "";
  display: inline-block;
  width: 1em; height: 1em;
  margin-right: 4px;
  vertical-align: -.13em;
  background: currentColor;
  opacity: .55;
  -webkit-mask: var(--glifo) center / contain no-repeat;
          mask: var(--glifo) center / contain no-repeat;
}
.contatto--mail { --glifo: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='2' y='4' width='20' height='16' rx='2'/><path d='m2 7 10 6 10-6'/></svg>"); }
.contatto--tel  { --glifo: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.1 4.2 2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1 1 .4 1.9.7 2.8a2 2 0 0 1-.5 2.1L8.1 9.9a16 16 0 0 0 6 6l1.3-1.2a2 2 0 0 1 2.1-.5c.9.3 1.8.6 2.8.7a2 2 0 0 1 1.7 2Z'/></svg>"); }
.contatto:hover { color: var(--primary-700); border-bottom-color: currentColor; }
.contatto:focus-visible { outline: var(--ring-focus-width) solid var(--ring-focus-color); outline-offset: var(--ring-focus-offset); }

/* ---- La superficie condivisa dei due pannelli (ADR-0021/D264). La parentela e' qui: fondo, bordo,
   raggio, ombra ed entrata sono una sola dichiarazione. Se cambia l'ombra, cambia per entrambe o per
   nessuna. Trigger a icona pura (.aiuto-info): stesso trattamento di .accesso-aiuto__trigger
   (components.css §8), qui riportato per il back-office; sovrascrive sfondo/bordo di .btn--secondario
   (stessa specificita', vince per ordine di caricamento). ---- */
.aiuto-info {
  background-color: transparent;
  border-color: transparent;
  border-radius: var(--radius-full);
  color: var(--primary-700);
}
.aiuto-info:hover { background-color: var(--neutral-100); border-color: transparent; color: var(--primary-600); }
/* La (i) apre gia' il pannello ricco anche in hover (D186): il tooltip CSS testuale
   ("Informazioni") resterebbe ridondante col pannello stesso. */
.aiuto-info.btn--tooltip::after { content: none; }
.rivela {
  width: min(22rem, calc(100vw - var(--space-8)));
  margin: auto; /* fallback: centrato come .menu se manca l'anchor positioning */
  padding: var(--space-3) var(--space-4);
  background: var(--neutral-0);
  color: var(--neutral-700);
  border: var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--elev-2);
  font-size: var(--text-sm);
  line-height: var(--leading-base);
}
/* Ancora IMPLICITA da showPopover({ source }): niente anchor-name, niente style inline (CSP
   style-src 'self', D109/D111). Un anchor-name fisso condiviso fa risolvere tutti i pannelli
   all'ULTIMO elemento in DOM order (per spec): e' il bug che questa ricetta chiude. In top layer il
   pannello non viene tagliato dallo scorrimento di .tabella-wrap; contro il bordo destro si ribalta. */
@supports (position-area: bottom span-right) {
  .rivela {
    margin: 0; inset: auto; margin-top: var(--space-1);
    position-anchor: auto;
    position-area: bottom span-right;
    position-try-fallbacks: flip-block, flip-inline;
    position-visibility: no-overflow;
  }
}
.rivela:popover-open { animation: menu-entra var(--motion-fast) both; }
@media (prefers-reduced-motion: reduce) { .rivela:popover-open { animation: none; } }

/* Anteprima di entita': apre con una CHIAVE DI TIPO in maiuscoletto mono, corpo a griglia di fatti,
   chiude sulla riga di destinazione. Il tooltip apre con una frase, e' prosa e non porta da nessuna
   parte: stessa famiglia, nessuna ambiguita'. */
.rivela--ent .rivela__tipo {
  font-family: var(--font-mono); font-size: var(--text-xs);
  letter-spacing: .06em; text-transform: uppercase; color: var(--neutral-500);
}
.rivela--ent .rivela__nome {
  margin-top: 2px;
  font-size: var(--text-md); font-weight: var(--fw-semibold); color: var(--neutral-900);
  overflow-wrap: anywhere;
}
.rivela--ent .dati {
  margin-top: var(--space-3); padding-top: var(--space-3); border-top: var(--border-default);
  grid-template-columns: minmax(5.5rem, max-content) 1fr;
  gap: var(--space-1) var(--space-4);
  font-size: var(--text-sm);
}
/* Riga di DESTINAZIONE, non un bottone (ADR-0021: solo fatti, mai azioni): dice dove porta il clic
   gia' presente sul collegamento, senza aggiungere un bersaglio dentro un pannello effimero. */
.rivela__destinazione {
  display: flex; align-items: center; gap: var(--space-2);
  margin-top: var(--space-3); padding-top: var(--space-2); border-top: var(--border-default);
  font-size: var(--text-xs); color: var(--neutral-500);
}
.rivela__destinazione svg { flex: none; opacity: .7; }

/* Tooltip d'aiuto (InfoPopover): ricco ma non interattivo — niente di raggiungibile con Tab, ed e'
   cio' che lo tiene un role="tooltip" legittimo invece di una terza primitiva. */
.rivela--aiuto .rivela__titolo { margin-bottom: var(--space-1); font-weight: var(--fw-semibold); color: var(--neutral-900); }
.rivela--aiuto .rivela__corpo { color: var(--neutral-600); text-transform: none; letter-spacing: normal;}
.rivela--aiuto .rivela__corpo :is(p, ul) { margin: 0; }
.rivela--aiuto .rivela__corpo ul { margin-top: var(--space-2); padding-left: var(--space-4); display: grid; gap: 2px; }
/* Il corpo azzera i margini di p e ul: senza questa riga la prosa che segue un elenco si incolla
   all'ultima voce. */
.rivela--aiuto .rivela__corpo :is(ul, p) + p { margin-top: var(--space-2); }
.rivela--aiuto .rivela__corpo strong { color: var(--neutral-800); font-weight: var(--fw-semibold); }

/* ---- Verdetto documentale della scheda Fornitore (D265 emendata): apre il tab Documenti e risponde
   prima dell'elenco — "manca qualcosa?" e' la domanda, la checklist sotto e' la risposta lunga.
   L'elenco delle eccezioni a parole non c'e' piu': con la checklist intera in pagina sarebbe la
   stessa lista scritta due volte, e due liste degli stessi documenti divergono. ---- */
.cop-verdetto {
  display: flex; align-items: baseline; gap: var(--space-2);
  font-size: var(--text-md); font-weight: var(--fw-semibold); line-height: var(--leading-md);
}
.cop-verdetto svg { flex: none; width: 15px; height: 15px; align-self: center; }
.cop-verdetto--allerta { color: var(--danger-text); }
.cop-verdetto--attesa  { color: var(--warning-text); }
.cop-verdetto--ok      { color: var(--success-text); }
/* "In scadenza" resta un'annotazione, non uno stato e non un conteggio (S7.1): sta accanto al
   verdetto smorzata, cosi' non compete con cio' che il verdetto ha gia' dichiarato piu' grave. */
.cop-verdetto__annota { font-weight: var(--fw-regular); color: var(--neutral-600); }
/* Divergenza di catalogo: riga muta in coda, condizionata alla divergenza (rara). La regola che
   spiega perche' quei requisiti non generano buchi (ADR-0011) sta nella (i), non sulla card. */
.cop-divergenza {
  display: flex; align-items: flex-start; gap: var(--space-2);
  font-size: var(--text-xs); color: var(--neutral-600); line-height: var(--leading-md);
}
.cop-divergenza svg { flex: none; width: 13px; height: 13px; margin-top: 1px; color: var(--neutral-500); }
.menu__gruppo { padding: var(--space-2) var(--space-3) var(--space-1); font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .06em; text-transform: uppercase; color: var(--neutral-500); }
.menu__gruppo--pericolo { color: var(--danger); }
.menu__sep { border: 0; border-top: var(--border-default); margin: var(--space-2) calc(-1 * var(--space-2)); }
.menu form { margin: 0; display: block; }
.menu__voce {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 36px;
  /* Una voce di menu e' un comando, non un rimando nel testo: la sottolineatura dei
     collegamenti (base.css) qui e' rumore, e la riga intera e' gia' il bersaglio. */
  text-decoration: none;
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  color: var(--neutral-700);
  text-align: left;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.menu__voce:hover { background: var(--neutral-100); color: var(--neutral-900); }
.menu__voce svg { flex: none; width: 16px; height: 16px; opacity: .7; }
.menu__voce--pericolo { color: var(--danger-text); }
.menu__voce--pericolo:hover { background: var(--danger-bg); }

/* ---- Responsive della scheda ricca (D136). Back-office desktop-first: la riga
   di checklist manda l'azione a capo su stretto (resta riga). Il collasso a card
   resta del portale fornitore (.densita-fornitore) su mobile. ---- */
@media (max-width: 720px) {
  .checklist__riga,
  .checklist--verifica .checklist__riga { grid-template-columns: auto minmax(0, 1fr); }
  .checklist__scadenza, .checklist__flag, .checklist__azione { grid-column: 2 / -1; justify-self: start; }
  .checklist--verifica .checklist__azione { justify-content: flex-start; }
  .scelta-rischio { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .densita-fornitore .checklist__riga { grid-template-columns: 1fr; gap: var(--space-2); padding: var(--space-4); }
  .densita-fornitore .checklist__stato { justify-self: start; }
  .densita-fornitore .checklist__azione { justify-self: stretch; }
  .densita-fornitore .checklist__azione .btn { width: 100%; }
}

/* ===========================================================================
   8. SCHEDA UTENTE E SCHEDA PRATICA - riallineamento al mock "Nuova UI" (schermi
   Utente e Pratica). Stessa grammatica della scheda Fornitore (sezione 7), piu' tre
   primitive che il mock introduce: la testata su banda bianca, la riga di ruolo
   che e' tutta un interruttore, la checklist a puntini con i gruppi come bande.
   =========================================================================== */

/* ---- Testata su banda: ritorno, titolo, meta e striscia stanno su bianco a tutta
   larghezza, chiusi da un filetto; il corpo resta sul grigio della pagina. La banda
   "esce" dal padding di .bo-main con margini negativi, cosi' il guscio non cambia.
   L'allineamento verticale della testata (flex-end) e il margine sotto restano quelli
   di .scheda-testata; qui si annulla solo il margine dell'ultimo figlio. ---- */
.scheda-hero {
  margin: calc(-1 * var(--space-6)) calc(-1 * var(--space-6)) var(--space-5);
  padding: var(--space-4) var(--space-6);
  background: var(--neutral-0);
  border-bottom: var(--border-default);
}
.scheda-hero > :last-child { margin-bottom: 0; }
/* La striscia dentro la banda: stessa carta ma senza il margine di pagina. */
.scheda-hero > .striscia { margin-top: var(--space-4); }
/* I tab chiudono la banda (mock "Nuova UI"): stanno sul suo filetto, non ne portano uno proprio.
   La banda perde il padding in basso cosi' la sottolineatura del tab attivo tocca il filetto. */
.scheda-hero:has(> .tab-scheda) { padding-bottom: 0; }
.scheda-hero > .tab-scheda { margin-top: 14px; margin-bottom: 0; border-bottom: 0; }
.scheda-hero > .tab-scheda .tab-scheda__voce { margin-bottom: 0; }
@media (max-width: 880px) {
  .scheda-hero { margin: calc(-1 * var(--space-5)) calc(-1 * var(--space-5)) var(--space-5); padding: var(--space-4) var(--space-5); }
}
/* Il link "Scheda fornitore" nelle azioni della testata e' un bottone, non un link sottolineato. */
.scheda-testata__azioni .btn { text-decoration: none; }
/* Nella riga meta di una testata su banda il separatore e' un punto smorzato. */
.meta-mono .sep { color: var(--neutral-300); }

/* ---- Nota sotto la banda di testata della card: un paragrafo di guida che occupa tutta
   la riga e si chiude con un filetto, a filo dei bordi. E' la frase che spiega *come si
   usa* la card ("spunta per assegnare"), non un aiuto a un campo. ---- */
.scheda-sezione > .scheda-sezione__nota {
  margin: 0;
  padding: var(--space-3) var(--space-5);
  font-size: var(--text-sm);
  line-height: var(--leading-md);
  color: var(--neutral-500);
  border-bottom: var(--border-width) solid color-mix(in srgb, var(--neutral-100) 60%, var(--neutral-0));
}
.scheda-sezione > .scheda-sezione__nota:last-child { margin: 0; border-bottom: 0; }

/* ---- Ruoli: ogni riga e' un interruttore intero (submit SSR, ADR-0013), non un nome con un
   bottone "Assegna" in fondo. La spunta a sinistra dice lo stato, la pastiglia a destra lo
   ripete a parole; la riga assegnata si tinge appena. Il `form` dell'EditForm e' un blocco
   trasparente: la lista va a filo dei bordi della card e porta i propri filetti. ---- */
.scheda-sezione > .ruoli-lista { margin: 0; gap: 0; }
.scheda-sezione > .ruoli-lista:last-child { margin: 0; }
.ruoli-lista form { display: block; margin: 0; }
.ruoli-lista form + form { border-top: var(--border-width) solid color-mix(in srgb, var(--neutral-100) 60%, var(--neutral-0)); }
.ruolo-riga {
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-3) var(--space-5);
  text-align: left;
  background: var(--neutral-0);
  border: 0;
  border-radius: 0;
  cursor: pointer;
  transition: background var(--motion-fast);
}
.ruolo-riga:hover { background: var(--neutral-50); }
.ruolo-riga[aria-pressed="true"] { background: color-mix(in srgb, var(--primary-50) 55%, var(--neutral-0)); border-color: transparent; }
.ruolo-riga[aria-pressed="true"]:hover { background: var(--primary-50); }
.ruolo-riga:disabled { cursor: not-allowed; }
.ruolo-riga:disabled .ruolo-riga__testo { opacity: .7; }
.ruolo-riga:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.ruolo-riga__spunta {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  margin-top: 1px;
  color: transparent;
  background: var(--neutral-0);
  border: var(--border-width) solid var(--neutral-300);
  border-radius: 4px;
  transition: background var(--motion-fast), border-color var(--motion-fast);
}
.ruolo-riga__spunta svg { width: 11px; height: 11px; }
.ruolo-riga[aria-pressed="true"] .ruolo-riga__spunta { color: var(--neutral-0); background: var(--primary-700); border-color: var(--primary-700); }
.ruolo-riga__testo { flex: 1; min-width: 0; }
.ruolo-riga__nome { display: block; font-size: var(--text-sm); font-weight: var(--fw-semibold); color: var(--neutral-800); }
.ruolo-riga__desc { display: block; margin-top: 1px; font-size: var(--text-xs); color: var(--neutral-500); }
.ruolo-riga .badge { flex: none; }

/* ---- Coppie chiave/valore in riga (card "Sicurezza"): la domanda a sinistra, la risposta a
   destra, una per riga. Nell'aside il default di .dati impila l'etichetta sopra il valore,
   che va bene per date e nomi lunghi; per quattro si'/no la riga e' piu' leggibile. Il tono
   del valore dice se quella risposta chiede attenzione. ---- */
.scheda-aside .scheda-sezione > .dati--righe { gap: var(--space-2); padding: var(--space-3) var(--space-4); }
.scheda-aside .scheda-sezione > .dati--righe > div { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.scheda-aside .scheda-sezione > .dati--righe > div > dt {
  padding: 0;
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: var(--fw-regular);
  letter-spacing: normal;
  text-transform: none;
  color: var(--neutral-600);
}
.scheda-aside .scheda-sezione > .dati--righe > div > dd { padding: 0; font-size: var(--text-sm); font-weight: var(--fw-medium); color: var(--neutral-800); }
.scheda-aside .scheda-sezione > .dati--righe > div > dd.mono { font-family: var(--font-mono); font-weight: var(--fw-regular); font-variant-numeric: tabular-nums; }
.scheda-aside .scheda-sezione > .dati--righe > div > dd.tono--ok { color: var(--success-text); font-weight: var(--fw-semibold); }
.scheda-aside .scheda-sezione > .dati--righe > div > dd.tono--attesa { color: var(--warning-text); font-weight: var(--fw-semibold); }
.scheda-aside .scheda-sezione > .dati--righe > div > dd.tono--allarme { color: var(--danger-text); font-weight: var(--fw-semibold); }
/* Le azioni di sicurezza stanno sotto le risposte, nella stessa card: agiscono su cio' che si legge sopra. */
.scheda-aside .scheda-sezione > .dati--righe + .azioni-riga { margin: 0 var(--space-4) var(--space-4); }

/* ---- Checklist della Pratica: riga = puntino di stato | documento | pastiglia | azione.
   Flex e non grid: l'azione c'e' solo quando si puo' agire e la pastiglia deve restare
   appoggiata a destra anche senza. Il puntino e' un quadratino (Blueprint), non un cerchio, e
   porta lo stesso colore semantico della pastiglia: si legge in diagonale come una colonna. ---- */
.checklist--pratica { margin: 0; padding: 0; list-style: none; }
.checklist--pratica .checklist__riga {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-2) var(--space-4);
  border-bottom: var(--border-width) solid color-mix(in srgb, var(--neutral-100) 60%, var(--neutral-0));
}
.checklist--pratica .checklist__riga:last-child { border-bottom: 0; }
/* Base 24rem, non 10rem (#176): la base e' cio' che decide l'andata a capo, e a 10rem il cluster
   di verifica (Anteprima/Scarica/Approva/Respingi/Sostituisci) restava in riga schiacciando la
   descrizione a una striscia — proprio dove la descrizione dice cosa controllare prima di approvare. */
.checklist--pratica .checklist__doc { flex: 1 1 24rem; }
/* L'azione si appoggia a destra; se proprio non ci sta, va a capo da sola, allineata a destra,
   e il documento resta sulla prima riga accanto al puntino. */
.checklist--pratica .checklist__azione { justify-self: auto; margin-left: auto; flex-wrap: wrap; justify-content: flex-end; }
/* Il file input resta nel DOM (e' lui che porta il file nel POST) ma fuori dalla vista: lo apre
   l'etichetta vestita da bottone. Resta focalizzabile: l'anello di focus va sull'etichetta. */
.campo-file--nascosto { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.checklist__upload { position: relative; }
.checklist__upload:has(.campo-file--nascosto:focus-visible) .checklist__upload-scegli { outline: 2px solid var(--focus); outline-offset: 2px; }
/* Il submit compare solo a file scelto; a quel punto l'etichetta dice che si puo' cambiare idea. */
.checklist__upload-invia { display: none; }
.checklist__upload:has(.campo-file--nascosto:valid) .checklist__upload-invia { display: inline-flex; }
.checklist__upload:has(.campo-file--nascosto:valid) .checklist__upload-scegli { color: var(--neutral-600); }
.checklist--pratica .checklist__motivazione { flex-basis: 100%; margin-left: calc(8px + var(--space-3)); }
/* Scadenza su una riga propria (D320): etichetta, data e azione sotto il documento, allineate al testo
   come la motivazione; nella colonna azioni il campo data schiacciava anteprima e download. */
.checklist--pratica .checklist__scadenza-riga { flex-basis: 100%; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); margin-left: calc(8px + var(--space-3)); }
.checklist__scadenza-etichetta { font-size: var(--text-xs); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--neutral-600); }
/* Data digitata in gg/mm/aaaa: larghezza da dieci caratteri, cifre tabulari, mai la riga intera. */
.campo__input.campo__data { width: 8.5rem; font-variant-numeric: tabular-nums; }
.checklist__punto { flex: none; width: 8px; height: 8px; border-radius: 2px; border: var(--border-width) solid transparent; }
.checklist__punto--neutral { background: var(--neutral-300); }
.checklist__punto--info    { background: var(--info); }
.checklist__punto--success { background: var(--success); }
.checklist__punto--warning { background: var(--warning); }
/* Il respinto e' un buco da ricolmare: vuoto col bordo, non pieno. */
.checklist__punto--danger  { background: var(--danger-bg); border-color: var(--danger); }

/* ---- Il titolo di gruppo della checklist dentro una card e' una banda, non un h3 di testo:
   mono maiuscola minuta con il conteggio accanto, filetto sotto, a filo dei bordi. Il secondo
   gruppo e i seguenti si staccano dal precedente con un fondo appena piu' scuro. Vale anche
   per il tab Documenti della scheda Fornitore, che usa la stessa lista. ---- */
.scheda-sezione > .checklist-gruppo,
.scheda-sezione > h2 + .checklist-gruppo,
.scheda-sezione > :not(h2) + .checklist-gruppo {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin: 0;
  padding: 6px var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--tracking-occhiello);
  text-transform: uppercase;
  color: var(--neutral-500);
  border-bottom: var(--border-width) solid color-mix(in srgb, var(--neutral-100) 60%, var(--neutral-0));
}
.scheda-sezione > :not(h2):not(.checklist-gruppo) + .checklist-gruppo { border-top: var(--border-width) solid color-mix(in srgb, var(--neutral-100) 60%, var(--neutral-0)); }
.scheda-sezione > .checklist + .checklist-gruppo { background: color-mix(in srgb, var(--neutral-50) 60%, var(--neutral-0)); }
.checklist-gruppo__n { font-variant-numeric: tabular-nums; letter-spacing: normal; text-transform: none; color: var(--neutral-400); }

/* ---- Barra d'azione in coda alla card: banda grigia a filo dei bordi, chiusa dal bordo della
   card. Il testo-guida a sinistra, il bottone a destra: e' un piede, non un paragrafo. ---- */
.scheda-sezione > .sezione-azioni,
.scheda-sezione > .sezione-azioni:last-child,
.scheda-sezione > :not(h2) + .sezione-azioni {
  margin: 0;
  padding: var(--space-3) var(--space-5);
  background: var(--neutral-50);
  border-top: var(--border-width) solid var(--neutral-100);
}
.scheda-sezione > .sezione-azioni p { font-size: var(--text-xs); color: var(--neutral-500); }
.scheda-sezione > .sezione-azioni form { margin: 0; }

/* ---- Storico compatto nella colonna di contesto: nodo, titolo, quando e chi. ---- */
.scheda-aside .storico__titolo { font-weight: var(--fw-semibold); color: var(--neutral-900); }
.scheda-aside .storico__attore { font-size: var(--text-xs); color: var(--neutral-600); }
.scheda-aside .storico__attore b { font-weight: var(--fw-medium); }
.scheda-aside .storico__causale { margin-top: 2px; font-size: var(--text-xs); color: var(--neutral-600); }

/* ===========================================================================
   NUOVO FORNITORE - pagina-form a due colonne (mock "Nuova UI", schermo Nuovo fornitore)
   Colonna principale: card con banda numerata ("1 di 2"), campi a coppie, riquadro dell'identita'
   fiscale, card-interruttore "Apri subito la pratica", azioni. Colonna di contesto: timeline
   "Cosa succede alla creazione" e nota sul codice fiscale fuori standard. Tutto zero-JS
   (ADR-0013): l'interruttore e il passo 3 della timeline seguono la casella con `:has(:checked)`.
   =========================================================================== */
/* La frase sotto il titolo della banda: cosa succede al salvataggio, non una didascalia di dati. */
.scheda-identita__intro {
  margin-top: var(--space-1);
  max-width: 70ch;
  font-size: var(--text-sm);
  color: var(--neutral-500);
}

/* Il form e' un blocco trasparente: il ritmo fra i blocchi lo danno le card (.scheda-sezione). */
.modulo { display: block; margin: 0; }
/* Dentro una card il ritmo fra i campi lo da' la card stessa (margini sui figli diretti):
   il margine storico di .campo raddoppierebbe lo stacco. */
.modulo .campo { margin-bottom: 0; }
.modulo .campo .aiuto { margin-top: var(--space-2); }
/* Pagina-form: la colonna di contesto del mock e' piu' stretta di quella della scheda entita'
   e l'insieme non si stira oltre ~66rem — un form largo si legge male. */
.scheda-corpo--modulo {
  grid-template-columns: minmax(0, 1fr) 19rem;
  max-width: 66rem;
}

/* Coppia di campi sulla stessa riga (tipo/macro, P.IVA/CF, PEC/telefono). Un campo solo in una
   coppia resta a meta' larghezza: e' il caso della data di iscrizione, che non merita una riga. */
.campi-2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
}
/* Etichetta della facoltativita': smorzata e in peso normale, dentro la label. */
.campo__facoltativo { font-weight: var(--fw-regular); color: var(--neutral-400); }

/* Riquadro che raggruppa campi che valgono come uno (P.IVA e codice fiscale): fondo appena piu'
   scuro della card, bordo leggero, e la frase che spiega perche' stanno insieme. */
.campo-gruppo {
  padding: var(--space-4);
  background: color-mix(in srgb, var(--neutral-50) 50%, var(--neutral-0));
  border: var(--border-width) solid var(--neutral-100);
  border-radius: var(--radius-md);
}
.campo-gruppo > .aiuto { margin-top: var(--space-3); }

/* Riga di aiuto con glifo davanti: l'icona e' decorativa e prende il colore smorzato del testo,
   salvo la variante primaria (la busta dell'email: e' li' che arriva l'invito). */
.bo p.aiuto--icona { display: flex; flex-direction: row; align-items: center; gap: var(--space-2); }
.aiuto--icona svg { flex: none; width: 12px; height: 12px; color: var(--neutral-400); }
.aiuto--icona-primaria svg { color: var(--info); }

/* ---- Card-interruttore "Apri subito la pratica" ----
   L'intera card e' la <label> della casella nativa (nascosta ma focalizzabile): click ovunque
   cambia lo stato, la tastiera ci arriva con Tab e Spazio, e l'anello di focus lo porta la card.
   L'interruttore disegnato riusa .interruttore e si accende con :has(:checked); la pastiglia a
   destra dice a parole lo stato in cui nascera' il fornitore. ---- */
.apri-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background: var(--neutral-0);
  border: var(--border-width) solid var(--border-color);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color var(--motion-fast), box-shadow var(--motion-fast);
}
.apri-card:has(:checked) {
  border-color: color-mix(in srgb, var(--primary-700) 40%, var(--neutral-0));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary-700) 40%, var(--neutral-0));
}
.apri-card:has(:focus-visible) { outline: 2px solid var(--primary-700); outline-offset: 2px; }
.apri-card__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.apri-card:has(:checked) .apri-card__interruttore { background: var(--primary-700); }
.apri-card:has(:checked) .apri-card__interruttore::before { translate: 16px 0; }
.apri-card:has(:checked):hover .apri-card__interruttore { background: var(--primary-900); }
.apri-card__testo { flex: 1; min-width: 0; }
.apri-card__titolo { display: block; font-size: var(--text-base); font-weight: var(--fw-semibold); color: var(--neutral-900); }
.apri-card__dettaglio { display: block; margin-top: 2px; font-size: var(--text-sm); color: var(--neutral-500); }
.apri-card__on, .apri-card__off { flex: none; display: none; }
.apri-card:has(:checked) .apri-card__on { display: inline-flex; }
.apri-card:not(:has(:checked)) .apri-card__off { display: inline-flex; }

/* Le azioni chiudono la colonna: primario con spunta, "Annulla" discreto accanto. */
.azioni-riga--modulo { align-items: center; padding-top: var(--space-1); }
.azioni-riga--modulo .btn svg { width: 14px; height: 14px; }

/* ---- Timeline "Cosa succede alla creazione": nodi numerati mono uniti da un filo, titolo e
   dettaglio. Il filo e' il fondo della colonna del nodo (2px centrati, alti quanto la riga) e
   manca sull'ultimo passo. Il passo 3 ha due frasi e ne mostra una sola, a seconda della casella
   nel form: acceso dice che la pratica si apre subito, spento che si aprira' dalla scheda. Senza
   la casella (chi non gestisce le pratiche) resta la frase "spento", che e' la verita'. ---- */
.passi {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  column-gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}
.passi__passo { display: contents; }
.passi__colonna {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  background: linear-gradient(var(--neutral-200), var(--neutral-200)) center / 2px 100% no-repeat;
}
.passi__passo:last-child .passi__colonna { background: none; }
.passi__nodo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-full);
  background: var(--info-bg);
  color: var(--primary-700);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--fw-medium);
}
.passi__corpo { display: block; min-width: 0; padding-bottom: var(--space-4); }
.passi__passo:last-child .passi__corpo { padding-bottom: 0; }
.passi__titolo { display: block; font-size: var(--text-sm); font-weight: var(--fw-semibold); color: var(--neutral-900); }
.passi__dettaglio { display: block; margin-top: 2px; font-size: var(--text-xs); color: var(--neutral-500); line-height: var(--leading-md); }
.passi__dettaglio--on { display: none; }
.modulo:has(.apri-card__input:checked) .passi__dettaglio--on { display: block; }
.modulo:has(.apri-card__input:checked) .passi__dettaglio--off { display: none; }
/* Il nodo del passo condizionato si accende solo se la pratica si apre. */
.passi__passo--condizionato .passi__nodo { background: var(--neutral-100); color: var(--neutral-500); }
.modulo:has(.apri-card__input:checked) .passi__passo--condizionato .passi__nodo { background: var(--info-bg); color: var(--primary-700); }

/* Nota ambra nella colonna di contesto: un'informazione da sapere prima, non un errore. */
.nota-avviso {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--warning-bg);
  border: var(--border-width) solid color-mix(in srgb, var(--warning) 45%, var(--warning-bg));
  border-radius: var(--radius-md);
  color: var(--warning-text);
}
.nota-avviso svg { flex: none; width: 14px; height: 14px; margin-top: 1px; }
.nota-avviso p { font-size: var(--text-xs); line-height: var(--leading-md); }

@media (max-width: 880px) {
  .scheda-corpo--modulo { grid-template-columns: minmax(0, 1fr); }
  .campi-2 { grid-template-columns: minmax(0, 1fr); }
}

/* ===========================================================================
   10. SCHEDA PRATICA - rifinitura sul mock "Nuova UI" (schermo Pratica): il percorso
   a tappe nella banda di testata, il richiamo del Flag sotto la banda della card Esito,
   le due schede d'esito affiancate, il piede "bottone + guida".
   =========================================================================== */

/* ---- Percorso a tappe: cinque nodi su una riga uniti da trattini. Le tappe fatte sono
   un disco pieno con la spunta, la corrente un anello acceso col punto, le future un
   anello vuoto. E' una lettura (aria-current="step"), non una navigazione: nessun link.
   Il trattino lo porta la tappa che segue (::before), cosi' il primo nodo non ne ha. ---- */
.scheda-hero > .fasi {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: var(--space-4) 0 0;
  padding: 0;
  list-style: none;
}
.fasi__tappa { display: flex; align-items: center; gap: var(--space-2); }
.fasi__tappa + .fasi__tappa::before {
  content: "";
  display: block;
  width: 22px;
  height: 2px;
  border-radius: 1px;
  background: var(--neutral-200);
}
.fasi__tappa--fatta + .fasi__tappa::before,
.fasi__tappa--fatta + .fasi__tappa--corrente::before { background: var(--primary-700); }
.fasi__nodo {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 17px;
  height: 17px;
  border-radius: 9999px;
  border: 1.5px solid var(--neutral-300);
  background: var(--neutral-0);
  color: var(--neutral-0);
}
.fasi__nodo svg { width: 9px; height: 9px; }
.fasi__tappa--fatta .fasi__nodo { border-color: var(--primary-700); background: var(--primary-700); }
.fasi__tappa--corrente .fasi__nodo { border-width: 2px; border-color: var(--primary-700); background: var(--primary-100); }
.fasi__tappa--corrente .fasi__nodo::after { content: ""; width: 5px; height: 5px; border-radius: 9999px; background: var(--primary-700); }
.fasi__nome { font-size: var(--text-xs); font-weight: var(--fw-medium); color: var(--neutral-600); white-space: nowrap; }
.fasi__tappa--corrente .fasi__nome { font-weight: var(--fw-semibold); color: var(--neutral-900); }
.fasi__tappa--futura .fasi__nome { font-weight: var(--fw-regular); color: var(--neutral-400); }
/* La verifica che ha respinto: la tappa corrente in tono d'allarme, il nome lo dice (badge in testata). */
.fasi__tappa--allarme .fasi__nodo { border-color: var(--danger); background: var(--danger-bg); }
.fasi__tappa--allarme .fasi__nodo::after { background: var(--danger); }
.fasi__tappa--allarme .fasi__nome { color: var(--danger-text); }

/* ---- Richiamo: un riquadro tonale dentro il corpo della card (icona + testo), il tono e' quello
   del semaforo. Non e' un .avviso di pagina: non ha margine sotto proprio e sta nel ritmo della card. ---- */
.richiamo {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-3);
  border: var(--border-width) solid;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  line-height: 1.55;
}
.richiamo > svg { flex: none; width: 14px; height: 14px; margin-top: 2px; }
.richiamo__corpo { min-width: 0; }
.richiamo__corpo p { margin: 0; }
.richiamo__corpo .mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.richiamo__nota { margin-top: var(--space-1); }
.richiamo--success { background: var(--success-bg); border-color: color-mix(in srgb, var(--success) 45%, var(--success-bg)); color: var(--success-text); }
.richiamo--warning { background: var(--warning-bg); border-color: color-mix(in srgb, var(--warning) 55%, var(--warning-bg)); color: var(--warning-text); }
.richiamo--danger  { background: var(--danger-bg);  border-color: color-mix(in srgb, var(--danger) 45%, var(--danger-bg));   color: var(--danger-text); }
.richiamo--info    { background: var(--info-bg);    border-color: color-mix(in srgb, var(--info) 40%, var(--info-bg));       color: var(--info-text); }

/* ---- Scelta dell'esito: due schede affiancate (non le tre del Flag), radio accesa in brand:
   l'esito non e' un semaforo ma una decisione, il verde/rosso lo porta gia' la nota. ---- */
.scelta-rischio--esito { grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
.scelta-rischio--esito .scelta-rischio__voce { border-color: var(--neutral-200); border-radius: var(--radius-md); }
.scelta-rischio--esito .scelta-rischio__voce input { accent-color: var(--primary-700); }
.scelta-rischio--esito .scelta-rischio__voce:has(input:checked) {
  border-color: var(--primary-700);
  background: color-mix(in srgb, var(--primary-50) 60%, var(--neutral-0));
  box-shadow: 0 0 0 1px var(--primary-700);
}

/* L'obbligo nell'etichetta del campo: non un asterisco ma una parola, smorzata e calda. */
.campo__label .campo__obbligo { font-weight: var(--fw-regular); color: var(--warning-text); }

/* Piede "bottone + guida": il bottone a sinistra, la frase che dice cosa succede accanto. */
.azioni-riga--guida { align-items: center; gap: var(--space-3) var(--space-4); }
.azioni-riga--guida p { flex: 1 1 16rem; max-width: 60ch; margin: 0; font-size: var(--text-xs); }

/* ===========================================================================
   9. SCHEDA FORNITORE - riallineamento al mock "Nuova UI" (schermo Scheda).
   Le primitive sono quelle delle sezioni 7-8 (banda, striscia, tab, checklist a puntini);
   qui stanno le forme che il mock introduce per questo schermo: il tono del conteggio in
   banda, la riga mono sotto il documento, il provvedimento a celle, il registro a tabella,
   la card delle note con lo stato vuoto tratteggiato.
   =========================================================================== */

/* Il conteggio nella banda porta il tono del verdetto: "3 / 5 coperti" in ambra dice gia' che
   manca qualcosa, senza una riga di verdetto sotto. */
.scheda-sezione > h2 .scheda-sezione__conteggio--ok      { color: var(--success-text); }
.scheda-sezione > h2 .scheda-sezione__conteggio--attesa  { color: var(--warning-text); }
.scheda-sezione > h2 .scheda-sezione__conteggio--allerta { color: var(--danger-text); }

/* Chip d'avviso: un dato fuori standard e' un'annotazione ambra, non un testo smorzato. */
.chip--avviso { color: var(--warning-text); background: var(--warning-bg); border-color: color-mix(in srgb, var(--warning) 45%, var(--warning-bg)); }
.dati dd .chip { margin-left: var(--space-1); vertical-align: 1px; }

.checklist--pratica .checklist__nome { font-size: var(--text-xs); }
.scheda-main .checklist--pratica .checklist__riga { padding: 10px var(--space-4); }
/* La divergenza di catalogo e' una riga in coda, dentro il padding della card. */
.scheda-sezione > .cop-divergenza { margin: var(--space-3) var(--space-4) var(--space-4); }

/* Stato vuoto di una card (mock): icona in un cerchio tenue, titolo, frase, eventuale rimando. */
.checklist-vuoto { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 40px var(--space-6); }
.checklist-vuoto > * + * { margin-top: 0; }
.checklist-vuoto__icona {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; margin-bottom: var(--space-1);
  border-radius: var(--radius-full);
  background: var(--primary-50); color: var(--primary-700);
}
.checklist-vuoto__icona svg { width: 19px; height: 19px; }
.checklist-vuoto__icona--ok { background: var(--success-bg); color: var(--success); }
.checklist-vuoto__titolo { font-size: var(--text-sm); font-weight: var(--fw-semibold); color: var(--neutral-900); }
.checklist-vuoto > p:not(.checklist-vuoto__titolo) { max-width: 44ch; font-size: var(--text-xs); }
.checklist-vuoto > a { margin-top: var(--space-1); font-size: var(--text-xs); font-weight: var(--fw-medium); }

/* ---- Provvedimento a card (mock): la banda porta tipo, causale e stato; il corpo e' una fila di
   celle etichetta/valore come la striscia. Il filetto rosso a sinistra della vecchia forma non
   serve piu': lo stato lo dice la pastiglia nella banda, e una card chiusa (revocata, scaduta) si
   smorza appena invece di portare un bordo grigio. ---- */
.provv-elenco { display: flex; flex-direction: column; gap: var(--space-3); }
.scheda-sezione.provv { border-left: var(--border-default); opacity: 1; }
.scheda-sezione.provv--chiuso .provv__griglia { opacity: .75; }
.scheda-sezione > h2.provv__head { gap: var(--space-2) 10px; padding: 11px var(--space-4); border-bottom: var(--border-width) solid var(--neutral-100); }
.provv__causale {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: normal;
  text-transform: none;
  color: var(--neutral-800);
}
.scheda-sezione > .provv__griglia,
.scheda-sezione > .provv__griglia:last-child {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 1px;
  margin: 0;
  background: var(--neutral-100);
}
.provv__cella { display: flex; flex-direction: column; gap: 3px; padding: 12px var(--space-4); background: var(--neutral-0); }
.provv__k {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--neutral-500);
}
.provv__v { font-size: var(--text-md); color: var(--neutral-800); overflow-wrap: anywhere; }
.provv__v.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.provv__v--testo { color: var(--neutral-600); }
.scheda-sezione > .provv__revoca { margin: 0; padding: var(--space-4); border-top: var(--border-width) solid var(--neutral-100); background: var(--neutral-50); }
.scheda-sezione > .provv__revoca .azioni-riga { margin-top: var(--space-3); }

/* ---- Registro degli stati a tabella (mock): il nodo colorato della timeline resta come primo
   segno della cella del passaggio, "da" smorzato e "a" in evidenza. ---- */
/* A filo dei bordi solo chi lo chiede: il registro degli stati e le tabelle marcate `--filo`
   (stato del Worker, #141). La tabella delle Pratiche resta com'era, dentro il padding. */
.scheda-sezione > .tabella-wrap:has(> :is(.tabella--storico, .tabella--filo)) { margin: 0; border: 0; border-radius: 0; }
.tabella--storico .col-quando { width: 150px; }
.tabella--storico td.mono { color: var(--neutral-500); white-space: nowrap; }
.passaggio { display: inline-flex; align-items: center; gap: var(--space-2); }
.passaggio__nodo { flex: none; width: 9px; height: 9px; border-radius: 2px; border: 2px solid var(--primary-700); background: var(--neutral-0); }
.passaggio__nodo--provvedimento { border-color: var(--danger); background: var(--danger-bg); }
.passaggio__nodo--esito { border-color: var(--success); background: var(--success-bg); }
.passaggio__da { font-size: var(--text-xs); color: var(--neutral-600); }
.passaggio__freccia { color: var(--neutral-400); }
.passaggio__a { font-size: var(--text-xs); font-weight: var(--fw-semibold); color: var(--neutral-900); }
.passaggio__nota { font-size: var(--text-xs); color: var(--neutral-400); }

/* ---- Note operative (mock): card a larghezza contenuta, textarea e bottone primario con la
   frase di contesto accanto; senza note, un riquadro tratteggiato al posto dell'elenco. ---- */
.scheda-sezione > .nota-form { margin: var(--space-4); }
.scheda-sezione > .nota-form + * { margin-top: var(--space-5); }
.nota-form .campo__input { width: 100%; resize: vertical; font-size: var(--text-xs); }
.nota-form .campo__input::placeholder { font-size: var(--text-xs); }
.nota-form__avvertenza { margin: 0 0 6px; font-size: var(--text-xs); font-style: italic; color: var(--neutral-500); }
.nota-form__azioni { display: flex; align-items: center; gap: var(--space-3); margin-top: 10px; }
/* ---- Elenco delle note: righe a filo dei bordi, separate da un filetto e staccate dal modulo
   da un filetto pieno. Testata = autore (pieno) · quando (mono smorzato) · azione a destra;
   sotto, il testo a corpo pieno con gli a capo dell'autore. ---- */
.scheda-sezione > .note-lista,
.scheda-sezione > .note-lista:last-child { margin: 0; padding: 0; list-style: none; border-top: var(--border-default); }
.nota { padding: var(--space-3) var(--space-4); }
.nota + .nota { border-top: var(--border-width) solid color-mix(in srgb, var(--neutral-100) 60%, var(--neutral-0)); }
.nota__testata { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.nota__autore { font-size: var(--text-sm); font-weight: var(--fw-semibold); color: var(--neutral-800); }
.nota__autore .ent { font-weight: inherit; }
.nota__quando { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--neutral-500); font-variant-numeric: tabular-nums; }
.nota__azione { margin: 0 0 0 auto; display: inline-flex; }
.nota__azione .btn--piccolo { min-height: 26px; padding: 0 10px; font-size: var(--text-xs); }
.nota__testo { margin-top: var(--space-1); font-size: var(--text-md); line-height: var(--leading-md); color: var(--neutral-900); white-space: pre-wrap; overflow-wrap: anywhere; }
.scheda-sezione > .vuoto-tratteggiato {
  margin: var(--space-4);
  padding: var(--space-6);
  text-align: center;
  border: 1px dashed var(--neutral-200);
  border-radius: var(--radius-md);
}
.vuoto-tratteggiato__titolo { font-size: var(--text-xs); font-weight: var(--fw-medium); color: var(--neutral-600); }
.vuoto-tratteggiato > p:not(.vuoto-tratteggiato__titolo) { margin-top: 2px; font-size: var(--text-xs); color: var(--neutral-500); }
