/* =============================================================================================
 * JURA Club — Componenti / UI components
 * =============================================================================================
 * IT: La libreria di primitive dell'interfaccia. Ogni componente qui dentro corrisponde a un
 *     partial in `viste/parti/`: se cambia la struttura del markup, cambia anche questo file, e
 *     viceversa. Nessun valore letterale: tutto da `tokens.css`.
 *
 *     Ordine: schede · pill di stato · bottoni · banner · tabelle · moduli · dati on-chain ·
 *     stati di vista · procedura guidata · cronologia · indicatori.
 * EN: UI primitive library, one block per partial in `viste/parti/`.
 * ============================================================================================= */

/* ---------------------------------------------------------------------------------------------
 * 1. SCHEDE
 * --------------------------------------------------------------------------------------------- */

.scheda {
  background: var(--colore-superficie);
  border: 1px solid var(--colore-bordo);
  border-radius: var(--raggio);
  padding: var(--sp-5);
}
.scheda--rilievo { box-shadow: var(--ombra-sm); }

/* Il filetto d'oro in cima marca la scheda che porta la prova di certificazione. È l'uso
 * legittimo dell'oro: firma su un elemento, non superficie piena (Linee Guida §4.4). */
.scheda--sigillo { border-top: 3px solid var(--jura-oro); }

/* IT: `flex-wrap` aggiunto il 2026-08-09: senza, un titolo lungo accanto a una pill produceva una
 *     riga da oltre cento caratteri dentro una colonna da settecento pixel, e il testo usciva o si
 *     comprimeva. Una riga di intestazione deve poter andare a capo come qualunque altra. */
.scheda__testata {
  flex-wrap: wrap;
  display: flex;
  align-items: baseline;
  gap: var(--sp-4);
  margin: 0 0 var(--sp-4);
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid var(--colore-bordo);
}
.scheda__testata > :last-child { margin-left: auto; }
.scheda__titolo { margin: 0; font-size: var(--testo-md); font-weight: var(--peso-forte); }
.scheda__piede {
  margin: var(--sp-4) calc(-1 * var(--sp-5)) calc(-1 * var(--sp-5));
  padding: var(--sp-4) var(--sp-5);
  background: var(--colore-superficie-alt);
  border-top: 1px solid var(--colore-bordo);
  border-radius: 0 0 var(--raggio) var(--raggio);
  font-size: var(--testo-sm);
}

/* --- Indicatore numerico (KPI) --------------------------------------------------------------- */
/* Le schede dei numeri stanno in una griglia che le stira tutte all'altezza della più alta. Il
 * contenuto restava in cima e sotto al «3» si apriva un vuoto che si legge come un elemento non
 * caricato — segnalato dal committente esattamente così. Ora il blocco riempie la scheda e le
 * tre parti si distribuiscono, quindi i valori di schede diverse restano allineati fra loro anche
 * quando le etichette vanno a capo in modo diverso. */
/* Griglia a tre righe allineata IN ALTO, non `space-between`.
 * `space-between` distribuiva le parti sull'altezza della scheda, quindi in una scheda senza nota
 * il numero finiva in fondo e le quattro cifre della fila stavano a quattro altezze diverse — che
 * a colpo d'occhio si legge come «non ha caricato». Con `align-content: start` e l'etichetta che
 * riserva due righe, i valori di schede diverse cadono tutti sulla stessa linea. */
.kpi {
  display: grid;
  grid-template-rows: auto auto auto;
  align-content: start;
  gap: var(--sp-1);
  height: 100%;
}
.kpi__etichetta {
  /* Due righe piene di etichetta: 2 x 1.55 di interlinea = 3.1em. Con 2.2em la quarta scheda
   * restava un gradino più in basso delle altre, che è proprio il difetto che si voleva chiudere. */
  min-height: 3.1em;
  font-size: var(--testo-xs);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--colore-testo-tenue);
}
.kpi__valore {
  font-family: var(--font-titolo);
  font-size: var(--testo-2xl);
  font-weight: var(--peso-forte);
  color: var(--colore-testo-forte);
  line-height: 1.1;
}
.kpi__nota {
  min-height: 2.4em;              /* una nota assente non fa risalire il numero */
  font-size: var(--testo-xs);
  color: var(--colore-testo-tenue);
}

/* ---------------------------------------------------------------------------------------------
 * 2. PILL DI STATO
 *
 * REGOLA NON NEGOZIABILE: la pill porta SEMPRE il testo. Il pallino colorato è un rinforzo
 * ridondante, mai il portatore del significato (Linee Guida §4.3 e §10). Chi non distingue i
 * colori legge esattamente la stessa informazione.
 * --------------------------------------------------------------------------------------------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 2px var(--sp-3);
  border-radius: var(--raggio-pill);
  border: 1px solid;
  font-size: var(--testo-xs);
  font-weight: var(--peso-forte);
  line-height: 1.7;
  /* `nowrap` con un tetto: una pill non si spezza, ma non sfonda nemmeno la cella che la
   * contiene — tronca, e il testo intero resta nel `title` dove la vista lo fornisce. */
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  /* IT: `text-overflow` NON funzionava, e la pill tagliava netto invece di mettere i puntini.
   *     La ragione: `display: inline-flex`. `text-overflow` agisce su un contenitore a blocco che
   *     trabocca, non sul testo anonimo dentro un contenitore flessibile — la dichiarazione era
   *     lì da sempre, corretta come intenzione e inerte come effetto.
   *     `min-width: 0` è la seconda metà: senza, un elemento flessibile non scende sotto la
   *     larghezza del proprio contenuto e non trabocca mai, quindi non tronca mai. */
  text-overflow: ellipsis;
  min-width: 0;
}
.pill::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: 0 0 6px;
}

.pill--ok     { color: var(--stato-ok-testo);     background: var(--stato-ok-fondo);     border-color: var(--stato-ok-bordo); }
.pill--attesa { color: var(--stato-attesa-testo); background: var(--stato-attesa-fondo); border-color: var(--stato-attesa-bordo); }
.pill--errore { color: var(--stato-errore-testo); background: var(--stato-errore-fondo); border-color: var(--stato-errore-bordo); }
.pill--info   { color: var(--stato-info-testo);   background: var(--stato-info-fondo);   border-color: var(--stato-info-bordo); }
.pill--neutro { color: var(--colore-testo-tenue); background: var(--colore-superficie-alt); border-color: var(--colore-bordo-ui); }
/* IT: RETTIFICA DEL 2026-08-09 (T-191). Il commento che stava qui diceva che le due varianti
 *     seguenti non erano usate e restavano di proposito, in attesa delle schermate da fare.
 *     Per `.pill--oro` **non è più vero**: la usa `viste/titolare/storico.eta:24` per il filtro
 *     attivo. Un commento che descrive un mondo che non c'è più è peggio di nessun commento —
 *     chi legge decide sulla base di ciò che trova scritto, e qui avrebbe potuto toglierla
 *     credendo di rimuovere codice morto.
 *     Il ragionamento sulle varianti previste dal contratto degli stati di vista (§4.1) resta
 *     valido per quelle che davvero non sono ancora usate. */
.pill--oro    { color: var(--jura-oro-scuro); background: var(--jura-avorio-alt); border-color: var(--jura-hairline); }

/* Badge di ruolo nella barra superiore: stesso principio, fondo scuro. */
.badge-ruolo {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 3px var(--sp-3);
  border-radius: var(--raggio-pill);
  border: 1px solid rgba(198, 163, 92, 0.5);
  background: rgba(198, 163, 92, 0.14);
  color: var(--jura-oro);
  font-size: var(--testo-xs);
  font-weight: var(--peso-forte);
  letter-spacing: 0.03em;
}

/* ---------------------------------------------------------------------------------------------
 * 3. BOTTONI
 *
 * Tre livelli e non di più. Il primario è Blu Notte; l'accento in Oro è riservato all'azione
 * che qualifica il ruolo (emettere una JURA, ancorare un hash) e ne compare al più UNO per
 * schermata. Il distruttivo è testuale finché non è confermato: un bottone rosso pieno invita a
 * premerlo, ed è l'ultima cosa che serve su un'azione irreversibile.
 * --------------------------------------------------------------------------------------------- */

.bottone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--raggio);
  border: 1px solid transparent;
  font-size: var(--testo-sm);
  font-weight: var(--peso-forte);
  text-decoration: none;
  cursor: pointer;
  /* IT: Anche `transform` e `box-shadow` sono in transizione, perché da oggi il bottone si abbassa
   *     alla pressione e si solleva appena al sorvolo. Durata svelta: la risposta a un gesto deve
   *     sembrare immediata — sopra i ~150 ms si percepisce come ritardo, non come movimento. */
  transition: background   var(--durata-svelta) var(--curva),
              border-color var(--durata-svelta) var(--curva),
              box-shadow   var(--durata-svelta) var(--curva),
              transform    var(--durata-svelta) var(--curva);
}

/* IT: GLI STATI CHE MANCAVANO A TUTTE E CINQUE LE VARIANTI (T-189).
 *     Ogni variante aveva il proprio `:hover` e nient'altro: nessun `:active`, che in tutto il
 *     progetto non compariva **nemmeno una volta**, e nessun `:focus-visible` proprio — solo
 *     l'anello globale, che dice «sei qui» ma non «questo si preme».
 *
 *     Le tre righe qui sotto valgono per tutte le varianti insieme, e non è pigrizia: sollevarsi
 *     al sorvolo, abbassarsi alla pressione e portare l'anello sono comportamenti del BOTTONE, non
 *     della sua tinta. Scriverli cinque volte avrebbe creato cinque occasioni di farli divergere.
 *
 *     `:active` è quello che conta di più ed è quello che mancava: senza, premere un bottone e
 *     premere un'immagine di un bottone sono la stessa esperienza. Un pixel basta — deve sentirsi,
 *     non vedersi. */
.bottone:hover:not(:disabled):not([aria-disabled="true"]) {
  transform: translateY(calc(-1 * var(--pressione)));
  box-shadow: var(--ombra-sm);
}
.bottone:active:not(:disabled):not([aria-disabled="true"]) {
  transform: translateY(var(--pressione));
  box-shadow: none;
}
.bottone:focus-visible { box-shadow: var(--ombra-sm); }

/* IT: IL BOTTONE CHE STA INVIANDO (T-190). Lo marca `arricchimento.mjs` all'invio, e serve a
 *     distinguerlo dai settanta bottoni inerti per scelta: quelli sono spenti e restano spenti,
 *     questo sta lavorando. Senza la distinzione, premere «Invia» su una rete lenta produce un
 *     bottone grigio indistinguibile da uno rotto — e chi guarda ripreme.
 *     Il cursore è `progress` e non `not-allowed`: l'uno dice «aspetta», l'altro «non si può». */
/* IT: L'AZIONE CHE LA SCHERMATA PROPONE si distingue da quelle che la schermata permette.
 *     (Strato di guida, 2026-08-09.) Su schermate con quattro o cinque bottoni — l'accordo, la
 *     conferma d'incasso, l'emissione — «che cosa devo fare adesso» è la domanda che ogni utente
 *     si pone per primo, e il colore da solo non basta a rispondere: il bottone d'accento è anche
 *     quello di azioni secondarie.
 *
 *     Il richiamo dura DUE BATTITI e si ferma, come il passo corrente e per la stessa ragione: un
 *     bottone che pulsa per sempre si smette di vedere. Ed è sull'ombra, non sulla dimensione: un
 *     bersaglio che cambia misura mentre ci si avvicina col mouse è un bersaglio che si manca. */
.bottone--proposto { animation: richiamo-oro 1.6s var(--curva) 2; }

/* IT: L'azione IRREVERSIBILE non pulsa e non invita: si annuncia. Il filetto a sinistra la separa
 *     dalle altre senza attirare il dito — la fretta, qui, è precisamente ciò da evitare. */
.bottone--irreversibile { box-shadow: inset 3px 0 0 var(--stato-errore); }

@media (prefers-reduced-motion: reduce) {
  .bottone--proposto { animation: none; }
}

.bottone[data-inviando] { opacity: 0.7; cursor: progress; }
.bottone[data-inviando]::after {
  content: "";
  width: 0.8em; height: 0.8em;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: gira 640ms linear infinite;
}
@keyframes gira { to { transform: rotate(360deg); } }

/* IT: Sotto movimento ridotto l'anello non gira: resta un cerchio fermo e incompleto, che dice
 *     comunque «in corso» senza muoversi. Spegnere l'animazione e basta lascerebbe un segno che
 *     sembra un errore di resa. */
@media (prefers-reduced-motion: reduce) {
  .bottone[data-inviando]::after { animation: none; border-top-color: currentColor; opacity: 0.5; }
}

/* IT: Una regione che sta cambiando lo dichiara, e l'aspetto lo segue. Vale per i moduli d'azione
 *     come per quelli di contatto: `aria-busy` è già il modo standard di dirlo, non serve
 *     inventare una classe. */
[aria-busy="true"] { cursor: progress; }
[aria-busy="true"] .campo { opacity: 0.75; transition: opacity var(--durata) var(--curva); }

.bottone--primario {
  background: var(--colore-primario);
  color: var(--jura-avorio);
  border-color: var(--colore-primario);
}
.bottone--primario:hover { background: var(--jura-blu-notte-chiaro); color: var(--jura-avorio); }

.bottone--accento {
  background: var(--jura-oro);
  color: var(--jura-blu-notte);
  border-color: var(--jura-oro-scuro);
}
.bottone--accento:hover { background: var(--jura-oro-chiaro); color: var(--jura-blu-notte); }

.bottone--secondario {
  background: var(--colore-superficie);
  color: var(--colore-testo-forte);
  border-color: var(--colore-bordo-ui);
}
.bottone--secondario:hover { background: var(--colore-superficie-alt); }

.bottone--fantasma {
  background: transparent;
  color: var(--colore-testo-forte);
  border-color: transparent;
  padding-left: var(--sp-2);
  padding-right: var(--sp-2);
}
.bottone--fantasma:hover { background: var(--colore-superficie-alt); }

.bottone--pericolo { background: transparent; color: var(--stato-errore); border-color: var(--stato-errore-bordo); }
.bottone--pericolo:hover { background: var(--stato-errore-fondo); }

.bottone--grande { padding: var(--sp-3) var(--sp-5); font-size: var(--testo-md); }
.bottone--pieno  { width: 100%; }

/* IT: UN CONTROLLO INERTE DEVE POTER DIRE PERCHÉ LO È (T-186).
 *
 *     `pointer-events: none` è stato tolto, e non è un dettaglio di stile: su un elemento
 *     `disabled` non impediva nulla — l'attributo blocca già attivazione ed eventi — mentre
 *     impediva due cose utili. La prima è il cursore qui sotto, che con gli eventi spenti il
 *     browser non applica: il `cursor: not-allowed` c'era da sempre e non si è mai visto. La
 *     seconda è il suggerimento nativo, cioè l'unico modo che il motivo scritto in `data-inerte`
 *     aveva di arrivare a chi guarda (vedi `server/template.mjs`, `dichiaraMotiviInerti`).
 *
 *     Se un giorno servisse un controllo inerte ma FOCALIZZABILE — `aria-disabled="true"` senza
 *     `disabled`, che è la forma accessibile — quello sì avrà bisogno di essere reso inattivo, ma
 *     con un gestore che rifiuta l'attivazione, non con una regola di stile: una difesa scritta
 *     nel foglio di stile si aggira spegnendo il foglio di stile. */
.bottone[aria-disabled="true"], .bottone:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}


/* ---------------------------------------------------------------------------------------------
 * 4. BANNER
 * --------------------------------------------------------------------------------------------- */

.banner {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-4);
  border: 1px solid;
  border-left-width: 4px;
  border-radius: var(--raggio);
  font-size: var(--testo-sm);
}
.banner__testo { margin: 0; }
.banner__testo strong { display: block; margin-bottom: 2px; }

.banner--info   { background: var(--stato-info-fondo);   border-color: var(--stato-info-bordo);   border-left-color: var(--stato-info); }
.banner--ok     { background: var(--stato-ok-fondo);     border-color: var(--stato-ok-bordo);     border-left-color: var(--stato-ok); }
.banner--attesa { background: var(--stato-attesa-fondo); border-color: var(--stato-attesa-bordo); border-left-color: var(--stato-attesa); }
.banner--errore { background: var(--stato-errore-fondo); border-color: var(--stato-errore-bordo); border-left-color: var(--stato-errore); }
/* Avorio/oro: usato per gli avvisi di dominio che non sono errori ma vincoli da leggere — per
 * esempio «il pagamento è regolato fuori dalla piattaforma» (Wireframe §5.6). */
.banner--avviso { background: var(--jura-avorio-alt); border-color: var(--jura-hairline); border-left-color: var(--jura-oro); }

/* --- Banner dei dati dimostrativi -------------------------------------------------------------
 * Sta in cima a ogni pagina e non si può chiudere. È una scelta deliberata: la regola di
 * progetto vieta di presentare come reale ciò che non lo è, e un avviso che l'utente può far
 * sparire al primo clic smette di proteggere esattamente quando servirebbe. Sparisce da solo il
 * giorno in cui la pagina legge dal backend. */
.banner-dimostrativo {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-5);
  background: repeating-linear-gradient(
    135deg,
    var(--jura-avorio-alt) 0 12px,
    var(--jura-avorio-rigato) 12px 24px
  );
  border-bottom: 1px solid var(--jura-hairline);
  color: var(--stato-attesa-testo);
  font-size: var(--testo-xs);
  font-weight: var(--peso-forte);
  letter-spacing: 0.02em;
}
.banner-dimostrativo span { color: var(--colore-testo-tenue); font-weight: var(--peso-normale); }

/* ---------------------------------------------------------------------------------------------
 * 5. TABELLE
 *
 * Sotto i 720px le tabelle dense diventano liste di schede (Wireframe §8). La trasformazione è
 * fatta in CSS con `data-etichetta` sulle celle: nessun secondo markup da tenere allineato.
 * --------------------------------------------------------------------------------------------- */

.tabella { width: 100%; border-collapse: collapse; font-size: var(--testo-sm); }
.tabella th {
  text-align: left;
  padding: var(--sp-3) var(--sp-4);
  background: var(--colore-superficie-alt);
  border-bottom: 1px solid var(--colore-bordo-ui);
  font-size: var(--testo-xs);
  font-weight: var(--peso-forte);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--colore-testo-tenue);
  white-space: nowrap;
}
.tabella td { padding: var(--sp-4); border-bottom: 1px solid var(--colore-bordo); vertical-align: top; }
/* IT: L'evidenziazione della riga è un AIUTO ALLA LETTURA, non la promessa di un'azione: su una
 *     tabella densa serve a non perdere la riga mentre l'occhio attraversa le colonne. Per questo
 *     resta su tutte le righe e il cursore NON cambia — è il cursore, non il fondo, a dire che
 *     qualcosa si può premere.
 *
 *     `:focus-within` è ciò che mancava (T-189): chi arriva con la tastiera dentro un link o un
 *     bottone della riga otteneva l'anello sul solo controllo e nessun riscontro sulla riga, cioè
 *     perdeva esattamente l'aiuto che il sorvolo dà a chi usa il mouse. Su una tabella di venti
 *     colonne è la differenza fra sapere dove si è e contare le celle. */
.tabella tbody tr { transition: background var(--durata-svelta) var(--curva); }
.tabella tbody tr:hover,
.tabella tbody tr:focus-within { background: var(--jura-avorio); }
.tabella__numerico { text-align: right; font-family: var(--font-mono); }

/* IT: UN IDENTIFICATIVO NON SI SPEZZA A METÀ (rifinitura, 2026-08-09).
 *     `.mono` porta `overflow-wrap: anywhere` (`base.css:84`), che non si limita a mandare a capo:
 *     **riduce la larghezza minima intrinseca** dell'elemento. Dentro una tabella, dove le
 *     intestazioni sono `white-space: nowrap` e si prendono lo spazio per prime, alla colonna dei
 *     valori tecnici non resta niente, e si leggeva «JURA-004 / 2» e «08/08/2026, 1 / 8:00».
 *
 *     Un identificativo spezzato non è un problema di estetica: è un dato che chi legge copia, e
 *     `JURA-004` non è `JURA-0042`. Nel corpo del testo `anywhere` resta giusto — lì il valore
 *     deve stare nella colonna di lettura; in tabella no, e la colonna si allarga. */
.tabella td .mono,
.tabella td.mono,
.tabella .valore-mono { overflow-wrap: normal; word-break: normal; }

@media (max-width: 720px) {
  .tabella, .tabella tbody, .tabella tr, .tabella td { display: block; width: 100%; }
  .tabella thead { display: none; }
  .tabella tr {
    border: 1px solid var(--colore-bordo);
    border-radius: var(--raggio);
    margin-bottom: var(--sp-3);
    background: var(--colore-superficie);
  }
  /* IT: `flex-wrap: wrap` e non `overflow-wrap: anywhere` (rifinitura, 2026-08-13, T-220).
   *     A schermo stretto l'etichetta si prende il 40% fisso e al valore resta il 60% meno lo
   *     spazio fra i due. Quando il valore contiene una parola più lunga di quel che resta — un
   *     identificativo monospazio, una parola tecnica — la cella non si restringe sotto la sua
   *     parola più lunga e la tabella esce dallo schermo. Sulla policy dei cookie usciva di 3px:
   *     poco, e comunque testo tagliato su un telefono.
   *
   *     La via breve sarebbe `overflow-wrap: anywhere`, e sarebbe sbagliata: qui sopra c'è la
   *     regola opposta, scritta il 9 agosto, che TOGLIE lo spezzamento dentro le tabelle perché
   *     `JURA-004` non è `JURA-0042`. Mandare il valore a capo SOTTO l'etichetta gli restituisce
   *     tutta la larghezza della scheda senza spezzare niente. */
  .tabella td {
    border-bottom: 1px solid var(--colore-bordo);
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
  }
  .tabella tr td:last-child { border-bottom: 0; }
  .tabella td::before {
    content: attr(data-etichetta);
    flex: 0 0 40%;
    font-size: var(--testo-xs);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--colore-testo-tenue);
    font-weight: var(--peso-forte);
  }
}

/* --- Lista di definizioni: la resa canonica dei metadati di un titolo ------------------------ */
/* LA COLONNA DELLE ETICHETTE HA UN TETTO, e prima non ce l'aveva.
 * `max-content` cresce senza limite: dentro una scheda stretta l'etichetta più lunga —
 * «IMPRONTA DEL FASCICOLO» — si prendeva quasi tutto lo spazio e al valore ne restavano ~90px,
 * con l'effetto che «ERC-1155» andava a capo a metà parola e un indirizzo diventava una colonnina
 * di tre righe. Il tetto in `ch` è legato alla dimensione del carattere, quindi regge anche se
 * qualcuno ingrandisce il testo. */
.dati {
  display: grid;
  grid-template-columns: minmax(0, min(max-content, 20ch)) minmax(0, 1fr);
  gap: var(--sp-3) var(--sp-5);
  margin: 0;
}
.dati dt { overflow-wrap: break-word; }
.dati dt { font-size: var(--testo-xs); text-transform: uppercase; letter-spacing: 0.06em; color: var(--colore-testo-tenue); }
.dati dd { margin: 0; min-width: 0; }
@media (max-width: 560px) { .dati { grid-template-columns: minmax(0, 1fr); gap: var(--sp-1) 0; } .dati dd { margin-bottom: var(--sp-3); } }

/* Query di CONTENITORE, non di finestra: `.dati` compare sia nella colonna principale sia in
 * quella laterale, e a rompersi non è lo schermo — è il posto in cui si trova. */
.scheda, .blocco-onchain, .segnaposto__corpo { container-type: inline-size; }
@container (max-width: 26rem) {
  .dati { grid-template-columns: minmax(0, 1fr); gap: var(--sp-1) 0; }
  .dati dd { margin-bottom: var(--sp-3); }
  .dati dd:last-child { margin-bottom: 0; }
}

/* ---------------------------------------------------------------------------------------------
 * 6. MODULI
 * --------------------------------------------------------------------------------------------- */

.campo { display: flex; flex-direction: column; gap: var(--sp-1); margin-bottom: var(--sp-4); }
.campo__etichetta { font-size: var(--testo-sm); font-weight: var(--peso-forte); color: var(--colore-testo-forte); }
.campo__aiuto { font-size: var(--testo-xs); color: var(--colore-testo-tenue); }
.campo__errore { font-size: var(--testo-xs); color: var(--stato-errore); font-weight: var(--peso-forte); }

/* IT: `password` mancava dall'elenco, e non per una ragione: il campo della password su `/accesso`
 *     era l'unico controllo di modulo del portale reso senza bordo, senza spaziatura e senza
 *     larghezza piena. Un elenco di tipi enumerati a mano è esattamente il posto in cui una cosa
 *     del genere si perde in silenzio. */
.campo input[type="text"], .campo input[type="email"], .campo input[type="number"],
.campo input[type="password"], .campo input[type="date"], .campo select, .campo textarea {
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--colore-bordo-campo);
  border-radius: var(--raggio);
  background: var(--colore-superficie);
  font-size: var(--testo-md);
  width: 100%;
  transition: border-color var(--durata-svelta) var(--curva),
              box-shadow  var(--durata-svelta) var(--curva);
}

/* IT: Il sorvolo su un campo compilabile — e solo su quello: un campo spento non deve promettere
 *     che ci si possa scrivere. */
.campo input:hover:not(:disabled):not([readonly]),
.campo select:hover:not(:disabled),
.campo textarea:hover:not(:disabled) { border-color: var(--colore-bordo-ui); }

/* IT: Il fuoco su un campo si vede DUE volte: l'anello globale di `base.css`, che vale per
 *     chiunque arrivi da tastiera, e il bordo colorato, che dice quale campo è attivo anche a chi
 *     è arrivato col mouse. Erano due cose che facevano lo stesso lavoro a metà. */
.campo input:focus, .campo select:focus, .campo textarea:focus {
  border-color: var(--colore-focus);
  box-shadow: 0 0 0 3px var(--colore-focus-tenue);
}

/* IT: TRENTUNO DEI SETTANTA CONTROLLI INERTI SONO CAMPI, non bottoni (T-186), e finora erano resi
 *     identici a un campo compilabile: nulla diceva a chi guarda che lì dentro non si scrive.
 *     La regola sta sui CONTROLLI e non su `.campo`, che è il contenitore e non è mai disabilitato
 *     — un errore che ho fatto scrivendo questa regola la prima volta. */
.campo input:disabled, .campo select:disabled, .campo textarea:disabled,
.campo input[readonly], .campo textarea[readonly] {
  opacity: 0.65;
  cursor: not-allowed;
  background: var(--colore-superficie-alt);
}

/* IT: Il campo in errore, e l'errore che lo accompagna. Vedi T-187: la mappa degli errori esisteva
 *     già lato server e veniva scartata prima di arrivare qui. */
.campo--errore input, .campo--errore select, .campo--errore textarea {
  border-color: var(--stato-errore);
}
.campo--errore input:focus, .campo--errore select:focus, .campo--errore textarea:focus {
  box-shadow: 0 0 0 3px var(--stato-errore-fondo);
}

/* Un campo che accetta un indirizzo o un hash è monospazio dal momento in cui si digita: chi
 * incolla vede subito se ha incollato la cosa giusta. */
.campo input.mono { font-family: var(--font-mono); font-size: var(--testo-sm); }

/* Area di caricamento tratteggiata (Wireframe §1.1). */
.zona-upload {
  border: 2px dashed var(--colore-bordo-campo);
  border-radius: var(--raggio-lg);
  padding: var(--sp-6);
  text-align: center;
  background: var(--colore-superficie-alt);
  color: var(--colore-testo-tenue);
}
.zona-upload strong { display: block; color: var(--colore-testo-forte); margin-bottom: var(--sp-1); }

/* ---------------------------------------------------------------------------------------------
 * 7. DATI ON-CHAIN E OFF-CHAIN
 *
 * La distinzione visiva fra ciò che è verificabile sulla catena e ciò che sta nei nostri
 * archivi è un requisito di prodotto, non una finezza grafica (Linee Guida §9.1): l'utente deve
 * sempre sapere che cosa può verificare da sé e che cosa gli stiamo dichiarando noi.
 * --------------------------------------------------------------------------------------------- */

.provenienza {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 1px var(--sp-2);
  border-radius: var(--raggio-sm);
  font-size: 10px;
  font-weight: var(--peso-forte);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  border: 1px solid;
}
.provenienza--onchain  { color: var(--stato-info); border-color: var(--stato-info-bordo); background: var(--stato-info-fondo); }
.provenienza--offchain { color: var(--colore-testo-tenue); border-color: var(--colore-bordo-ui); background: var(--colore-superficie-alt); }

/* Il blocco che contiene la prova on-chain ha un fondo proprio e un filetto a sinistra: si
 * distingue a colpo d'occhio dal resto della scheda. */
.blocco-onchain {
  background: var(--colore-superficie-alt);
  border: 1px solid var(--colore-bordo-ui);
  border-left: 3px solid var(--stato-info);
  border-radius: var(--raggio);
  padding: var(--sp-5);
}

/* Valore tecnico abbreviato con l'originale disponibile al sorvolo e alla copia. */
.valore-mono {
  display: inline-block;
  max-width: 100%;
  font-family: var(--font-mono);
  font-size: var(--testo-sm);
  background: var(--colore-superficie-alt);
  border: 1px solid var(--colore-bordo-ui);
  border-radius: var(--raggio-sm);
  padding: 1px var(--sp-2);
  /* Una riga sola, troncata con l'ellissi. Il valore INTERO resta nel `title` — visibile al
   * sorvolo — ed è quello che viene copiato al clic. Un hash spezzato su tre righe non è più
   * leggibile di uno troncato: è solo più ingombrante, e rompe l'allineamento della colonna. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
  transition: background var(--durata-svelta) var(--curva), border-color var(--durata-svelta) var(--curva);
}

/* IT: QUANDO LO SCRIPT NE FA UN PULSANTE, DEVE AVERE L'ASPETTO DI UN PULSANTE (T-189).
 *     `arricchimento.mjs` prende ogni `.valore-mono[title]`, gli dà `role="button"`,
 *     `tabindex="0"` e il cursore `copy` — **iniettandolo in linea**, perché il foglio di stile non
 *     sapeva nulla di tutto questo. Il risultato era un elemento annunciato come pulsante ai
 *     lettori di schermo, raggiungibile da tastiera, e visivamente identico a un'etichetta inerte.
 *
 *     Le regole guardano `[role="button"]`, cioè lo stato che lo script ha davvero applicato: a
 *     script spento nulla di tutto questo compare, e il valore resta l'etichetta ferma che era —
 *     che è il comportamento giusto, perché senza script non c'è nulla da copiare. */
.valore-mono[role="button"] { cursor: copy; }
.valore-mono[role="button"]:hover { background: var(--jura-avorio); border-color: var(--colore-bordo-ui); }
.valore-mono[role="button"]:active { background: var(--colore-superficie-alt); }

/* ---------------------------------------------------------------------------------------------
 * 8. STATI DI VISTA
 *
 * Il piano del frontend impone sette stati obbligatori per ogni schermata. Qui vivono quelli che
 * hanno una resa propria: vuoto, errore, permesso negato, segnaposto, caricamento.
 * --------------------------------------------------------------------------------------------- */

.stato-vista {
  text-align: center;
  padding: var(--sp-7) var(--sp-5);
  border: 1px dashed var(--colore-bordo-ui);
  border-radius: var(--raggio-lg);
  background: var(--colore-superficie);
  color: var(--colore-testo-tenue);
}
.stato-vista__titolo {
  font-family: var(--font-titolo);
  font-size: var(--testo-lg);
  color: var(--colore-testo-forte);
  margin-bottom: var(--sp-2);
}
.stato-vista__testo { max-width: 46ch; margin: 0 auto var(--sp-4); }

/* Scheletro di caricamento. Il piano vieta lo spinner a pieno schermo: il contenuto si annuncia
 * nella forma che avrà, così la pagina non «salta» quando arriva. */
.scheletro {
  background: linear-gradient(90deg, var(--colore-superficie-alt) 25%, var(--ui-superficie-scura) 37%, var(--colore-superficie-alt) 63%);
  background-size: 400% 100%;
  border-radius: var(--raggio-sm);
  height: 1em;
  animation: scheletro 1.4s ease infinite;
}
@keyframes scheletro { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }
@media (prefers-reduced-motion: reduce) { .scheletro { animation: none; } }

/* --- Segnaposto di schermata non ancora realizzata --------------------------------------------
 * Dichiara che cosa mostrerà, per quale ruolo e da quale fonte prenderà i dati. Una pagina
 * «in costruzione» che non dice nulla è peggio di un errore: fa credere che manchi solo la
 * grafica. Questa dice esattamente che cosa manca. */
.segnaposto { border: 1px solid var(--colore-bordo); border-radius: var(--raggio); overflow: hidden; }
.segnaposto__testata {
  padding: var(--sp-3) var(--sp-4);
  background: var(--jura-avorio-alt);
  border-bottom: 1px solid var(--jura-hairline);
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
}
.segnaposto__corpo { padding: var(--sp-4); background: var(--colore-superficie); }
.segnaposto__scheletri { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-4); }
.segnaposto__scheletri .scheletro:nth-child(2) { width: 82%; }
.segnaposto__scheletri .scheletro:nth-child(3) { width: 64%; }

/* ---------------------------------------------------------------------------------------------
 * 9. PROCEDURA GUIDATA (stepper)
 * --------------------------------------------------------------------------------------------- */

.passi { display: flex; gap: var(--sp-3); list-style: none; padding: 0; margin: 0 0 var(--sp-6); flex-wrap: wrap; }
.passo {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--colore-bordo-ui);
  border-radius: var(--raggio-pill);
  background: var(--colore-superficie);
  font-size: var(--testo-sm);
  color: var(--colore-testo-tenue);
}
.passo__numero {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--colore-superficie-alt);
  font-size: var(--testo-xs); font-weight: var(--peso-forte);
}
.passo { transition: border-color var(--durata) var(--curva), background var(--durata) var(--curva); }

/* IT: IL PASSO CORRENTE SI FA TROVARE (strato di guida, 2026-08-09).
 *     Prima si distingueva per colore e peso: su una fila di sei pillole quasi uguali, chi guarda
 *     una schermata per la prima volta ci mette qualche secondo a capire dove si trova, e in una
 *     dimostrazione quei secondi li spende chi presenta a spiegare invece che a mostrare.
 *
 *     L'alone pulsa **due volte e si ferma**. Non è una decisione estetica: un movimento
 *     perpetuo su una schermata di lavoro diventa rumore entro un minuto, e la prima cosa che
 *     l'occhio impara a fare è ignorarlo. Due battiti dicono «guarda qui» e poi tacciono. */
.passo--corrente {
  border-color: var(--jura-oro);
  background: var(--jura-avorio-alt);
  color: var(--colore-testo-forte);
  font-weight: var(--peso-forte);
  animation: richiamo-oro 1.6s var(--curva) 2;
}
.passo--corrente .passo__numero { background: var(--jura-oro); color: var(--jura-blu-notte); }
.passo--fatto { color: var(--stato-ok); border-color: var(--stato-ok-bordo); background: var(--stato-ok-fondo); }
.passo--fatto .passo__numero { background: var(--stato-ok); color: var(--ui-bianco); }

/* IT: Il segno di spunta del passo compiuto si disegna invece di comparire. Dura poco più di un
 *     terzo di secondo: quanto basta a farsi notare da chi stava guardando altrove. */
.passo--fatto .passo__numero { animation: spunta 400ms var(--curva) both; }

@keyframes richiamo-oro {
  0%, 100% { box-shadow: 0 0 0 0 rgba(198, 163, 92, 0); }
  50%      { box-shadow: 0 0 0 5px rgba(198, 163, 92, 0.28); }
}
@keyframes spunta {
  from { transform: scale(0.6); opacity: 0; }
  to   { transform: scale(1);   opacity: 1; }
}

/* IT: `reduce` azzera, non addolcisce. Chi ha chiesto meno movimento non deve vedere un richiamo
 *     più lento: non deve vederlo. Il passo corrente resta distinguibile per colore e peso, che
 *     è ciò che faceva prima — nessuna informazione va persa. */
@media (prefers-reduced-motion: reduce) {
  .passo--corrente,
  .passo--fatto .passo__numero { animation: none; }
}

/* ---------------------------------------------------------------------------------------------
 * 10. CRONOLOGIA
 *
 * La macchina a stati di un accordo va letta come una storia, non come una tabella: chi ha fatto
 * che cosa, quando, e che cosa manca adesso.
 * --------------------------------------------------------------------------------------------- */

.cronologia { list-style: none; margin: 0; padding: 0 0 0 var(--sp-5); border-left: 2px solid var(--colore-bordo); }
.cronologia__voce { position: relative; padding: 0 0 var(--sp-4) var(--sp-4); }
.cronologia__voce::before {
  content: "";
  position: absolute;
  left: calc(-1 * var(--sp-5) - 5px);
  top: 6px;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--colore-superficie);
  border: 2px solid var(--colore-bordo-ui);
}
.cronologia__voce--fatto::before   { background: var(--stato-ok);     border-color: var(--stato-ok); }
.cronologia__voce--corrente::before { background: var(--jura-oro);    border-color: var(--jura-oro-scuro); }
.cronologia__voce--errore::before  { background: var(--stato-errore); border-color: var(--stato-errore); }

/* IT: LA VOCE APPENA ACCADUTA si accende e si spegne (strato di guida, 2026-08-09).
 *     Dopo un atto, la cronologia dell'accordo ha una riga in più — ed è **in fondo**, dove chi ha
 *     appena premuto non sta guardando. Senza un segno, l'unica prova che qualcosa è cambiato è la
 *     fascia in cima, e chi presenta deve dire «guardate qui sotto». Il richiamo dura un secondo e
 *     mezzo e poi la riga torna come le altre: ha fatto il suo lavoro.
 *
 *     Lo applica lo SCRIPT, non il foglio (D-084): a JavaScript spento la riga c'è comunque, ferma
 *     e completa, ed è il comportamento giusto — la riga è informazione, il richiamo è comodità. */
.cronologia__voce--nuova { animation: richiamo-riga 1500ms var(--curva) both; }
@keyframes richiamo-riga {
  0%   { background: var(--jura-avorio-alt); box-shadow: -12px 0 0 var(--jura-avorio-alt); }
  100% { background: transparent;            box-shadow: -12px 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .cronologia__voce--nuova { animation: none; }
}

/* IT: Il passo ANCORA DA COMPIERE. Trovato mancante il 2026-08-09 dalla prova «ogni classe usata
 *     dalle viste applicative esiste in un foglio di stile», il giorno stesso in cui la prova è
 *     nata: `accordi/accordo.eta:64` genera `--attesa` da `esito === "atteso"`, e questa regola non
 *     esisteva. Il passo futuro veniva reso identico a quello neutro.
 *
 *     Non è una regola scritta per far tacere una verifica — il pallino cavo era già il valore di
 *     partenza, ma il TESTO no: un passo che deve ancora accadere è raccontato con lo stesso peso
 *     di uno accaduto, e su una macchina a stati che si legge come una storia è proprio la
 *     distinzione che serve. Il pallino resta cavo per scelta dichiarata, la descrizione si
 *     attenua. */
.cronologia__voce--attesa::before { background: var(--colore-superficie); border-color: var(--colore-bordo-ui); }
.cronologia__voce--attesa .cronologia__cosa { font-weight: var(--peso-normale); color: var(--colore-testo-tenue); }
.cronologia__quando { font-size: var(--testo-xs); color: var(--colore-testo-tenue); font-family: var(--font-mono); }
.cronologia__cosa { font-weight: var(--peso-forte); color: var(--colore-testo-forte); }

/* ---------------------------------------------------------------------------------------------
 * 11. INDICATORE DI SERVIZIO (semaforo)
 * --------------------------------------------------------------------------------------------- */

.servizio { display: flex; align-items: baseline; gap: var(--sp-3); font-size: var(--testo-sm); flex-wrap: wrap; }
.servizio__spia { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 8px; }
.servizio--ok     .servizio__spia { background: var(--stato-ok); }
.servizio--attesa .servizio__spia { background: var(--stato-attesa); }
.servizio--errore .servizio__spia { background: var(--stato-errore); }
.servizio__esito { margin-left: auto; font-size: var(--testo-xs); color: var(--colore-testo-tenue); text-align: right; }

/* ---------------------------------------------------------------------------------------------
 * 12. SCHEDA-TITOLO (la card di una JURA)
 * --------------------------------------------------------------------------------------------- */

.titolo-card {
  display: flex; flex-direction: column; gap: var(--sp-3);
  background: var(--colore-superficie);
  border: 1px solid var(--colore-bordo);
  border-top: 3px solid var(--jura-oro);
  border-radius: var(--raggio);
  padding: var(--sp-5);
  text-decoration: none;
  color: inherit;
  transition: box-shadow var(--transizione), border-color var(--transizione);
}
.titolo-card { transition: box-shadow var(--durata) var(--curva), border-color var(--durata) var(--curva), transform var(--durata) var(--curva); }
/* IT: `:focus-within` accanto a `:hover`, ed è indispensabile proprio QUI: la scheda è resa
 *     cliccabile da un collegamento steso su tutta la sua superficie (`::after { inset: 0 }`, più
 *     sotto). Chi ci arriva da tastiera mette a fuoco quel collegamento, che è un rettangolo
 *     invisibile grande quanto la scheda: senza questa regola la scheda non reagiva in alcun modo
 *     e l'anello circondava un elemento che visivamente non esiste. */
.titolo-card:hover,
.titolo-card:focus-within { box-shadow: var(--ombra); border-color: var(--jura-hairline); }
.titolo-card:active { box-shadow: var(--ombra-sm); transform: translateY(var(--pressione)); }
.titolo-card__sigillo { color: var(--jura-oro); }
.titolo-card__sigillo svg, .titolo-card__sigillo img { height: 28px; width: auto; }
.titolo-card__id { font-family: var(--font-mono); font-size: var(--testo-xs); color: var(--colore-testo-tenue); }
.titolo-card__nome { font-family: var(--font-titolo); font-size: var(--testo-lg); color: var(--colore-testo-forte); margin: 0; }
.titolo-card__piede { margin-top: auto; display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }

/* ---------------------------------------------------------------------------------------------
 * 13. AREA PUBBLICA
 * --------------------------------------------------------------------------------------------- */

.eroe {
  background: linear-gradient(160deg, var(--jura-blu-notte) 0%, var(--jura-grafite) 62%, var(--jura-blu-notte-scuro) 100%);
  color: var(--colore-testo-inverso);
  padding: var(--sp-8) var(--sp-6);
}
.eroe__interno { max-width: var(--larghezza-contenuto); margin: 0 auto; }
.eroe__claim {
  font-family: var(--font-titolo);
  font-size: var(--testo-3xl);
  line-height: 1.15;
  margin: 0 0 var(--sp-4);
  color: var(--jura-avorio);
  max-width: 18ch;
}
.eroe__claim em { font-style: normal; color: var(--jura-oro); }
.eroe__testo { max-width: 56ch; color: rgba(247, 244, 236, 0.82); font-size: var(--testo-lg); }
.eroe__azioni { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-5); }

.sezione { padding: var(--sp-8) var(--sp-6); }
.sezione--alt { background: var(--colore-fondo-alt); }
.sezione__interno { max-width: var(--larghezza-contenuto); margin: 0 auto; }
.sezione__titolo { font-family: var(--font-titolo); font-size: var(--testo-xl); margin-bottom: var(--sp-2); }

/* IT: IL TITOLO DI PAGINA NON PUÒ AVERE IL CORPO DI UN SOTTOTITOLO (rifinitura, 2026-08-09).
 *     Cinque pagine del sito aprono con `.eroe__claim` su fondo blu, quaranta pixel. Le altre tre
 *     — `/contatti`, `/note-legali`, `/privacy` e `/cookie` — non hanno un eroe e usano
 *     `.sezione__titolo`, che è `--testo-xl`: **esattamente il corpo degli `h2` della stessa
 *     pagina**. Su `/contatti`, che è una voce della barra, il titolo di pagina non si distingueva
 *     dai titoli di sezione, e la pagina sembrava cominciare a metà.
 *
 *     La regola guarda l'ELEMENTO e non una classe nuova: un `h1` è il titolo della pagina per
 *     definizione, e non serve ricordarsi di marcarlo. Le pagine con eroe non passano di qui,
 *     perché il loro `h1` porta `.eroe__claim`. */
h1.sezione__titolo {
  /* IT: `--testo-2xl` esiste già in `tokens.css` ed è commentato «titoli di pagina»: era il token
   *     giusto, e non lo usava nessuno. */
  font-size: var(--testo-2xl);
  line-height: 1.25;
  margin-bottom: var(--sp-3);
}
.sezione__sommario { color: var(--colore-testo-tenue); max-width: var(--larghezza-editoriale); margin-bottom: var(--sp-6); }

/* ---------------------------------------------------------------------------------------------
 * 14. COMPONENTI EMERSI DALLA RIMOZIONE DEGLI STILI INLINE
 *
 * IT: Questi otto blocchi non sono nuovi: esistevano già, scritti a mano dentro il markup con
 *     attributi `style`. Toglierli ha reso visibile che erano componenti, non eccezioni — la
 *     prova è che ciascuno ricorreva in più schermate con le stesse identiche proprietà.
 *     È la ragione per cui il divieto degli `style` inline non è pedanteria: un componente
 *     scritto in linea non si vede, quindi non si riusa e non si mantiene.
 * --------------------------------------------------------------------------------------------- */

/* --- Elenco senza pallini, con righe separate ------------------------------------------------ */
.elenco-nudo { list-style: none; padding: 0; margin: 0; }

.elenco-righe { list-style: none; padding: 0; margin: 0; }
.elenco-righe > li {
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--colore-bordo);
}
.elenco-righe > li:last-child { border-bottom: 0; }

/* Elenco numerato con rientro coerente con la scala, invece del rientro del browser. */
.elenco-rientrato { padding-left: var(--sp-5); }
.elenco-rientrato > li { margin-bottom: var(--sp-3); }

/* --- Scelta: la riga di una casella o di un pulsante di opzione ------------------------------
 * Il bersaglio cliccabile comprende l'etichetta, non solo il quadratino: su mobile un quadratino
 * di 13 px è sotto la soglia di 24 px raccomandata per un elemento interattivo. */
.scelta {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
  cursor: pointer;
}
.scelta input { margin-top: 3px; flex: 0 0 auto; }
.scelta:last-child { margin-bottom: 0; }

/* IT: La scelta aveva `cursor: pointer` e nient'altro (T-189): il bersaglio comprende tutta
 *     l'etichetta — che è la ragione per cui questo componente esiste — ma nulla lo mostrava, e
 *     una superficie cliccabile che non si annuncia è larga quanto il quadratino che si vede.
 *     `:focus-within` porta il riscontro sulla riga intera quando il fuoco entra nel controllo. */
.scelta { border-radius: var(--raggio); padding: var(--sp-1) var(--sp-2); margin-left: calc(-1 * var(--sp-2)); transition: background var(--durata-svelta) var(--curva); }
.scelta:hover { background: var(--colore-superficie-alt); }
.scelta:focus-within { background: var(--jura-avorio); }

/* --- Scelta resa come scheda: l'opzione che ha bisogno di una spiegazione ---------------------- */
.scelta-scheda { cursor: pointer; display: block; transition: border-color var(--durata-svelta) var(--curva), box-shadow var(--durata-svelta) var(--curva); }
.scelta-scheda:hover { border-color: var(--colore-bordo-ui); }
.scelta-scheda:focus-within { border-color: var(--colore-focus); box-shadow: 0 0 0 3px var(--colore-focus-tenue); }
/* IT: L'opzione SCELTA si distingue da quella su cui si sta passando sopra. Senza, l'unico segno
 *     era il pallino dentro il controllo, che su una scheda alta cinque righe è quasi invisibile.
 *     Sotto `@supports` per la stessa ragione dell'anello della titolo-card: dove `:has()` non
 *     c'è, si perde una distinzione in più, non una che c'era prima. */
@supports selector(:has(*)) {
  .scelta-scheda:has(input:checked) { border-color: var(--jura-oro); box-shadow: inset 3px 0 0 var(--jura-oro); }
}
.scelta-scheda--attenzione { border-color: var(--stato-attesa); }

/* --- Gruppo di campi con didascalia ----------------------------------------------------------- */
.gruppo-campi {
  border: 1px solid var(--colore-bordo);
  border-radius: var(--raggio);
  padding: var(--sp-5);
  margin: 0 0 var(--sp-5);
}
.gruppo-campi > legend {
  padding: 0 var(--sp-2);
  font-size: var(--testo-sm);
  font-weight: var(--peso-forte);
  color: var(--colore-testo-forte);
}

/* --- Etichetta di blocco: il soprattitolo di un riquadro tecnico ------------------------------ */
.etichetta-blocco {
  font-size: var(--testo-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--colore-testo-tenue);
  margin-bottom: var(--sp-2);
}

/* --- Blocco di testo preformattato (il messaggio che l'utente firmerà) ------------------------ */
.blocco-testo {
  margin: 0;
  white-space: pre-wrap;
  font-family: var(--font-mono);
  font-size: var(--testo-xs);
  line-height: var(--interlinea);
}

/* --- Sigillo in cima a una scheda ------------------------------------------------------------- */
.sigillo-scheda { color: var(--jura-oro); margin-bottom: var(--sp-4); display: block; }
.sigillo-scheda svg { height: 30px; width: auto; }

/* --- Serie di pill accostate ------------------------------------------------------------------ */
.pill-serie { display: inline-flex; flex-wrap: wrap; gap: var(--sp-2); }

/* --- Selettore di ruolo nella barra superiore -------------------------------------------------
 * È un interruttore di ANTEPRIMA, non un cambio di utente: lo dice l'attributo `title` e lo
 * ripete la fascia dei dati dimostrativi. Qui vive solo la sua resa. */
.topbar__ruoli { display: flex; gap: var(--sp-1); }
.topbar__ruolo {
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--raggio-sm);
  font-size: var(--testo-xs);
  font-weight: var(--peso-forte);
  text-decoration: none;
  color: rgba(247, 244, 236, 0.7);
}
.topbar__ruolo { transition: background var(--durata-svelta) var(--curva), color var(--durata-svelta) var(--curva); }
.topbar__ruolo:hover { color: var(--jura-avorio); background: rgba(247, 244, 236, 0.08); }
.topbar__ruolo:active { background: rgba(247, 244, 236, 0.16); }

/* IT: LO STATO CORRENTE SI LEGGE DALL'ATTRIBUTO, NON DA UNA CLASSE PARALLELA (T-189).
 *     Il markup emetteva già `aria-current="page"` (`parti/topbar.eta`) **e** la classe
 *     `--corrente`, e lo stile guardava solo la seconda: due dichiarazioni della stessa cosa, che
 *     è il modo classico di ritrovarsele divergenti — con l'aggravante che quella giusta per chi
 *     ascolta la pagina sarebbe rimasta senza resa visiva.
 *     La classe resta accettata per non rendere questa correzione un cambio di markup, ma la
 *     fonte di verità è l'attributo. */
.topbar__ruolo[aria-current="page"],
.topbar__ruolo--corrente { color: var(--jura-oro); }

/* --- Bottone chiaro su fondo scuro ------------------------------------------------------------ */
.bottone--su-scuro { color: rgba(247, 244, 236, 0.85); }
.bottone--su-scuro:hover { color: var(--jura-avorio); background: rgba(247, 244, 236, 0.1); }

/* --- Testo di errore in un titolo ------------------------------------------------------------- */
.testo-errore { color: var(--stato-errore); }

/* --- Nota stretta accanto a una pill ----------------------------------------------------------- */
.nota-stretta { max-width: 34ch; }

/* ---------------------------------------------------------------------------------------------
 * 15. INGRESSO ALLA DIMOSTRAZIONE
 *
 * IT: La scheda-bersaglio con cui si sceglie il punto di vista. È un LINK, non un bottone,
 *     perché porta a un'altra pagina: chi usa la tastiera lo raggiunge con Tab e lo apre con
 *     Invio, e chi lo apre in una scheda nuova ottiene ciò che si aspetta.
 *     Bersaglio ampio: tutta la scheda è cliccabile, non solo il titolo.
 * --------------------------------------------------------------------------------------------- */

.ingresso {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  height: 100%;
  padding: var(--sp-5);
  background: var(--colore-superficie);
  border: 1px solid var(--colore-bordo);
  border-left: 3px solid var(--jura-oro);
  border-radius: var(--raggio);
  text-decoration: none;
  color: inherit;
  transition: box-shadow var(--transizione), border-color var(--transizione);
}
.ingresso { transition: box-shadow var(--durata) var(--curva), border-color var(--durata) var(--curva), transform var(--durata) var(--curva); }
.ingresso:hover,
.ingresso:focus-visible { box-shadow: var(--ombra); border-color: var(--jura-hairline); color: inherit; }
.ingresso:active { box-shadow: var(--ombra-sm); transform: translateY(var(--pressione)); }
/* IT: La freccia dell'ingresso avanza di poco quando ci si posa sopra. È l'unico movimento
 *     figurativo ammesso nell'applicazione, e si giustifica perché **significa**: la freccia dice
 *     «di qua», e muoversi in quella direzione è la stessa informazione detta due volte. */
.ingresso__dove::after { transition: margin-left var(--durata-svelta) var(--curva); }
.ingresso:hover .ingresso__dove::after,
.ingresso:focus-visible .ingresso__dove::after { margin-left: var(--sp-1); }

.ingresso__ruolo {
  font-family: var(--font-titolo);
  font-size: var(--testo-lg);
  font-weight: var(--peso-forte);
  color: var(--colore-testo-forte);
}
.ingresso__cosa { color: var(--colore-testo-tenue); font-size: var(--testo-sm); }
.ingresso__dove {
  margin-top: auto;
  padding-top: var(--sp-3);
  font-size: var(--testo-xs);
  font-weight: var(--peso-forte);
  color: var(--jura-oro-scuro);
  letter-spacing: 0.02em;
}
.ingresso__dove::after { content: " →"; }

/* --- Coda dei margini ------------------------------------------------------------------------
 * IT: Un contenitore con spaziatura interna propria non deve ereditare anche il margine di coda
 *     dell'ultimo figlio: sommandoli si ottiene il doppio dello spazio sotto rispetto a sopra.
 *     Era il difetto che si stava rattoppando a mano con `mb-0` sparsi nelle viste. */
.scheda > :last-child,
.banner__testo:last-child,
.stato-vista > :last-child,
.segnaposto__corpo > :last-child,
.gruppo-campi > :last-child,
.sezione__interno > :last-child { margin-bottom: 0; }

/* --- Il selettore di ruolo su schermo stretto -------------------------------------------------
 * IT: Quattro nomi per esteso — «Titolare · Creator · Amministrazione · Terzo autorizzato» —
 *     più il badge e il marchio sommavano ~600px dentro una barra alta 60px senza `flex-wrap`:
 *     overflow orizzontale garantito su qualunque telefono. Sotto i 900px restano le iniziali,
 *     e il nome per esteso resta nel `title` e nella versione lunga nascosta ai soli occhi. */
.topbar__ruolo-corto { display: none; }

@media (max-width: 900px) {
  .topbar__ruolo-lungo { display: none; }
  .topbar__ruolo-corto { display: inline; }
  .topbar__ruolo { min-width: 28px; text-align: center; }
}
@media (max-width: 560px) {
  .topbar__ruoli { display: none; }   /* sotto questa soglia si entra dalla pagina di accesso */
  .badge-ruolo { display: none; }
}

/* --- Valore lungo troncato -------------------------------------------------------------------
 * IT: Un percorso di file o una firma di endpoint sono valori tecnici: servono per essere
 *     riconosciuti, non letti parola per parola. Troncati su una riga tengono l'allineamento
 *     della colonna; il valore intero resta nel `title`, visibile al sorvolo.
 *     Senza questo, `docs/PIANO_FRONTEND_E_ADMIN.md` — una sola parola senza spazi — sfondava
 *     il riquadro laterale della scheda. */
.valore-lungo {
  display: block;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --- Scheletro a blocco: riempie l'area di una scheda invece di lasciarla vuota -------------- */
.scheletro--blocco { height: 6.5em; border-radius: var(--raggio); }

/* --- Etichetta del selettore di ruolo --------------------------------------------------------- */
.topbar__etichetta-ruoli {
  font-size: var(--testo-xs);
  color: rgba(247, 244, 236, 0.6);
  letter-spacing: 0.04em;
}
.topbar__osserva { color: rgba(247, 244, 236, 0.5); }

@media (max-width: 900px) { .topbar__etichetta-ruoli { display: none; } }

/* --- Barra laterale come lista ----------------------------------------------------------------
 * IT: Le voci sono ora `<li>` dentro `<ul>`, e il titolo di gruppo è un `<h2>`. La lista non
 *     deve però portare i pallini né il rientro del browser: qui si azzerano, mentre la
 *     SEMANTICA — «elenco di sei voci, gruppo Governo» — resta e viene annunciata. */
.sidebar__voci { list-style: none; margin: 0; padding: 0; }
.sidebar__titolo { margin: 0; font-family: var(--font-testo); }

/* --- Scheda-titolo: il link è sul titolo, non sull'intera scheda -------------------------------
 * IT: Prima tutta la scheda era un `<a>`, e il nome accessibile del link diventava una frase di
 *     una trentina di parole — identificativo, nome, tipo, quote, percentuale e tre pill. Ora il
 *     link è sul solo titolo; l'area cliccabile resta l'intera scheda grazie al pseudo-elemento
 *     in copertura, che non aggiunge nulla all'albero di accessibilità. */
.titolo-card { position: relative; }
.titolo-card__collegamento { color: inherit; text-decoration: none; }
.titolo-card__collegamento::after { content: ""; position: absolute; inset: 0; }
.titolo-card:hover .titolo-card__collegamento,
.titolo-card:focus-within .titolo-card__collegamento { text-decoration: underline; }

/* IT: L'anello va sulla SCHEDA, non sul collegamento steso: quel collegamento è un rettangolo
 *     trasparente esteso a tutta la superficie, e l'anello attorno al suo contorno reale — che è
 *     il testo del titolo — indicherebbe un bersaglio più piccolo di quello che si preme davvero.
 *
 *     PERCHÉ È CONDIZIONATO, e vale la pena scriverlo. Spostare l'anello richiede di toglierlo da
 *     dove sta, e `outline: none` sarebbe **il primo di tutto il progetto**: se un browser non
 *     conoscesse `:has()`, la prima riga verrebbe applicata e la seconda no — l'anello non si
 *     sposterebbe, sparirebbe. Un miglioramento estetico che in un browser vecchio diventa
 *     l'impossibilità di navigare da tastiera non è un miglioramento.
 *     Dentro `@supports` le due righe vivono o cadono insieme, che è il solo modo corretto di
 *     scrivere una sostituzione. */
@supports selector(:has(*)) {
  .titolo-card__collegamento:focus-visible { outline: none; }
  .titolo-card:has(.titolo-card__collegamento:focus-visible) {
    outline: var(--focus-spessore) solid var(--colore-focus);
    outline-offset: var(--focus-scarto);
  }
}
/* Ciò che deve restare cliccabile per conto proprio va sopra la copertura. */
.titolo-card__piede, .titolo-card__piede * { position: relative; z-index: 1; }

/* --- `.scheda--piatta` non faceva nulla ------------------------------------------------------
 * IT: Era `box-shadow: none` su una scheda che l'ombra non ce l'ha: un modificatore usato in
 *     cinque viste e privo di effetto. Ora significa quello che il nome promette — una scheda
 *     secondaria, che non compete con quella principale accanto. */
.scheda--piatta { background: transparent; border-style: dashed; }
.sidebar__segno { color: var(--colore-testo-tenue); font-size: var(--testo-sm); }

/* --- Etichetta che si accorcia su schermo stretto ---------------------------------------------
 * IT: La forma lunga resta nel documento e resta letta dalle tecnologie assistive; sparisce solo
 *     alla vista. Nascondere il testo con `display:none` lo toglierebbe anche a loro, quindi la
 *     versione corta è `aria-hidden` e la lunga usa la classe per soli lettori di schermo. */
.etichetta-corta { display: none; }
@media (max-width: 560px) {
  .etichetta-lunga { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .etichetta-corta { display: inline; }
  .topbar { padding: 0 var(--sp-3); gap: var(--sp-2); }
}

/* Rete di sicurezza contro lo sfondamento orizzontale: un elemento flessibile non si restringe
 * sotto il proprio contenuto se non gli si dice che può farlo. È la causa più comune di una
 * pagina più larga dello schermo, e non si vede finché non si apre un telefono. */
.topbar > *, .topbar__destra > * { min-width: 0; }

/* --- Fascia dell'esito di un'azione ------------------------------------------------------------
 * IT: Compare in cima, subito dopo la fascia dei dati dimostrativi, perché è la risposta a
 *     qualcosa che l'utente ha appena fatto. Non si chiude da sola: sparisce navigando altrove,
 *     che è il momento in cui l'utente ha finito di leggerla — non tre secondi dopo, quando
 *     magari stava ancora guardando il modulo. */
/* IT: L'ESITO ENTRA, invece di essere già lì (strato di guida, 2026-08-09).
 *     La fascia compare in cima alla pagina dopo un rimando, cioè in un punto che l'occhio ha già
 *     attraversato: chi ha appena premuto un bottone in fondo alla schermata guarda in fondo alla
 *     schermata, e un messaggio che appare in cima senza muoversi si perde. Sono 220 millisecondi,
 *     ed è la differenza fra «non è successo niente» e «ecco che cosa è successo».
 *
 *     Il movimento è **verticale e breve**: scende da dove non c'era. Una comparsa in dissolvenza
 *     sarebbe più discreta e direbbe meno — qui serve che si veda. */
.fascia-esito {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5);
  font-size: var(--testo-sm);
  border-bottom: 1px solid;
  animation: esito-entra var(--durata) var(--curva) both;
}
@keyframes esito-entra {
  from { opacity: 0; transform: translateY(-100%); }
  to   { opacity: 1; transform: translateY(0); }
}
/* IT: Il segno arriva un istante dopo il testo: si legge prima che cosa è successo, poi se è
 *     andata bene. Invertire l'ordine farebbe cercare il colore invece della frase. */
.fascia-esito__segno { animation: spunta 300ms var(--curva) 120ms both; }

@media (prefers-reduced-motion: reduce) {
  .fascia-esito, .fascia-esito__segno { animation: none; }
}
.fascia-esito__segno {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; flex: 0 0 20px;
  border-radius: 50%;
  font-weight: var(--peso-massimo);
  color: var(--ui-bianco);
}
.fascia-esito--ok {
  background: var(--stato-ok-fondo);
  border-bottom-color: var(--stato-ok-bordo);
  color: var(--stato-ok-testo);
}
.fascia-esito--ok .fascia-esito__segno { background: var(--stato-ok); }
.fascia-esito--errore {
  background: var(--stato-errore-fondo);
  border-bottom-color: var(--stato-errore-bordo);
  color: var(--stato-errore-testo);
}
.fascia-esito--errore .fascia-esito__segno { background: var(--stato-errore); }

/* --- Modulo di azione ---------------------------------------------------------------------------
 * IT: Ogni modulo che compie un'azione porta due campi nascosti: quale azione, e dove tornare.
 *     Il secondo esiste perché l'azione non deve decidere da sola dove atterra chi la compie —
 *     la stessa azione, chiamata da schermate diverse, deve riportare a quella da cui è partita. */
.modulo-azione { margin: 0; }
.banner-dimostrativo__ripristina {
  margin-left: auto;
  padding: 2px var(--sp-3);
  border: 1px solid var(--jura-hairline);
  border-radius: var(--raggio-pill);
  background: var(--ui-bianco);
  color: var(--stato-attesa-testo);
  text-decoration: none;
  font-weight: var(--peso-forte);
  white-space: nowrap;
}
.banner-dimostrativo__ripristina:hover { background: var(--jura-avorio); color: var(--stato-attesa-testo); }
