/* =========================================================================
   Diora Energia — tema del gestionale.

   TUTTE le tinte stanno nelle variabili :root qui sotto: cambiare la palette
   (quando arriveranno logo e colori ufficiali) vuol dire toccare solo questo
   blocco, mai le regole. Nessun framework CSS, font di sistema, tabelle dense:
   questa e' una interfaccia da lavoro, si guarda tutto il giorno.
   ========================================================================= */

:root {
  /* =======================================================================
     Palette Diora Energia (Mattone 4, B9) — derivata dal logo.

     Due ori, con ruoli diversi e non intercambiabili:
       --oro       (#C39A3B) e' il colore del marchio. Solo DECORATIVO: bordi
                   attivi, filetti, il marchio stesso. Su fondo chiaro non
                   arriva al contrasto AA, quindi non ci si scrive mai sopra.
       --accento   (#8F6C1A) e' lo stesso oro scurito fino a superare l'AA.
                   E' quello che porta il testo: link, pulsanti, voce di menu
                   attiva.
     Il verde foglia del logo diventa il colore degli stati positivi, anch'esso
     scurito quanto basta per reggere il testo.
     ======================================================================= */

  /* --- superfici --- */
  --fondo: #fafaf7;           /* bianco caldo */
  --fondo-card: #ffffff;
  --fondo-barra: #ffffff;
  --fondo-testata: #f2f0e9;
  --fondo-riga-alt: #fbfaf6;
  --fondo-riga-hover: #f7f2e4;
  --fondo-evidenziata: #fdf6e4;

  /* --- testo --- */
  --testo: #23272b;           /* antracite */
  --testo-tenue: #6b6f75;
  --testo-inverso: #ffffff;

  /* --- linee --- */
  --bordo: #e5e1d7;
  --bordo-forte: #c8c2b4;
  --raggio: 6px;

  /* --- oro del marchio: decorativo, mai sotto al testo --- */
  --oro: #c39a3b;
  --oro-tenue: #ede2c6;

  /* --- accento: l'oro scurito, quello che regge il testo (AA) --- */
  --accento: #8f6c1a;
  --accento-scuro: #6e5213;
  --accento-tenue: #f4eedd;

  /* --- stati semantici (tenui: devono informare, non urlare) --- */
  --ok: #35823f;              /* verde foglia scurito per il testo */
  --ok-fondo: #e9f4ea;
  --verde-foglia: #3e9b4f;    /* il verde del logo: pallini e filetti */
  --attesa: #8a6a1e;
  --attesa-fondo: #fbf2da;
  --allarme: #a33a3a;
  --allarme-fondo: #fbeaea;
  --neutro: #5f6570;
  --neutro-fondo: #eeece6;
  --info: #3a6b8a;
  --info-fondo: #e8eff4;

  /* --- stati del contratto ---
     Tinte distinte ma tutte della stessa famiglia terrosa. Nell'interfaccia
     non compaiono MAI da sole: sempre pallino + etichetta, perche' un colore
     non e' un'informazione per chi non lo distingue. */
  --stato-nuovo: var(--attesa);
  --stato-nuovo-fondo: var(--attesa-fondo);
  --stato-caricato_partner: var(--info);
  --stato-caricato_partner-fondo: var(--info-fondo);
  --stato-attivato: var(--ok);
  --stato-attivato-fondo: var(--ok-fondo);
  --stato-caricato_bridge: #1f6b63;
  --stato-caricato_bridge-fondo: #e4f0ee;
  --stato-cessato: var(--neutro);
  --stato-cessato-fondo: var(--neutro-fondo);
  --stato-cancellato: var(--allarme);
  --stato-cancellato-fondo: var(--allarme-fondo);

  /* --- tipo di fornitura --- */
  --luce: #8a6a1e;
  --luce-fondo: #fbf2da;
  --gas: #3a6b8a;
  --gas-fondo: #e8eff4;

  /* --- misure --- */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
          Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;
  --testo-base: 13px;
  --testo-piccolo: 12px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--fondo);
  color: var(--testo);
  font-family: var(--font);
  font-size: var(--testo-base);
  line-height: 1.45;
}

a { color: var(--accento); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ------------------------------------------------------- menu laterale --- */
/* Mattone 5, Parte A: il menu passa da barra orizzontale a colonna. Le voci
   sono diventate dieci e in orizzontale non ci stavano piu' senza andare a
   capo; in colonna ci stanno tutte e si possono raggruppare per mestiere
   (Operativita' / Bridge / Controllo / Sistema).

   La larghezza e' fissa e il menu e' sticky a tutta altezza: la posizione di
   una voce non cambia mai, cosi' la si prende senza leggerla. */
.impaginato { display: flex; align-items: flex-start; min-height: 100vh; }
.laterale {
  flex: none;
  width: 208px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 8px;
  background: var(--fondo-barra);
  border-right: 1px solid var(--bordo);
  z-index: 20;
}
/* Compresso: restano le sole icone. Non si nasconde niente per davvero — le
   etichette spariscono dalla vista ma i `title` restano, e con loro i nomi
   per chi naviga con la tastiera o con un lettore di schermo. */
.laterale.compresso { width: 56px; }
.laterale.compresso .etichetta { display: none; }
.laterale.compresso .logo { justify-content: center; }
.laterale.compresso nav a,
.laterale.compresso .comprimi,
.laterale.compresso .esci { justify-content: center; padding-left: 0; padding-right: 0; }
/* Compresso, i titoli diventano un filetto: la parola non ci sta e una
   sigla non aiuterebbe nessuno. Con i titoli spariti sparisce anche il modo
   di riaprire un gruppo, quindi qui le voci si mostrano sempre — un gruppo
   chiuso e invisibile sarebbe un menu con dei buchi inspiegabili. */
.laterale.compresso .gruppo { height: 1px; padding: 0; margin: 8px 6px;
                              border-left: 0; background: var(--bordo);
                              pointer-events: none; }
.laterale.compresso .gruppo .freccia { display: none; }
.laterale.compresso .gruppo-voci.chiuso .voci { display: flex; }
.laterale.compresso .utente { justify-content: center; }
.laterale.compresso .badge { position: absolute; top: 2px; right: 4px;
                             margin: 0; min-width: 15px; line-height: 15px; }

.logo {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 4px 8px 12px;
  font-weight: 700;
  letter-spacing: 0.10em;
  color: var(--testo);
  font-size: 12px;
  flex: none;
}
.logo img { width: 30px; height: 30px; display: block; flex: none; }
.logo:hover { text-decoration: none; }
.testata-laterale { display: flex; align-items: center; }
.chiudi-menu {
  flex: none;
  margin-left: auto;
  padding: 4px 8px;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 16px;
  line-height: 1;
  color: var(--testo-tenue);
  cursor: pointer;
}
.chiudi-menu:hover { color: var(--testo); }

.laterale nav { display: flex; flex-direction: column; gap: 1px; }

/* --- gruppi apribili ---
   I titoli erano grigi e muti: si leggevano come decorazione. Ora sono in
   antracite con il filetto d'oro del marchio, e sono pulsanti veri — chi usa
   sempre e solo Bridge si chiude gli altri due gruppi e se li ritrova chiusi
   la volta dopo (la preferenza sta in localStorage). */
.gruppo-voci { display: flex; flex-direction: column; }
.laterale .gruppo {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  margin: 12px 0 3px;
  padding: 4px 8px;
  border: 0;
  border-left: 2px solid var(--oro);
  border-radius: 0;
  background: none;
  font-family: inherit;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--testo);
  text-align: left;
  cursor: pointer;
}
.laterale .gruppo:hover { color: var(--accento); }
.laterale .gruppo:focus-visible { outline: 2px solid var(--oro); outline-offset: 1px; }
.laterale .gruppo .freccia {
  margin-left: auto;
  font-size: 9px;
  color: var(--testo-tenue);
  transition: transform 150ms;
}
.gruppo-voci.chiuso .freccia { transform: rotate(-90deg); }
.gruppo-voci.chiuso .voci { display: none; }
.voci { display: flex; flex-direction: column; gap: 1px; }
.laterale nav a {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 9px;
  border-radius: var(--raggio);
  color: var(--testo-tenue);
  font-weight: 500;
  white-space: nowrap;
}
.laterale nav a:hover { background: var(--fondo-testata); text-decoration: none; }
.laterale nav a.attivo {
  background: var(--accento-tenue);
  color: var(--accento);
  box-shadow: inset 2px 0 0 var(--oro);  /* l'oro pieno resta decorativo */
  font-weight: 600;
}
.laterale .icona {
  flex: none;
  width: 18px;
  text-align: center;
  font-size: 14px;
  line-height: 1;
}
.laterale .etichetta { overflow: hidden; text-overflow: ellipsis; }

.piede-laterale {
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px solid var(--bordo);
}
.comprimi {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 7px 9px;
  border: 0;
  border-radius: var(--raggio);
  background: none;
  font-family: inherit;
  font-size: var(--testo-piccolo);
  color: var(--testo-tenue);
  cursor: pointer;
}
.comprimi:hover { background: var(--fondo-testata); }
/* Pastiglia del conteggio eccezioni: visibile da ogni pagina (B5). */
.badge {
  display: inline-block;
  min-width: 17px;
  padding: 0 5px;
  margin-left: 5px;
  border-radius: 9px;
  background: var(--allarme);
  color: var(--testo-inverso);
  font-size: 10px;
  font-weight: 700;
  line-height: 17px;
  text-align: center;
  vertical-align: 1px;
}
.utente {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 4px 9px 8px;
  color: var(--testo-tenue);
  font-size: var(--testo-piccolo);
}
.laterale.compresso .utente { padding: 4px 0 8px; }
.utente > .etichetta { overflow: hidden; text-overflow: ellipsis; }
.esci { display: flex; align-items: center; gap: 10px; padding: 5px 0;
        color: var(--accento); }
.esci .icona { flex: none; width: 18px; text-align: center; }
.utente em {
  font-style: normal;
  background: var(--neutro-fondo);
  color: var(--neutro);
  padding: 1px 6px;
  border-radius: 10px;
  font-size: 11px;
}

/* ------------------------------------------------------------ contenuto --- */
/* `min-width: 0` non e' un dettaglio: senza, un figlio flex si rifiuta di
   restringersi sotto la larghezza del suo contenuto, e una tabella larga
   spingerebbe fuori pagina invece di scorrere dentro il suo riquadro. */
.contenuto { flex: 1; min-width: 0; padding: 20px; max-width: 1600px; }
h1 { font-size: 20px; margin: 0 0 16px; }
h2 { font-size: 14px; margin: 0 0 10px; }
.titolo-sezione {
  margin: 28px 0 10px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--testo-tenue);
}
.nota, .piede { color: var(--testo-tenue); font-size: var(--testo-piccolo); }
.nota { margin: -4px 0 10px; }
.briciole { margin: 0 0 10px; font-size: var(--testo-piccolo); }
.tenue { color: var(--testo-tenue); }
.mono { font-family: var(--font-mono); font-size: var(--testo-piccolo); }
.nowrap { white-space: nowrap; }
.centro { text-align: center; }

/* ----------------------------------------------------------------- card --- */
.griglia-card, .griglia-schede {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 14px;
}
.card {
  background: var(--fondo-card);
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  padding: 14px 16px;
}
.card h2 {
  color: var(--testo-tenue);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 11px;
}
.numerone { font-size: 30px; font-weight: 600; margin: 4px 0 10px; }
.numerone.piccolo { font-size: 17px; }
.numerone.allarme { color: var(--allarme); }
.unita { font-size: 12px; font-weight: 400; color: var(--testo-tenue);
         margin-left: 6px; }
.lista-stati { list-style: none; margin: 0; padding: 0; }
.lista-stati li {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 3px 0;
  border-bottom: 1px solid var(--fondo-testata);
}
.lista-stati li:last-child { border-bottom: 0; }
.lista-stati b { margin-left: auto; font-variant-numeric: tabular-nums; }
.pallino { width: 8px; height: 8px; border-radius: 50%; background: var(--neutro);
           flex: none; }
.esito { font-weight: 600; margin: 0 0 8px; }
.esito.ok { color: var(--ok); }
.esito.allarme { color: var(--allarme); }
.delta {
  font-family: var(--font-mono);
  background: var(--fondo-testata);
  border-radius: 3px;
  padding: 0 4px;
  margin-right: 4px;
  white-space: nowrap;
}

/* --------------------------------------------------------------- tabelle --- */
table.densa {
  width: 100%;
  border-collapse: collapse;
  background: var(--fondo-card);
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  overflow: hidden;
  font-size: var(--testo-piccolo);
}
/* `overflow: hidden` sul contenitore arrotondato impedirebbe l'intestazione
   fissa (un antenato che ritaglia annulla lo sticky): l'angolo stondato si
   ottiene invece con `border-radius` sulle celle d'angolo, piu' sotto. */
table.densa { overflow: visible; }
table.densa th {
  background: var(--fondo-testata);
  text-align: left;
  padding: 7px 10px;
  font-weight: 600;
  color: var(--testo-tenue);
  border-bottom: 1px solid var(--bordo);
  white-space: nowrap;
  /* Intestazione fissa (Mattone 5, Parte A): in un elenco di 250 righe,
     scoprire cosa c'e' nella settima colonna non deve costare un ritorno in
     cima. Il fondo dev'essere pieno, altrimenti le righe si vedono sotto. */
  position: sticky;
  top: 0;
  z-index: 2;
}
table.densa thead tr:first-child th:first-child { border-top-left-radius: var(--raggio); }
table.densa thead tr:first-child th:last-child { border-top-right-radius: var(--raggio); }
table.densa td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--fondo-testata);
  vertical-align: top;
}
table.densa tbody tr:nth-child(even) { background: var(--fondo-riga-alt); }
table.densa tbody tr:hover { background: var(--fondo-riga-hover); }
table.densa tr.evidenziata,
table.densa tr.evidenziata:hover { background: var(--fondo-evidenziata); }
tr.cliccabile { cursor: pointer; }
.vuoto { text-align: center; color: var(--testo-tenue); padding: 20px !important; }
.conteggio { color: var(--testo-tenue); font-size: var(--testo-piccolo);
             margin: 0 0 8px; }

/* ------------------------------------------------------------------ tag --- */
.tag {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 600;
  background: var(--neutro-fondo);
  color: var(--neutro);
  white-space: nowrap;
}
.tag.grande { padding: 3px 10px; font-size: 12px; }
.tag.allarme { background: var(--allarme-fondo); color: var(--allarme); }

.stato-nuovo { background: var(--stato-nuovo-fondo); color: var(--stato-nuovo); }
.stato-caricato_partner { background: var(--stato-caricato_partner-fondo);
                          color: var(--stato-caricato_partner); }
.stato-attivato { background: var(--stato-attivato-fondo); color: var(--stato-attivato); }
.stato-caricato_bridge { background: var(--stato-caricato_bridge-fondo);
                         color: var(--stato-caricato_bridge); }
.stato-cessato { background: var(--stato-cessato-fondo); color: var(--stato-cessato); }
.stato-cancellato { background: var(--stato-cancellato-fondo);
                    color: var(--stato-cancellato); }

/* Stati di una pratica di acquisizione (batch 1). Colori presi in prestito
   dalla stessa scala dei contratti, così un'attesa è gialla e una chiusura è
   grigia dovunque la si guardi. Gli stati dei batch 2-3 ci sono già: la
   pastiglia esiste dal giorno in cui esisterà lo stato. */
.stato-pratica-ricevuta { background: var(--attesa-fondo); color: var(--attesa); }
.stato-pratica-in_analisi { background: var(--info-fondo); color: var(--info); }
.stato-pratica-estratta { background: var(--info-fondo); color: var(--info); }
.stato-pratica-da_ricontrollare { background: var(--allarme-fondo);
                                  color: var(--allarme); }
.stato-pratica-pronta_per_revisione { background: var(--ok-fondo); color: var(--ok); }
.stato-pratica-esportata { background: var(--stato-caricato_bridge-fondo);
                           color: var(--stato-caricato_bridge); }
.stato-pratica-scartata { background: var(--neutro-fondo); color: var(--neutro); }
span.pallino.stato-nuovo { background: var(--stato-nuovo); }
span.pallino.stato-caricato_partner { background: var(--stato-caricato_partner); }
span.pallino.stato-attivato { background: var(--stato-attivato); }
span.pallino.stato-caricato_bridge { background: var(--stato-caricato_bridge); }
span.pallino.stato-cessato { background: var(--stato-cessato); }
span.pallino.stato-cancellato { background: var(--stato-cancellato); }

.tipo-LUCE { background: var(--luce-fondo); color: var(--luce); }
.tipo-GAS { background: var(--gas-fondo); color: var(--gas); }

.verifica-non_verificato { background: var(--neutro-fondo); color: var(--neutro); }
.verifica-verificato_bolletta { background: var(--ok-fondo); color: var(--ok); }
.verifica-mismatch { background: var(--allarme-fondo); color: var(--allarme); }
span.pallino.verifica-non_verificato { background: var(--neutro); }
span.pallino.verifica-verificato_bolletta { background: var(--ok); }
span.pallino.verifica-mismatch { background: var(--allarme); }

.attore-sistema { background: var(--info-fondo); color: var(--info); }
.attore-utente { background: var(--accento-tenue); color: var(--accento); }
.attore-agente { background: var(--attesa-fondo); color: var(--attesa); }

/* -------------------------------------------------------------- popover --- */
/* La «i» che apre una spiegazione. Il testo lungo non sta in un `title=`: su
   un telefono il title non esiste (non c'e' il passaggio del mouse), ed e'
   proprio li' che serve — chi guarda la dashboard dal cantiere non ha il
   manuale sottomano. */
.con-aiuto { position: relative; display: inline-flex; vertical-align: middle; }
.apri-aiuto {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  padding: 0;
  border: 1px solid var(--bordo-forte);
  border-radius: 50%;
  background: var(--fondo-card);
  color: var(--testo-tenue);
  font-family: var(--font);
  font-size: 11px;
  font-weight: 700;
  font-style: italic;
  line-height: 1;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
}
.apri-aiuto:hover, .apri-aiuto[aria-expanded="true"] {
  border-color: var(--oro);
  color: var(--accento);
}
.popover {
  position: absolute;
  top: calc(100% + 7px);
  left: 0;
  z-index: 60;
  width: 320px;
  max-width: calc(100vw - 28px);
  padding: 10px 12px 12px;
  background: var(--fondo-card);
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  box-shadow: 0 8px 28px rgba(20, 25, 33, 0.16);
  /* Il popover eredita da dove sta: dentro un `.card h2` sarebbe maiuscoletto
     spaziato, dentro un `label` sarebbe grigio e grassetto. Qui si riparte. */
  font-size: var(--testo-piccolo);
  font-weight: 400;
  font-style: normal;
  text-transform: none;
  letter-spacing: normal;
  line-height: 1.45;
  color: var(--testo);
  white-space: normal;
  text-align: left;
  cursor: default;
}
.testata-popover {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}
.chiudi-popover {
  flex: none;
  padding: 0 2px;
  border: 0;
  background: none;
  color: var(--testo-tenue);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
.chiudi-popover:hover { color: var(--testo); }
.legenda { list-style: none; margin: 0; padding: 0; }
.legenda li {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 5px 0;
  border-bottom: 1px solid var(--fondo-testata);
}
.legenda li:last-child { border-bottom: 0; }
.legenda .tag { flex: none; }
/* Etichetta di un campo con la sua «i» accanto, senza allargare il campo. */
.etichetta-campo { display: flex; align-items: center; gap: 5px; }

/* --------------------------------------------------------------- filtri --- */
.filtri {
  display: flex;
  gap: 10px;
  align-items: flex-end;
  flex-wrap: wrap;
  background: var(--fondo-card);
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  padding: 10px 12px;
  margin-bottom: 12px;
}
.campo { display: flex; flex-direction: column; gap: 3px; }
.campo label { font-size: 11px; color: var(--testo-tenue); font-weight: 600; }
.campo input, .campo select {
  font-family: inherit;
  font-size: var(--testo-piccolo);
  padding: 5px 7px;
  border: 1px solid var(--bordo-forte);
  border-radius: 4px;
  background: var(--fondo-card);
  color: var(--testo);
  min-width: 150px;
}
.campo input[type="search"] { min-width: 260px; }
.campo input:focus, .campo select:focus {
  outline: 2px solid var(--accento-tenue);
  border-color: var(--accento);
}

/* --------------------------------------------------------- paginazione --- */
.paginazione {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin: 12px 0;
  font-size: var(--testo-piccolo);
}
.paginazione a { cursor: pointer; color: var(--accento); }
.paginazione a.disabilitato { color: var(--bordo-forte); cursor: default; }

/* --------------------------------------------------------------- schede --- */
.intestazione-scheda { display: flex; align-items: center; gap: 12px;
                       margin-bottom: 16px; }
.intestazione-scheda h1 { margin: 0; }
.card dl { display: grid; grid-template-columns: 40% 60%; gap: 0; margin: 0; }
.card dt {
  color: var(--testo-tenue);
  padding: 4px 8px 4px 0;
  border-bottom: 1px solid var(--fondo-testata);
  font-size: var(--testo-piccolo);
}
.card dd {
  margin: 0;
  padding: 4px 0;
  border-bottom: 1px solid var(--fondo-testata);
  word-break: break-word;
}

/* ---------------------------------------------------------------- login --- */
.schermata-login, .schermata-errore {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.riquadro-login {
  background: var(--fondo-card);
  border: 1px solid var(--bordo);
  border-radius: 8px;
  padding: 32px;
  width: 100%;
  max-width: 340px;
  display: flex;
  flex-direction: column;
}
.logo-login { text-align: center; margin-bottom: 2px; }
.logo-login img { width: 100%; max-width: 240px; height: auto; }
.sottotitolo { text-align: center; color: var(--testo-tenue);
               font-size: var(--testo-piccolo); margin: 4px 0 22px; }
.riquadro-login label { font-size: 11px; font-weight: 600;
                        color: var(--testo-tenue); margin-bottom: 3px; }
.riquadro-login input {
  font-family: inherit;
  font-size: var(--testo-base);
  padding: 8px 10px;
  border: 1px solid var(--bordo-forte);
  border-radius: 4px;
  margin-bottom: 14px;
  background: var(--fondo-card);
  color: var(--testo);
}
.riquadro-login input:focus { outline: 2px solid var(--accento-tenue);
                              border-color: var(--accento); }
.riquadro-login button {
  font-family: inherit;
  font-size: var(--testo-base);
  font-weight: 600;
  padding: 9px;
  border: 0;
  border-radius: 4px;
  background: var(--accento);
  color: var(--testo-inverso);
  cursor: pointer;
  margin-top: 4px;
}
.riquadro-login button:hover { background: var(--accento-scuro); }
.avviso { padding: 8px 10px; border-radius: 4px; font-size: var(--testo-piccolo);
          margin: 0 0 14px; }
.avviso.errore { background: var(--allarme-fondo); color: var(--allarme); }

/* --------------------------------------------------------------- errore --- */
.riquadro-errore { text-align: center; }
.codice-errore { font-size: 44px; font-weight: 700; color: var(--bordo-forte);
                 margin: 0; }
.messaggio-errore { color: var(--testo-tenue); margin: 4px 0 16px; }

/* ----------------------------------------------------------------- HTMX --- */
.htmx-indicator { opacity: 0; color: var(--testo-tenue); transition: opacity 150ms; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { opacity: 1; }

/* =========================================================================
   Scritture (Mattone 4). Da qui in giù tutto serve alle viste che modificano.
   ========================================================================= */

/* -------------------------------------------------------------- pulsanti --- */
.pulsante {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: inherit;
  font-size: var(--testo-piccolo);
  font-weight: 600;
  padding: 6px 13px;
  border: 1px solid var(--bordo-forte);
  border-radius: 4px;
  background: var(--fondo-card);
  color: var(--testo);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}
.pulsante:hover { background: var(--fondo-testata); text-decoration: none; }
.pulsante.primario {
  background: var(--accento);
  border-color: var(--accento);
  color: var(--testo-inverso);
}
.pulsante.primario:hover { background: var(--accento-scuro); }
.pulsante.pericolo { color: var(--allarme); border-color: var(--allarme); }
.pulsante.pericolo:hover { background: var(--allarme-fondo); }
.pulsante.minuto { padding: 2px 8px; font-size: 11px; font-weight: 500; }
.pulsante:focus-visible { outline: 2px solid var(--oro); outline-offset: 1px; }

/* ----------------------------------------------------------------- form --- */
.modulo fieldset.card { border: 1px solid var(--bordo); margin: 0 0 14px; }
.modulo legend {
  font-weight: 700;
  font-size: 13px;
  padding: 0 8px;
  color: var(--testo);
}
.riga-campi {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: flex-end;
  margin-bottom: 10px;
}
.riga-campi:last-child { margin-bottom: 0; }
/* Righe "rigide" (sezione Contratto): le celle si allineano in ALTO invece che
   al fondo come le righe di modulo normali. Così le etichette stanno tutte sulla
   stessa linea in cima e gli input partono dalla stessa baseline anche quando una
   cella ha un testo d'aiuto sotto e le vicine no — con `flex-end` una cella più
   alta trascinava giù le altre e sfalsava tutto. L'aiuto vive in una riga sua con
   un'altezza minima riservata, quindi non influenza l'allineamento dei campi
   adiacenti. Resta flex (non grid) per non perdere il wrap responsivo. */
.riga-campi.rigida { align-items: start; }
.riga-campi.rigida > .campo { align-self: start; }
/* L'etichetta occupa una riga d'altezza fissa: se a una certa larghezza va a capo,
   gli input della riga restano comunque allineati. */
.riga-campi.rigida > .campo > label { min-height: 14px; }
/* La riga dell'aiuto ha un'altezza minima riservata (≈ due righe): uniforme fra
   celle con aiuto corto, lungo o assente, senza spostare i campi vicini. */
.riga-campi.rigida > .campo > .aiuto { display: block; min-height: 2.6em; }
.campo.cresci { flex: 1 1 240px; }
.campo.pieno { flex: 1 1 100%; }
.campo.stretto input { min-width: 70px; width: 70px; }
.campo textarea {
  font-family: inherit;
  font-size: var(--testo-piccolo);
  padding: 6px 8px;
  border: 1px solid var(--bordo-forte);
  border-radius: 4px;
  background: var(--fondo-card);
  color: var(--testo);
  resize: vertical;
  width: 100%;
}
.campo textarea:focus { outline: 2px solid var(--accento-tenue);
                        border-color: var(--accento); }
.campo.cresci input, .campo.cresci select { min-width: 100%; }
.campo-spunta { justify-content: flex-end; padding-bottom: 5px; }
.campo-spunta label {
  font-size: var(--testo-piccolo);
  font-weight: 400;
  color: var(--testo);
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
/* La casella dentro una spunta è un controllo nativo, non un campo di testo:
   non deve ereditare min-width, bordo e padding di `.campo input` — era quello
   che la stirava a rettangolo largo (fino al 100% dentro un `.campo.cresci`) e
   spingeva l'etichetta in una colonna strettissima fuori dal bordo della card. */
.campo-spunta input[type="checkbox"],
.campo-spunta input[type="radio"] {
  min-width: 0;
  width: auto;
  flex: 0 0 auto;
  margin: 2px 0 0;
  padding: 0;
}
/* L'etichetta prende lo spazio che resta e va a capo dentro la card, non fuori. */
.campo-spunta label b { font-weight: 600; min-width: 0; }
/* La spunta «l'export e' completo» sotto il caricamento dell'export Bridge.
   Non e' un'opzione fra tante: e' la risposta a una guardia che ha fermato
   l'analisi, quindi si legge come una frase e non come una casella in fila. */
.spunta-export {
  display: flex; gap: 8px; align-items: flex-start;
  margin: 10px 0 0; font-size: 13px; color: var(--testo-tenue);
}
.spunta-export input[type="checkbox"] {
  width: auto; min-width: 0; flex: 0 0 auto; margin: 2px 0 0;
}

.aiuto { font-size: 11px; color: var(--testo-tenue); }
.aiuto-allarme { color: var(--allarme); font-weight: 600; }
.azioni-form { display: flex; gap: 8px; align-items: center; margin-top: 4px; }
/* Pulsanti nowrap dentro un `fieldset` (min-width: min-content) ne alzavano il
   pavimento oltre lo schermo stretto: qui la riga va a capo invece di sfondare
   la card (sezione Cliente della modifica contratto, batch anagrafiche). */
.azioni-form.avvolgibili { flex-wrap: wrap; }
.barra-salvataggio {
  position: sticky;
  bottom: 0;
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 12px 0;
  margin-top: 8px;
  background: linear-gradient(to top, var(--fondo) 70%, transparent);
}

/* --------------------------------------------------------------- avvisi --- */
.avviso.ok { background: var(--ok-fondo); color: var(--ok); }
.avviso.info { background: var(--info-fondo); color: var(--info); }
/* Né un errore né una conferma: una cosa da guardare (la nota del dedup
   leggero su una pratica, per esempio). */
.avviso.attesa { background: var(--attesa-fondo); color: var(--attesa); }
.avviso p { margin: 0 0 6px; }
.avviso p:last-child { margin: 0; }
.azioni-avviso { display: flex; gap: 8px; align-items: center; margin-top: 8px; }
.piede.allarme { color: var(--allarme); font-weight: 600; }

/* ------------------------------------------------- azioni della scheda --- */
/* I sei pulsanti in testa alla scheda contratto stavano su **una riga sola**:
   a 390px la fila arrivava a 828px e faceva scorrere di lato l'intera pagina
   (misurato 30/07, difetto pre-esistente). Stessa lezione di `.azioni-form
   .avvolgibili` del 29/07: la riga va a capo invece di sfondare lo schermo. */
.azioni-scheda { display: flex; flex-wrap: wrap; gap: 8px; margin-left: auto;
  align-items: center; }
.azioni-scheda form { margin: 0; }
.riquadro-azione {
  background: var(--fondo-card);
  border: 1px solid var(--oro);
  border-left: 3px solid var(--oro);
  border-radius: var(--raggio);
  padding: 14px 16px;
  margin-bottom: 16px;
}
.riquadro-azione h2 { font-size: 14px; margin-bottom: 4px; }

/* ------------------------------------------- griglia di lavorazione (B1) --- */
/* Un contenitore che scorre in orizzontale scorre anche in verticale, e in un
   contenitore che scorre lo sticky si misura sul contenitore, non sulla
   pagina. Senza un'altezza massima il riquadro non scorre mai da solo e
   l'intestazione non si fisserebbe: gliela diamo, ed e' quasi tutto lo
   schermo meno l'aria per titolo e barra di salvataggio. */
.tabella-scorrevole { overflow: auto; max-height: calc(100vh - 230px); }
.griglia-lavorazione th.colonna-azione,
.griglia-lavorazione td.colonna-azione { background: var(--fondo-evidenziata); }
.griglia-lavorazione td.colonna-azione input[type="date"],
.griglia-lavorazione td.colonna-azione select {
  font-family: inherit;
  font-size: 11px;
  padding: 3px 5px;
  border: 1px solid var(--bordo-forte);
  border-radius: 3px;
  background: var(--fondo-card);
  color: var(--testo);
  min-width: 120px;
  max-width: 160px;
}
.griglia-lavorazione input[type="checkbox"] { width: 16px; height: 16px; }
tr.riga-errore > td { box-shadow: inset 0 -1px 0 var(--allarme); }
tr.riga-messaggio-errore td {
  background: var(--allarme-fondo);
  color: var(--allarme);
  font-size: 11px;
}

/* ----------------------------------------------------------- wizard (B4) --- */
.passo legend { display: flex; align-items: center; gap: 8px; }
.numero-passo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--accento);
  color: var(--testo-inverso);
  font-size: 11px;
}
.scelta-cliente { display: flex; gap: 18px; margin-bottom: 12px; }
.scelta-cliente .opzione {
  display: flex; align-items: center; gap: 6px; font-size: var(--testo-piccolo);
}
.cliente-scelto {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid var(--verde-foglia);
  border-radius: var(--raggio);
  background: var(--ok-fondo);
  margin-top: 8px;
}
.cliente-scelto.vuoto-scelta {
  border: 1px dashed var(--bordo-forte);
  background: var(--fondo-testata);
}
.risultati-ricerca { margin-top: 8px; }
.dettaglio-indirizzo { margin-top: 10px; }
.dettaglio-indirizzo summary {
  cursor: pointer; font-size: var(--testo-piccolo); color: var(--accento);
}
.riquadro-eccezione { margin-top: 10px; }
.riga-allegato { align-items: flex-end; }

/* ------------------------------------------------------- eccezioni (B5) --- */
.eccezione { margin-bottom: 12px; }
.testata-eccezione {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 8px;
}
.riferimenti {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 8px;
}
.payload {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 0;
  margin: 0 0 10px;
  font-size: var(--testo-piccolo);
}
.payload dt {
  color: var(--testo-tenue); padding: 3px 8px 3px 0;
  border-bottom: 1px solid var(--fondo-testata);
}
.payload dd {
  margin: 0; padding: 3px 0; border-bottom: 1px solid var(--fondo-testata);
  word-break: break-word;
}
.chiusura-eccezione { border-top: 1px solid var(--bordo); padding-top: 10px; }
.esito-chiuso {
  border-top: 1px solid var(--bordo); padding-top: 8px; margin: 0;
  font-size: var(--testo-piccolo); color: var(--testo-tenue);
}
.vuoto-sezione {
  text-align: center; color: var(--testo-tenue); padding: 32px;
  background: var(--fondo-card); border: 1px dashed var(--bordo);
  border-radius: var(--raggio);
}

/* ------------------------------------------------------------- log (B6) --- */
.cambiamenti { max-width: 520px; }
.cambiamento {
  display: flex; gap: 6px; align-items: baseline; flex-wrap: wrap;
  padding: 1px 0;
}
.nome-campo { color: var(--testo-tenue); min-width: 120px; }
.cambiamento .prima { text-decoration: line-through; color: var(--testo-tenue); }
.cambiamento .freccia { color: var(--oro); }
.cambiamento .dopo { font-weight: 600; }

/* --------------------------------------------------- configurazione (B8) --- */
.tab { display: flex; gap: 4px; border-bottom: 1px solid var(--bordo);
       margin-bottom: 14px; }
.tab a {
  padding: 7px 16px; color: var(--testo-tenue); font-weight: 600;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tab a:hover { text-decoration: none; color: var(--testo); }
.tab a.attiva { color: var(--accento); border-bottom-color: var(--oro); }
.modulo.card { margin-top: 16px; }
.griglia-punti { max-width: 560px; }
.griglia-punti th { text-align: left; }
.cella-punti {
  font-family: var(--font-mono);
  font-size: var(--testo-piccolo);
  padding: 4px 6px;
  border: 1px solid var(--bordo-forte);
  border-radius: 3px;
  background: var(--fondo-card);
  color: var(--testo);
  width: 62px;
  text-align: right;
}

/* =========================================================================
   Mattone 5 — pipeline export Bridge e ritocchi UI.
   ========================================================================= */

/* ------------------------------------------------- righe per pagina (A2) --- */
.per-pagina { display: flex; align-items: center; gap: 6px;
              font-size: var(--testo-piccolo); color: var(--testo-tenue); }
.per-pagina select { min-width: 80px; }
.testata-elenco {
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
  margin-bottom: 8px;
}
.testata-elenco .conteggio { margin: 0; }

/* --------------------------------------------------------- export (B2/B3) --- */
/* Il numero dei pronti e' la prima cosa che si guarda entrando: sta grande,
   accanto al pulsante che lo trasforma in un file. */
.testata-export {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  background: var(--fondo-card);
  border: 1px solid var(--bordo);
  border-left: 3px solid var(--oro);
  border-radius: var(--raggio);
  padding: 14px 18px;
  margin-bottom: 16px;
}
.testata-export .numerone { margin: 0; }
.testata-export .spiega { flex: 1 1 320px; color: var(--testo-tenue);
                          font-size: var(--testo-piccolo); }
.testata-export form { margin: 0; }

.gruppo-modifiche { margin-bottom: 18px; }
.gruppo-modifiche > h3 {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 6px; font-size: 13px;
}
.istruzione { font-weight: 500; }
.istruzione .mono { font-weight: 600; }
/* Il cambio collaboratore e' l'unica istruzione in due tempi: si vede che e'
   diversa senza doverla leggere fino in fondo. */
tr.doppia-istruzione > td { background: var(--attesa-fondo); }
tr.doppia-istruzione:hover > td { background: var(--fondo-riga-hover); }
.seconda-parte { display: block; color: var(--attesa); margin-top: 2px; }

.riga-esportazione summary { cursor: pointer; }
.dettaglio-export { margin-top: 10px; }
.stato-generato { background: var(--attesa-fondo); color: var(--attesa); }
.stato-confermato_caricato { background: var(--ok-fondo); color: var(--ok); }
/* Lista/export ritirato: neutro come un contratto cancellato — non e' un errore
   da vedere in rosso, e' una cosa messa da parte apposta. */
.stato-annullata { background: var(--stato-cancellato-fondo);
                   color: var(--stato-cancellato); }

/* Gli stati di una riga `modifiche_bridge` nel blocco della scheda contratto
   (30/07). Stessa scala di lettura degli altri stati: in attesa -> in corso ->
   fatto, e il ritirato in neutro. */
.stato-modifica-pendente { background: var(--attesa-fondo); color: var(--attesa); }
.stato-modifica-esportata { background: var(--info-fondo); color: var(--info); }
.stato-modifica-confermata { background: var(--ok-fondo); color: var(--ok); }
.stato-modifica-annullata { background: var(--stato-cancellato-fondo);
                            color: var(--stato-cancellato); }

/* --------------------------------------------- filtri richiudibili (mobile) --- */
/* Su desktop il pulsante non esiste e la card dei filtri sta dov'e' sempre
   stata: qui si aggiunge solo il modo di chiuderla, non si cambia niente. */
.apri-filtri { display: none; margin-bottom: 12px; }
.apri-filtri .conta-filtri { font-variant-numeric: tabular-nums; }

/* =========================================================================
   Mobile (< 768px). Il menu non si comprime: sparisce, e torna a richiesta
   come pannello sovrapposto con le etichette per esteso. Una striscia di sole
   icone su un telefono ruba larghezza a una tabella che ne ha gia' poca, e si
   legge male proprio dove si legge peggio.
   ========================================================================= */
@media (max-width: 767px) {
  .barra-mobile {
    display: flex;
    align-items: center;
    gap: 12px;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 52px;
    padding: 0 14px;
    background: var(--fondo-barra);
    border-bottom: 1px solid var(--bordo);
    z-index: 30;
  }
  .hamburger {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    width: 24px;
    height: 17px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
  }
  .hamburger span {
    display: block;
    height: 2px;
    border-radius: 2px;
    background: var(--testo);
  }
  .logo-mobile {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 700;
    font-size: 12px;
    letter-spacing: 0.10em;
    color: var(--testo);
  }
  .logo-mobile img { width: 26px; height: 26px; }
  .logo-mobile:hover { text-decoration: none; }

  /* Il menu: fuori dallo schermo finche' non serve. `transform` e non
     `display` perche' scivola dentro, e uno scorrimento si segue con
     l'occhio — un pannello che appare di colpo no. */
  .laterale {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    width: 264px;
    height: 100%;
    padding: 12px 10px;
    transform: translateX(-100%);
    /* `visibility` insieme al `transform`: spostare fuori schermo nasconde il
       menu all'occhio ma **non** alla tastiera, e chi naviga col tab si
       ritroverebbe a percorrere dieci voci invisibili prima di arrivare al
       contenuto. `visibility: hidden` lo toglie dal giro; il ritardo nella
       transizione lo fa sparire a scivolata finita, non a meta'. */
    visibility: hidden;
    transition: transform 180ms ease, visibility 0s linear 180ms;
    box-shadow: 4px 0 24px rgba(20, 25, 33, 0.18);
    z-index: 50;
  }
  .laterale.aperto {
    transform: translateX(0);
    visibility: visible;
    transition: transform 180ms ease, visibility 0s;
  }
  /* Aperto, le etichette ci sono sempre: qui non esiste la forma a icone. */
  .laterale .etichetta { display: inline; }
  .laterale .icona { width: 20px; }
  .chiudi-menu { display: block; }
  .testata-laterale {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
  }
  /* Comprimere non ha senso quando il menu e' gia' un pannello che si chiude. */
  .comprimi { display: none; }

  .scrim {
    position: fixed;
    inset: 0;
    background: rgba(20, 25, 33, 0.34);
    z-index: 40;
  }
  /* Col pannello aperto la pagina sotto non deve scorrere: si scorre il menu. */
  body.menu-aperto { overflow: hidden; }

  .impaginato { display: block; }
  .contenuto { padding: 66px 12px 32px; max-width: none; }

  .apri-filtri { display: inline-flex; }
  .filtri.chiusi-mobile { display: none; }

  /* Il popover su telefono non si appende alla «i»: ancorato li' sborderebbe
     a destra (la «i» sta gia' a meta' schermo e il riquadro e' largo 320px) e
     farebbe scorrere di lato la pagina — il difetto che il ritocco precedente
     aveva appena chiuso. Diventa un foglietto in basso, largo quanto lo
     schermo meno l'aria: `fixed`, quindi non allarga niente. */
  .popover {
    position: fixed;
    top: auto;
    left: 12px;
    right: 12px;
    bottom: 14px;
    width: auto;
    max-width: none;
    z-index: 60;
  }

  /* Le tabelle sono piu' larghe di un telefono, e senza questo a scorrere di
     lato e' la **pagina**: titolo, pulsante «Filtri» e conteggio scivolano via
     mentre cerchi la colonna Offerta. Cosi' scorre solo la tabella e il resto
     resta dov'e'. `min-width: 100%` la tiene comunque larga quanto lo schermo
     quando le colonne sono poche.

     `max-height` non e' un vezzo, e' cio' che rende fissa l'intestazione.
     Un elemento che scorre in orizzontale scorre anche in verticale (il CSS
     non permette `overflow-x: auto` con `overflow-y: visible`: il secondo
     diventa `auto` da solo), e dentro un contenitore che scorre lo `sticky`
     si misura sul **contenitore**, non sulla pagina. Senza un tetto d'altezza
     il contenitore non scorre mai per conto suo — scorre la pagina sotto — e
     l'intestazione non ha nulla a cui restare attaccata: e' il motivo per cui
     il fix del Mattone 5 teneva su desktop e non su telefono.

     Il tetto e' quasi tutto lo schermo: cosi' la pagina si sposta di pochi
     pixel e la tabella resta praticamente ferma sotto la barra, mentre a
     scorrere sono le righe dentro di lei — con l'intestazione appesa in cima.
     `dvh` sta dopo `vh` di proposito: dove non e' riconosciuto vale la riga
     prima, e su iOS tiene conto della barra del browser che si ritira. */
  table.densa {
    display: block;
    overflow: auto;
    min-width: 100%;
    width: max-content;
    max-width: 100%;
    max-height: calc(100vh - 160px);
    max-height: calc(100dvh - 160px);
  }
  /* Il fondo dev'essere pieno: sotto ci scorrono le righe. */
  table.densa th {
    position: sticky;
    top: 0;
    z-index: 2;
  }
  /* La griglia di lavorazione ha gia' il suo contenitore che scorre: se anche
     la tabella dentro si mettesse a scorrere per conto suo verrebbero due
     scorrimenti annidati, e l'intestazione si fermerebbe a meta'. */
  .tabella-scorrevole table.densa { max-height: none; overflow: visible; }
  .tabella-scorrevole {
    overflow: auto;
    max-height: calc(100vh - 160px);
    max-height: calc(100dvh - 160px);
  }

  /* Su schermo stretto una riga di filtri a fianco l'uno dell'altro diventa
     una colonna di campi larghi un dito: meglio pieni. */
  .filtri .campo { flex: 1 1 100%; }
  .filtri .campo input, .filtri .campo select,
  .filtri .campo input[type="search"] { min-width: 0; width: 100%; }
  .testata-export { flex-direction: column; align-items: flex-start; gap: 10px; }
  /* In colonna la `flex-basis` di `.spiega` non e' piu' una larghezza ma
     un'ALTEZZA: i 320px pensati per il desktop diventavano 320px di vuoto
     sotto due righe di testo, su ogni pagina con questa testata. Visto a
     390px il 20/08/2026, e sistemato dove nasce invece che sulla pagina
     nuova. */
  .testata-export .spiega { flex: 0 1 auto; }
}

/* Da 768px in su: niente barra mobile, niente pannello, niente scrim. */
@media (min-width: 768px) {
  .barra-mobile, .scrim, .chiudi-menu { display: none; }
}

/* --- Mattone 5-bis: riconciliazione Bridge ------------------------------
   Le schede per categoria sono una decina e con nomi lunghi: in riga non ci
   stanno nemmeno su desktop. Scorrono dentro la loro barra invece di mandare
   di lato la pagina — la stessa scelta presa per le tabelle il 18/07. */
.tab.schede-categorie {
  overflow-x: auto;
  flex-wrap: nowrap;
  scrollbar-width: thin;
}
.tab.schede-categorie a { white-space: nowrap; }
.tab.schede-categorie .badge {
  background: var(--fondo-testata);
  color: var(--testo-tenue);
}
.tab.schede-categorie a.attiva .badge { background: var(--allarme); color: #fff; }
/* Badge «da decidere» a zero: la categoria è lavorata, niente rosso d'allarme. */
.tab.schede-categorie .badge.zero { background: var(--stato-attivato-fondo, var(--fondo-testata));
  color: var(--testo-tenue); opacity: .7; }

/* La riga di controllo del report: contatore escluse + link ai due report. */
.controllo-riga { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center; }

/* «Segna come estranea»: il motivo accanto al pulsante, che si adatta a capo su
   schermo stretto senza rompere la fila di azioni. */
.azioni-form .estranea { display: flex; gap: 6px; align-items: center;
  flex-wrap: wrap; flex: 1 1 260px; }
.azioni-form .estranea input[type="text"] { flex: 1 1 180px; min-width: 140px; }

/* «Annulla» sulla riga di una modifica: chiuso dietro un summary, il motivo e il
   pulsante di conferma compaiono solo aprendolo. */
.annulla-modifica > summary { display: inline-block; cursor: pointer; list-style: none; }
.annulla-modifica > summary::-webkit-details-marker { display: none; }
.annulla-modifica[open] { display: flex; flex-direction: column; gap: 4px;
  align-items: flex-start; }
.annulla-modifica[open] input[type="text"] { width: 100%; min-width: 160px; }

/* Il confronto Bridge/noi: due colonne affiancate finche' c'e' larghezza, una
   sotto l'altra quando non c'e'. Affiancate sono un confronto; incolonnate su
   uno schermo stretto sarebbero due elenchi da tenere a mente. */
.confronto {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
  margin-bottom: 12px;
}
.confronto > div {
  background: var(--fondo-card);
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  padding: 10px 12px;
}
.confronto h3 {
  margin: 0 0 6px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--testo-tenue);
}
.confronto dl { display: grid; grid-template-columns: 42% 58%; margin: 0; }
.confronto dt {
  color: var(--testo-tenue);
  padding: 3px 8px 3px 0;
  font-size: var(--testo-piccolo);
}
.confronto dd { margin: 0; padding: 3px 0; word-break: break-word; }

/* Una riga che merita un'occhiata prima di spuntarla (il nominativo discorde
   negli insoluti). Non la disabilita: la marca. */
tr.attenzione > td { background: var(--fondo-evidenziata); }

/* -------------------------------------- esiti KO e richiami (Mattone 009) --- */
/* Una riga ricomparsa in «Da caricare» perché il richiamo è dovuto: si nota,
   ma non urla. Lo scaduto pesa un filo di più. */
tr.riga-richiamo > td { background: var(--fondo-evidenziata); }
tr.riga-richiamo.scaduto > td { background: var(--allarme-fondo); }

/* Il pannello Esito impila le due (o tre) strade con un filo di respiro fra
   loro; ognuna è una form a sé. */
.esito-riga .esito-strade {
  display: flex; flex-direction: column; gap: 16px;
  margin: 12px 0;
}
.esito-riga .esito-strade > form {
  padding-top: 14px; border-top: 1px solid var(--bordo);
}
.esito-riga .esito-strade > form:first-child { padding-top: 0; border-top: 0; }
.esito-riga h3 { margin: 0 0 4px; font-size: 1rem; }

/* ------------------------------------- cambio offerta con decorrenza (30/07) --- */
/* I due campi che governano un cambio d'offerta (motivo e decorrenza) restano
   spenti finché l'offerta scelta è quella attuale: `disabled` li rende grigi da
   soli, qui si aggiunge solo il segno di quando si **accendono**, così si vede
   a colpo d'occhio che si sta cambiando l'offerta e da quando. */
.campo-cambio-offerta.acceso label { color: var(--accento); }
.campo-cambio-offerta.acceso input,
.campo-cambio-offerta.acceso select {
  border-color: var(--accento);
  background: var(--accento-tenue);
}
/* La riga di micro-copy sotto i campi: informa, non allarma. Sta dentro il
   fieldset, quindi non deve prendersi i margini di un avviso di pagina. */
.nota-cambio-offerta { margin: 4px 0 0; }

/* -------------------------------- modifiche Bridge nella scheda contratto --- */
/* Il blocco riusa `.annulla-modifica` della pagina Modiche (definito sopra):
   qui serve solo che il form dell'annullo, che nella scheda è vero e non
   collegato con `form=`, non spezzi l'impilamento del <details>. */
.annulla-modifica > form { display: flex; flex-direction: column; gap: 4px;
  align-items: flex-start; }
.annulla-modifica > form input[type="text"] { width: 100%; min-width: 160px; }

/* ------------------------------- l'agente di estrazione (batch 2) --- */
/* Il semaforo di una pratica: un pallino in lista, un tag nella scheda. Il
   grigio e' «non analizzata», che e' diverso da «va bene» — e infatti non e'
   verde. */
span.pallino.semaforo-verde { background: var(--verde-foglia); }
span.pallino.semaforo-giallo { background: var(--attesa); }
span.pallino.semaforo-rosso { background: var(--allarme); }
span.pallino.semaforo-grigio { background: var(--neutro); }
.tag.semaforo-verde { background: var(--ok-fondo); color: var(--ok); }
.tag.semaforo-giallo { background: var(--attesa-fondo); color: var(--attesa); }
.tag.semaforo-rosso { background: var(--allarme-fondo); color: var(--allarme); }
.tag.semaforo-grigio { background: var(--neutro-fondo); color: var(--neutro); }

/* L'esito di un singolo campo. Cinque valori, cinque colori, e nessuno di
   questi e' un giudizio sul cliente: sono giudizi sulla lettura. */
.tag.esito-ok { background: var(--ok-fondo); color: var(--ok); }
.tag.esito-typo_corretto { background: var(--info-fondo); color: var(--info); }
.tag.esito-mismatch { background: var(--attesa-fondo); color: var(--attesa); }
.tag.esito-illeggibile { background: var(--allarme-fondo); color: var(--allarme); }
.tag.esito-mancante { background: var(--neutro-fondo); color: var(--neutro); }

/* La tabella dei campi estratti: il valore e' un campo di testo, perche' si
   corregge dov'e' scritto e non in un'altra pagina. */
.campi-agente input[type="text"] { width: 100%; min-width: 120px;
  font-family: var(--mono, ui-monospace, monospace); }
.campi-agente td { vertical-align: top; }
.campi-agente .nota-campo { color: var(--testo-tenue);
  font-size: var(--testo-minuscolo, 11px); display: block; margin-top: 2px; }
/* La riga di un campo obbligatorio che non passa i cancelli: un filetto a
   sinistra, non un fondo colorato — la tabella resta leggibile e l'occhio
   trova comunque le righe da guardare. */
.campi-agente tr.in-dubbio > td:first-child {
  box-shadow: inset 3px 0 0 var(--attesa); }
.campi-agente caption { text-align: left; font-weight: 600; padding: 10px 0 4px; }


/* ------------------------------- i caricamenti partner (batch 3) --- */
/* Lo stato di un caricamento. Stessa famiglia terrosa degli status del
   contratto: la bozza e' in attesa, l'invio e' informativo, gli esiti sono
   verdi solo quando sono davvero tornati. */
.tag.stato-caricamento-bozza { background: var(--neutro-fondo); color: var(--neutro); }
.tag.stato-caricamento-allegati_pronti { background: var(--info-fondo); color: var(--info); }
.tag.stato-caricamento-excel_generato { background: var(--attesa-fondo); color: var(--attesa); }
.tag.stato-caricamento-inviato { background: var(--accento-tenue); color: var(--accento-scuro); }
.tag.stato-caricamento-esiti_ricevuti { background: var(--ok-fondo); color: var(--ok); }
.tag.stato-caricamento-annullato { background: var(--allarme-fondo); color: var(--allarme); }

/* Le due code verso il partner. Gli switch aspettano la finestra di fine mese e
   sono la routine: neutri. Le altre pratiche il partner le lavora entro due
   giorni e vanno mandate appena ci sono: hanno il colore dell'attesa, che in
   questa pagina vuol dire "questo aspetta te". */
.tag.tipo-caricamento-switch { background: var(--neutro-fondo); color: var(--neutro); }
.tag.tipo-caricamento-altre_pratiche { background: var(--attesa-fondo); color: var(--attesa); }

/* La sequenza guidata: quattro riquadri, uno per passo. Il passo di adesso ha
   il filetto d'accento a sinistra, quelli fatti restano leggibili ma spenti, e
   quelli che verranno dopo sono attenuati — non nascosti: si deve poter
   leggere in anticipo cosa succedera'. */
.passi { display: grid; gap: 12px; margin: 16px 0 20px; }
@media (min-width: 900px) {
  .passi { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.passo {
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  padding: 12px 14px;
  background: var(--fondo-card);
}
.passo h2 { margin: 0 0 6px; font-size: 1rem; }
.passo .nota { margin: 0 0 8px; }
.passo.adesso { box-shadow: inset 3px 0 0 var(--accento); }
.passo.dopo { opacity: .62; }
.passo.fatto h2::after { content: " ✓"; color: var(--ok); }
.passo .azioni-form { display: flex; gap: 8px; flex-wrap: wrap; }
.passo .esito-passo { margin: 0 0 8px; font-size: 13px; color: var(--ok); }
.testo-email { margin: 0 0 10px; }
.testo-email textarea {
  width: 100%; margin-top: 6px; font-family: var(--font);
  font-size: 13px; padding: 8px; border: 1px solid var(--bordo);
  border-radius: var(--raggio); background: var(--fondo-riga-alt);
}

/* L'anteprima, un blocco per pratica. L'unita' che si guarda e' la pratica,
   perche' e' la pratica a partire o a restare fuori tutta intera: le sue righe
   stanno dentro, e si aprono solo quando servono. Restano aperte da sole
   quelle con un rosso. */
.pratica-tracciato {
  border: 1px solid var(--bordo); border-radius: var(--raggio);
  margin: 8px 0; background: var(--fondo-card);
}
.pratica-tracciato > summary {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  padding: 9px 12px; cursor: pointer; font-size: .95rem;
}
.pratica-tracciato > summary::-webkit-details-marker { display: none; }
.pratica-tracciato > summary::before {
  content: "▸"; color: var(--testo-tenue); font-size: 11px;
}
.pratica-tracciato[open] > summary::before { content: "▾"; }
.pratica-tracciato[open] > summary { border-bottom: 1px solid var(--bordo); }
.pratica-tracciato > summary .cliente { font-weight: 600; }
.pratica-tracciato > *:not(summary) { padding: 0 12px; }
.pratica-tracciato.esclusa { box-shadow: inset 3px 0 0 var(--allarme); }

/* L'anteprima di una riga del tracciato. Le colonne sono ottantotto: quelle
   legittimamente vuote non si mostrano, o la pagina sarebbe illeggibile e
   nessuno la guarderebbe — che e' il modo di non accorgersi di un buco. */
.riga-tracciato { margin: 14px 0 18px; }
.riga-tracciato h3 {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin: 0 0 6px; font-size: .98rem;
}
.riga-tracciato.esclusa { box-shadow: inset 3px 0 0 var(--allarme);
  padding-left: 10px; }
table.tracciato td:first-child { width: 30%; font-size: 12px; }
table.tracciato tr.buco-blocca > td:first-child {
  box-shadow: inset 3px 0 0 var(--allarme); }
table.tracciato tr.buco-avvisa > td:first-child {
  box-shadow: inset 3px 0 0 var(--attesa); }
table.densa tr.riga-ko > td:first-child {
  box-shadow: inset 3px 0 0 var(--allarme); }

/* Da dove viene una cella. Solo tre fonti hanno un colore: quelle che nessuno
   ha letto ne' digitato. Le altre restano grigie — evidenziare tutto e'
   evidenziare niente. */
.tag.fonte-calcolata,
.tag.fonte-decodificata,
.tag.fonte-fissa { background: var(--attesa-fondo); color: var(--attesa); }
.tag.fonte-estratta,
.tag.fonte-digitata,
.tag.fonte-anagrafica,
.tag.fonte-vuota_ammessa { background: var(--neutro-fondo); color: var(--neutro); }

ul.buchi { margin: 0; padding-left: 18px; }
ul.buchi li { margin: 2px 0; }

/* Spiccioli condivisi: la colonna della spunta non deve prendersi spazio, e il
   campo delle note deve prendersi quello che avanza. */
th.stretta { width: 28px; }
.campo.cresce { flex: 1 1 240px; }

/* ------------------------------------------------------- cruscotto --- */
/* I contatori in testa a «Caricamenti partner»: sette tessere cliccabili che
   portano ognuna alla sua lista filtrata. Sono piu' piccole delle `.card` della
   Dashboard di proposito — la' un riquadro e' il contenuto della pagina, qui e'
   l'indice di quello che c'e' sotto, e sette riquadri grandi spingerebbero il
   lavoro vero sotto la piega. */
.griglia-cruscotto {
  display: grid;
  /* 150px e non 168: a 1400px le sette tessere devono stare in una riga
     sola. Con la soglia piu' alta la settima andava a capo da sola, e una
     tessera orfana sotto le altre sei sembra un errore invece di un
     indice. */
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  margin: 0 0 18px;
}
.tessera {
  display: block;
  background: var(--fondo-card);
  border: 1px solid var(--bordo);
  border-left: 3px solid var(--bordo-forte);
  border-radius: var(--raggio);
  padding: 10px 12px;
  color: inherit;
}
a.tessera:hover { background: var(--fondo-riga-hover); text-decoration: none; }
a.tessera:focus-visible { outline: 2px solid var(--oro); outline-offset: 1px; }
/* La tessera attiva e' quella il cui filtro sta gia' governando la pagina: si
   deve poter capire da dove si e' arrivati senza rileggere la barra degli
   indirizzi. */
.tessera.attiva { border-left-color: var(--accento); background: var(--accento-tenue); }
.tessera .conta { font-size: 24px; font-weight: 600; line-height: 1.1; }
.tessera .voce {
  display: block;
  font-size: var(--testo-piccolo);
  color: var(--testo-tenue);
  margin-top: 2px;
}
/* Il colore dice «questo aspetta qualcuno», mai da solo: accanto c'e' sempre
   la parola. Uno zero non si colora mai — niente da fare non e' un allarme. */
.tessera.attesa .conta { color: var(--attesa); }
.tessera.attesa { border-left-color: var(--attesa); }
.tessera.allarme .conta { color: var(--allarme); }
.tessera.allarme { border-left-color: var(--allarme); }
.tessera.buona .conta { color: var(--ok); }
.tessera.buona { border-left-color: var(--verde-foglia); }
.tessera.spenta .conta { color: var(--testo-tenue); font-weight: 500; }

/* Il filtro attivo, dichiarato sopra la lista che sta governando. */
.filtro-attivo {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--accento-tenue);
  border: 1px solid var(--oro-tenue);
  border-radius: var(--raggio);
  padding: 7px 12px;
  margin: 0 0 10px;
  font-size: var(--testo-piccolo);
}

/* La riga di una attivazione con la data corretta a mano: si deve vedere che
   non e' piu' quella proposta. */
.data-attivazione { width: 8.5em; }
.data-attivazione.corretta,
.data-decorrenza.corretta { border-color: var(--accento); background: var(--accento-tenue); }

/* Le decorrenze delle pratiche non-switch, dentro il passo 2 della scheda: una
   tabella in un `details`, che di suo starebbe stretta in un riquadro. */
/* Gli esiti di ritorno: uno strumento chiuso, non un passo della sequenza.
   Il riquadro e' volutamente piu' spento dei tre passi qui sopra — se un giorno
   servira', si apre; se non serve mai, non chiede niente a nessuno. */
.strumento-esiti {
  border: 1px dashed var(--bordo);
  border-radius: 10px;
  padding: 12px 14px;
  margin: 0 0 20px;
}
.strumento-esiti summary { cursor: pointer; font-weight: 600; }
.strumento-esiti[open] summary { margin-bottom: 8px; }

.decorrenze { margin: 0 0 12px; width: 100%; }
.decorrenze summary { cursor: pointer; font-weight: 600; }
.decorrenze table { margin-top: 8px; }
