@charset "utf-8";

/* =========================================================================
   ISPAY · ufficio acquisti storici
   Mondo: il nodo splendente.

   La palette NON e' inventata: e' quella misurata nel documento di ISPAY
   Chain. Giallo #FFDE05, ambra #FFB305, arancio #FF7200, ciano #15A9E9,
   blu elettrico #0D27D6, verde #49DB6C, viola #844BF0, navy #00134A.

   Fondo: abisso blu con nebulosa che respira e una rete di nodi che si
   muove davvero (canvas). Le superfici sono pannelli di vetro scuro con
   bordo che prende la luce: la profondita' e' costruita con transform e
   ombre a colori, non simulata con filtri.
   ========================================================================= */

/* ------------------------------------------------------------------ fonti */

@font-face {
  font-family: "PT Serif"; font-style: normal; font-weight: 400;
  font-display: swap; src: url("../fonti/pt-serif-400.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: "PT Serif"; font-style: normal; font-weight: 700;
  font-display: swap; src: url("../fonti/pt-serif-700.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: "Source Sans 3"; font-style: normal; font-weight: 400;
  font-display: swap; src: url("../fonti/source-sans-3-400.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: "Source Sans 3"; font-style: normal; font-weight: 600;
  font-display: swap; src: url("../fonti/source-sans-3-600.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: "Source Sans 3"; font-style: normal; font-weight: 700;
  font-display: swap; src: url("../fonti/source-sans-3-700.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: "Courier Prime"; font-style: normal; font-weight: 400;
  font-display: swap; src: url("../fonti/courier-prime-400.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+2000-206F;
}

/* -------------------------------------------------------------- i colori */

:root {
  /* la palette di ISPAY, misurata sul documento */
  --giallo:  #FFDE05;
  --ambra:   #FFB305;
  --arancio: #FF7200;
  --ciano:   #15A9E9;
  --blu:     #0D27D6;
  --verde:   #49DB6C;
  --viola:   #844BF0;
  --lilla:   #E0D2FC;
  --navy:    #00134A;
  --ardesia: #212830;

  /* l'abisso: quattro profondita' di blu, non un grigio */
  --vuoto-1: #000714;
  --vuoto-2: #001134;
  --vuoto-3: #0A1C5C;
  --vuoto-4: #12257A;

  --testo:      #EAF2FF;
  --testo-muto: #9FB4DC;
  /* Il testo tenue e' stato alzato da #7A93C4. Su `#12257A` il vecchio valore
     scendeva a 4,33:1, sotto la soglia dei 4,5:1 che vale per un testo da
     13 px. Il nuovo resta sullo stesso tono (azzurro desaturato della
     famiglia) ma con la luminosita' giusta: sui pannelli misurati va da
     6,2:1 a 7,6:1. Non e' un abbellimento: e' il testo che spiega cosa
     scrivere in un campo, e se non si legge il membro sbaglia. */
  --testo-tenue:#93A9D6;

  --luce:  rgba(21,169,233,.55);
  --luce-b:rgba(13,39,214,.45);

  /* profondita': tre livelli, ognuno con la sua ombra colorata */
  --d1: 0 10px 26px -14px rgba(0,10,60,.9), 0 1px 0 0 rgba(120,190,255,.10) inset;
  --d2: 0 26px 60px -26px rgba(0,6,50,.95), 0 1px 0 0 rgba(140,200,255,.14) inset;
  --d3: 0 46px 100px -40px rgba(0,4,40,.98), 0 1px 0 0 rgba(150,210,255,.18) inset;

  --r-passo: 16px;
  --r-ampio: 26px;

  --respiro: 1180px;
  --serif: "PT Serif", Georgia, serif;
  --sans:  "Source Sans 3", system-ui, -apple-system, sans-serif;
  --mono:  "Courier Prime", ui-monospace, monospace;
}

/* ------------------------------------------------------------------ base */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100dvh;
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.62;
  color: var(--testo);
  background: var(--vuoto-1);
  overflow-x: hidden;
}

a { color: var(--ciano); text-decoration: none; }
a:hover { color: #7FD4FF; }

h1, h2, h3 { font-family: var(--serif); font-weight: 700; line-height: 1.12; margin: 0; }

p { margin: 0; }

svg { display: block; }

/* il testo selezionato si accende come il resto del mondo */
::selection { background: var(--giallo); color: var(--vuoto-1); }

.salta {
  position: absolute; left: -9999px; top: 0; z-index: 60;
  background: var(--ciano); color: var(--vuoto-1);
  padding: 12px 18px; border-radius: 0 0 10px 0; font-weight: 600;
}
.salta:focus { left: 0; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ------------------------------------------------- lo sfondo: l'abisso vivo */

/* quattro strati che si muovono a velocita' diverse: e' il movimento che
   tiene vivo lo sfondo anche quando la pagina e' ferma */
.abisso {
  position: fixed; inset: 0; z-index: 0; overflow: hidden;
  background:
    radial-gradient(120% 80% at 12% -10%, rgba(21,169,233,.30), transparent 58%),
    radial-gradient(100% 70% at 88% 8%,  rgba(132,75,240,.26), transparent 60%),
    radial-gradient(120% 90% at 50% 110%, rgba(13,39,214,.42), transparent 64%),
    linear-gradient(180deg, var(--vuoto-1) 0%, var(--vuoto-2) 48%, #00091F 100%);
}

.abisso__nebbia {
  position: absolute; inset: -30%;
  background:
    radial-gradient(closest-side, rgba(73,219,108,.16), transparent) 18% 30%/44% 40% no-repeat,
    radial-gradient(closest-side, rgba(21,169,233,.20), transparent) 76% 22%/40% 36% no-repeat,
    radial-gradient(closest-side, rgba(255,179,5,.12), transparent) 58% 72%/38% 34% no-repeat,
    radial-gradient(closest-side, rgba(132,75,240,.18), transparent) 26% 82%/46% 40% no-repeat;
  filter: blur(26px);
  animation: nebbia 34s ease-in-out infinite alternate;
}
@keyframes nebbia {
  0%   { transform: translate3d(-2%, -1%, 0) scale(1);    opacity: .75; }
  50%  { transform: translate3d(2%, 2%, 0) scale(1.08);   opacity: 1; }
  100% { transform: translate3d(-1%, 3%, 0) scale(1.02);  opacity: .82; }
}

/* la gramma del mondo, in prospettiva: due piani che scorrono via */
.abisso__griglia {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(21,169,233,.16) 1px, transparent 1px),
    linear-gradient(90deg, rgba(21,169,233,.16) 1px, transparent 1px);
  background-size: 62px 62px;
  transform: perspective(560px) rotateX(66deg) scale(2.1);
  transform-origin: 50% 0;
  mask-image: linear-gradient(180deg, transparent 4%, #000 34%, #000 72%, transparent 96%);
  -webkit-mask-image: linear-gradient(180deg, transparent 4%, #000 34%, #000 72%, transparent 96%);
  animation: gramma 16s linear infinite;
  opacity: .55;
}
@keyframes gramma {
  from { background-position: 0 0, 0 0; }
  to   { background-position: 0 62px, 0 0; }
}

/* cubi 3D veri: sei facce, una scena in prospettiva */
.cubi { position: absolute; inset: 0; perspective: 900px; perspective-origin: 50% 42%; }
.cubo {
  position: absolute; width: 58px; height: 58px;
  transform-style: preserve-3d;
  animation: galleggio 13s ease-in-out infinite;
}
.cubo > i {
  position: absolute; inset: 0; display: block;
  border: 1px solid rgba(21,169,233,.5);
  background: linear-gradient(140deg, rgba(21,169,233,.20), rgba(13,39,214,.06));
  box-shadow: 0 0 26px rgba(21,169,233,.30) inset, 0 0 18px rgba(21,169,233,.22);
}
.cubo > i:nth-child(1) { transform: translateZ(29px); }
.cubo > i:nth-child(2) { transform: rotateY(90deg) translateZ(29px); }
.cubo > i:nth-child(3) { transform: rotateY(180deg) translateZ(29px); }
.cubo > i:nth-child(4) { transform: rotateY(270deg) translateZ(29px); }
.cubo > i:nth-child(5) { transform: rotateX(90deg) translateZ(29px); }
.cubo > i:nth-child(6) { transform: rotateX(270deg) translateZ(29px); }

.cubo:nth-child(1) { top: 16%; left: 9%;  animation-duration: 15s; }
.cubo:nth-child(2) { top: 62%; left: 16%; width: 40px; height: 40px; animation-duration: 11s; animation-delay: -3s; }
.cubo:nth-child(3) { top: 22%; right: 12%; width: 76px; height: 76px; animation-duration: 19s; animation-delay: -6s; }
.cubo:nth-child(4) { bottom: 12%; right: 20%; width: 34px; height: 34px; animation-duration: 9s; animation-delay: -2s; }
.cubo:nth-child(5) { top: 44%; left: 42%; width: 26px; height: 26px; animation-duration: 13s; animation-delay: -8s; opacity: .7; }
.cubo:nth-child(6) { bottom: 24%; left: 46%; width: 20px; height: 20px; animation-duration: 17s; animation-delay: -5s; opacity: .55; }

@keyframes galleggio {
  0%, 100% { transform: translate3d(0,0,0) rotateX(18deg) rotateY(0deg); }
  25%      { transform: translate3d(14px,-22px,40px) rotateX(38deg) rotateY(72deg); }
  50%      { transform: translate3d(-10px,18px,-30px) rotateX(-14deg) rotateY(158deg); }
  75%      { transform: translate3d(12px,24px,26px) rotateX(52deg) rotateY(246deg); }
}

/* L'ATTO: quando la firma cala, il mondo risponde. Sei cubi si accendono a
   cascata, dal primo all'ultimo, come un'onda che attraversa la scena.
   `filter` qui e' vietato: su un elemento con preserve-3d crea un containing
   block e le sei facce perderebbero la profondita'. Per lo stesso motivo i
   ritardi stanno sulla transizione delle facce e non su `animation` del cubo,
   che cosi' continua a galleggiare senza interruzioni. */
.cubo > i { transition: border-color .45s ease, box-shadow .45s ease; }
.in-atto .cubo > i {
  border-color: rgba(255,222,5,.92);
  box-shadow: 0 0 36px rgba(255,222,5,.55) inset, 0 0 30px rgba(255,222,5,.45);
}
.in-atto .cubo:nth-child(1) > i { transition-delay: .00s; }
.in-atto .cubo:nth-child(2) > i { transition-delay: .06s; }
.in-atto .cubo:nth-child(3) > i { transition-delay: .12s; }
.in-atto .cubo:nth-child(4) > i { transition-delay: .18s; }
.in-atto .cubo:nth-child(5) > i { transition-delay: .24s; }
.in-atto .cubo:nth-child(6) > i { transition-delay: .30s; }
/* l'accensione si spegne: il mondo torna al suo stato di riposo */
body.atto-esaurito .cubo > i { transition-delay: 0s; transition-duration: 1.1s; }
body.atto-esaurito .cubo > i {
  border-color: rgba(21,169,233,.5);
  box-shadow: 0 0 26px rgba(21,169,233,.30) inset, 0 0 18px rgba(21,169,233,.22);
}

/* la rete di nodi: il nome del progetto, in movimento continuo */
.rete {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  opacity: .85;
}

.vineta {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(120% 90% at 50% 40%, transparent 42%, rgba(0,4,20,.72) 100%);
}

/* ------------------------------------------------------------ il contenitore */

.pagina {
  position: relative; z-index: 2;
  min-height: 100dvh;
  padding: clamp(16px, 3.4vw, 40px);
  display: flex; flex-direction: column;
}
.pagina > * { width: 100%; max-width: var(--respiro); margin-inline: auto; }

/* ------------------------------------------------------------------ testata */

/* T3 · La testata su un telefono stretto.

   Prima: tre righe, 206 px prima del contenuto, e i comandi sotto i 44 px che
   il dito preme con facilita'. Adesso e' UNA riga sola: il marchio, i comandi
   (icona + nome su desktop, solo icona con `aria-label` su telefono) e la
   lingua. Sul telefono il nome dei comandi sparisce e restano i simboli, che
   hanno un nome accessibile dichiarato nel template.

   Il paralassa allo scroll agisce sul MARCHIO e basta: sfumare la
   navigazione a .28 di opacita' (com'e' prima) vuol dire che il comando che
   serve in quel momento sparisce proprio mentre lo si cerca. */
.barra {
  display: flex; align-items: center; gap: 14px;
  padding: 4px 0 18px;
  min-height: 56px;
}
/* La barra del contatore sta dentro la pagina, non nella testata: la coda di
   18px che serve a staccare il titolo dal bordo dello schermo qui aggiunge
   solo aria fra il contatore e le schede delle categorie. */
.barra--coda { padding-bottom: 4px; }

.marchio {
  display: inline-flex; align-items: center; gap: 11px;
  text-decoration: none; color: var(--testo);
  /* il nome «ISPAY» si puo' nascondere: il logo lo dice gia' */
  /* Il marchio e' un link che torna alla pagina iniziale, quindi e' un
     bersaglio come gli altri: con il logo a 30 px finiva alto 26 px su un
     telefono, sotto i 44 che si preme col dito. Non si allarga il logo, che
     deve restare della sua misura: si allarga l'area attorno, e ogni tanto il
     dito lo sfiora. */
  min-height: 44px;
}
.marchio__logo {
  height: 30px; width: auto; display: block;
  filter: drop-shadow(0 0 14px rgba(21,169,233,.75));
  animation: respiro-logo 5.5s ease-in-out infinite;
}
@keyframes respiro-logo {
  0%, 100% { filter: drop-shadow(0 0 12px rgba(21,169,233,.55)); }
  50%      { filter: drop-shadow(0 0 26px rgba(73,219,108,.85)); }
}
.marchio__nome {
  font-family: var(--serif); font-weight: 700; font-size: 20px; letter-spacing: .16em;
  color: #fff; text-shadow: 0 0 22px rgba(21,169,233,.65);
}
/* Il sigillo — «ufficio acquisti storici» — era il pezzo che faceva la
   seconda riga della testata. Ora sta nel piee, dove un'etichetta
   descrittiva ha il suo posto: la testata dice chi sei, il piee cosa e' questo
   posto. */
.barra .marchio__sigillo { display: none; }
.piee .marchio__sigillo {
  display: inline-block;
  font-size: 12px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ciano);
}

.barra__voci { display: flex; align-items: center; gap: 6px; margin-left: auto; }

/* I comandi: sempre almeno 44x44 px, anche quando l'etichetta sparisce.
   Il bersaglio si allarga con `padding`, non con l'altezza del testo: cosi'
   l'icona da sola ha lo stesso bersaglio dell'icona con la parola. */
.lezione {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; min-width: 44px;
  padding: 10px 15px;
  font-family: var(--sans); font-size: 15px; font-weight: 600; color: var(--testo-muto);
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(120,170,255,.16);
  border-radius: 999px;
  cursor: pointer; text-decoration: none;
  transition: transform .22s cubic-bezier(.16,1,.3,1), color .22s,
              border-color .22s, background .22s, box-shadow .22s;
}
.lezione svg { width: 18px; height: 18px; flex: none; }
.lezione:hover {
  color: #fff; transform: translateY(-2px);
  border-color: rgba(21,169,233,.65);
  background: rgba(21,169,233,.16);
  box-shadow: 0 0 26px rgba(21,169,233,.34);
}
.lezione[aria-current="page"] {
  color: #fff; border-color: var(--ciano);
  background: linear-gradient(120deg, rgba(21,169,233,.30), rgba(13,39,214,.30));
  box-shadow: 0 0 30px rgba(21,169,233,.42), 0 0 0 1px rgba(21,169,233,.35);
}

/* il selettore lingua: un `<details>`, cioe' un dettaglio che si apre e si
   chiude da solo — anche senza JavaScript. Cinque chip in fila occupavano
   210 px e avevano bersagli 40x31 px: sotto la soglia che il dito preme
   senza mirare. */
.lingue { position: relative; margin-left: 8px; }
.lingue__scelta {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 44px; padding: 10px 14px;
  list-style: none; cursor: pointer;
  border-radius: 999px;
  border: 1px solid rgba(120,170,255,.22);
  background: rgba(255,255,255,.04);
  color: var(--testo);
  font-family: var(--sans); font-size: 14px; font-weight: 600;
  transition: border-color .2s, background .2s, color .2s;
}
.lingue__scelta::-webkit-details-marker { display: none; }
.lingue__scelta:hover { border-color: var(--ciano); background: rgba(21,169,233,.14); }
.lingue[open] .lingue__scelta { border-color: var(--ciano); color: #fff; }
.lingue__attuale { white-space: nowrap; }
.lingue__freccia { width: 14px; height: 14px; flex: none; transition: transform .2s; }
.lingue[open] .lingue__freccia { transform: rotate(180deg); }

.lingue__schiera {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 20;
  min-width: 210px; padding: 12px;
  border-radius: var(--r-passo);
  border: 1px solid rgba(120,170,255,.28);
  background: rgba(3, 14, 38, .97);
  box-shadow: var(--d2);
}
.lingue__titolo {
  font-size: 12px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  color: var(--ciano); margin-bottom: 9px;
}
.lingue__pulsanti { display: grid; gap: 5px; }
.timbro-lingua {
  display: flex; align-items: baseline; gap: 9px; width: 100%;
  min-height: 44px;
  font-family: var(--sans); font-size: 14px;
  text-align: start; text-decoration: none;
  color: var(--testo-muto);
  background: rgba(255,255,255,.03);
  border: 1px solid rgba(120,170,255,.14);
  padding: 10px 13px; border-radius: 10px; cursor: pointer;
  transition: color .2s, border-color .2s, background .2s;
}
.timbro-lingua__nome { flex: 1; }
.timbro-lingua__codice {
  font-family: var(--mono); font-size: 12px; letter-spacing: .1em;
  color: var(--testo-tenue); text-transform: uppercase;
}
.timbro-lingua:hover { color: #fff; border-color: var(--ciano); background: rgba(21,169,233,.14); }
.timbro-lingua[aria-current="true"] {
  color: var(--vuoto-1); font-weight: 700;
  background: linear-gradient(120deg, var(--giallo), var(--ambra));
  border-color: var(--giallo);
  box-shadow: 0 0 22px rgba(255,222,5,.45);
}
.timbro-lingua[aria-current="true"] .timbro-lingua__codice { color: rgba(0,7,20,.72); }

/* ------------------------------------------------------------- i pannelli */

/* T1 · I cubi non competono col testo.

   Il principio di `DESIGN.md` e' «se un effetto compete con un testo, vince il
   testo». Finche' i pannelli erano vetro traslucido (`.075` di bianco su un
   canvas animato) i sei cubi si vedevano PASSARE SOTTO i titoli, i campi e le
   righe della tabella: la scena muoveva il testo mentre lo si leggeva.

   La correzione non e' togliere il mondo — resta un abisso blu che respira —
   ma togliere il mondo da DOVE SI LEGGE:

     1. `isolate` mette il pannello in un proprio contesto di impasto, cosi'
        niente di cio' che c'e' sotto puo' ereditarne lo sfondo;
     2. lo sfondo scende su un blu pieno (`.90`), non piu' vetro: dietro al
        testo non passa piu' nessun nodo della rete;
     3. il velo sotto al contenuto (`::before`, z-index -1) e' pieno nel
        mezzo — dove stanno i titoli e le righe — e si assottiglia sui bordi,
        dove si vede ancora la scena.

   Il pannello resta un oggetto di vetro scuro: cambia solo quanto e'
   traslucido, e quanto. */
.foglio {
  position: relative;
  isolation: isolate;
  /* Lo strato in cima e' la MASCHERA: piena nel mezzo, dove stanno i titoli,
     i campi e le righe, e assottigliata verso il bordo, dove si guarda solo
     la scena. Sotto, il blu e' piu' chiaro (.62) perche' il mondo si veda
     attorno al testo e non dietro. I due si sommano: al centro il fondo
     totale supera il .97, al bordo resta circa il .62. */
  background:
    radial-gradient(90% 78% at 50% 45%,
      rgba(2,10,28,.94) 0%, rgba(2,10,28,.80) 64%, rgba(2,10,28,.50) 100%),
    linear-gradient(160deg, rgba(255,255,255,.075), rgba(255,255,255,.018) 46%, rgba(0,0,0,.10)),
    rgba(2, 10, 28, .62);
  border: 1px solid rgba(120,170,255,.20);
  border-radius: var(--r-ampio);
  box-shadow: var(--d3);
  padding: clamp(24px, 4vw, 46px);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  transform-style: preserve-3d;
  animation: pannello-entra .8s cubic-bezier(.16,1,.3,1) both;
}
.foglio--pieno { box-shadow: var(--d3), 0 0 0 1px rgba(21,169,233,.24); }

/* la linea di luce che attraversa il bordo superiore: e' il dettaglio che
   fa leggere il pannello come un oggetto, non come un rettangolo colorato */
.foglio::before {
  content: ""; position: absolute; left: 12%; right: 12%; top: -1px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--ciano), var(--giallo), var(--ciano), transparent);
  box-shadow: 0 0 18px rgba(21,169,233,.75);
  pointer-events: none;
}
.foglio::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: radial-gradient(90% 60% at 50% -10%, rgba(21,169,233,.14), transparent 62%);
  pointer-events: none; z-index: -1;
}

@keyframes pannello-entra {
  from { opacity: 0; transform: translateY(38px) rotateX(11deg) scale(.97); }
  to   { opacity: 1; transform: none; }
}

/* Il pannello segue il mouse in prospettiva.

   Il selettore aveva uno spazio dentro il nome della classe (`.foglio--
   incline`): e' una regola che non abbinava mai niente, quindi la
   transizione che doveva rendere morbido il ritorno al centro non esisteva.
   Il nome giusto e' `data-inclina`, l'attributo che mette nel template il
   pannello dell'accesso. La transizione resta comunque fuori dai calcoli del
   JavaScript: `scivola()` interpola `transform` frame per frame e, se il CSS
   transizionasse lo stesso, il ritorno al centro oscillerebbe. */
[data-inclina] { transition: transform .18s ease-out; }

/* ------------------------------------------------------------------ titoli */

.occhiello {
  font-size: 12px; font-weight: 700; letter-spacing: .24em; text-transform: uppercase;
  color: var(--ciano); margin-bottom: 12px;
  text-shadow: 0 0 18px rgba(21,169,233,.6);
}

.titolo { letter-spacing: -.015em; }
.titolo--intro {
  font-size: clamp(32px, 5.2vw, 56px);
  background: linear-gradient(100deg, #FFFFFF 8%, var(--ciano) 46%, var(--lilla) 78%, var(--giallo) 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  background-size: 220% 100%;
  animation: testo-scorrimento 9s ease-in-out infinite;
}
@keyframes testo-scorrimento {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}
.titolo--2 { font-size: clamp(23px, 3vw, 31px); color: #fff; }
.titolo--3 { font-size: 19px; color: #fff; }

.sottotitolo { color: var(--testo-muto); font-size: 16px; margin-top: 12px; max-width: 62ch; }
.monospazio { font-family: var(--mono); font-size: .94em; letter-spacing: .02em; }

.sezione { margin-top: 34px; }

/* ---------------------------------------------------------------- bottoni */

.bottone {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-family: var(--sans); font-size: 16px; font-weight: 700;
  text-decoration: none; cursor: pointer;
  padding: 13px 24px; border-radius: 12px;
  border: 1px solid transparent;
  transition: transform .2s cubic-bezier(.16,1,.3,1), box-shadow .25s, filter .25s;
}
.bottone svg { width: 18px; height: 18px; }

/* il riflesso che attraversa il pulsante al passaggio */
.bottone::after {
  content: ""; position: absolute; top: 0; left: -120%; width: 55%; height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.55), transparent);
  transform: skewX(-18deg);
  transition: left .55s cubic-bezier(.16,1,.3,1);
}
.bottone:hover::after { left: 150%; }

.bottone--pieno {
  color: var(--vuoto-1);
  background: linear-gradient(120deg, var(--giallo) 0%, var(--ambra) 46%, var(--arancio) 100%);
  box-shadow: 0 0 30px rgba(255,179,5,.45), 0 12px 30px -14px rgba(0,0,0,.85);
}
.bottone--pieno:hover { transform: translateY(-3px) scale(1.03); box-shadow: 0 0 52px rgba(255,179,5,.72), 0 16px 34px -14px rgba(0,0,0,.9); }

.bottone--timbro {
  color: #fff;
  background: linear-gradient(120deg, var(--ciano), var(--blu));
  border-color: rgba(21,169,233,.6);
  box-shadow: 0 0 30px rgba(21,169,233,.42), 0 12px 30px -14px rgba(0,0,0,.85);
}
.bottone--timbro:hover { transform: translateY(-3px) scale(1.03); box-shadow: 0 0 54px rgba(21,169,233,.75), 0 16px 34px -14px rgba(0,0,0,.9); }

.bottone--filo {
  background: rgba(255,255,255,.04); color: var(--testo);
  border-color: rgba(120,170,255,.24);
}
.bottone--filo:hover { border-color: var(--ciano); background: rgba(21,169,233,.16); transform: translateY(-2px); box-shadow: 0 0 26px rgba(21,169,233,.4); }

.bottone--chiaro { background: rgba(255,255,255,.10); color: #fff; }
.bottone--chiaro:hover { background: rgba(255,255,255,.18); }

.bottone--armato {
  background: linear-gradient(120deg, var(--arancio), #FF3D00);
  color: #fff; border-color: rgba(255,114,0,.7);
  box-shadow: 0 0 34px rgba(255,114,0,.6);
}

.bottone[disabled] { opacity: .45; cursor: not-allowed; transform: none; }

/* ------------------------------------------------------------------ campi */

.campo { display: block; margin-top: 20px; }
.campo__etichetta {
  display: block; font-size: 12px; font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--ciano); margin-bottom: 9px;
}
.campo__input, .campo select, .campo textarea {
  width: 100%; font-family: var(--sans); font-size: 16px; color: #fff;
  background: rgba(0,8,32,.5);
  border: 1px solid rgba(120,170,255,.26);
  border-radius: 12px;
  padding: 14px 16px;
  transition: border-color .2s, box-shadow .25s, background .25s;
}
.campo__input::placeholder { color: rgba(160,185,225,.45); }
.campo__input:focus, .campo select:focus, .campo textarea:focus {
  outline: none;
  border-color: var(--ciano);
  background: rgba(0,20,60,.62);
  box-shadow: 0 0 0 3px rgba(21,169,233,.20), 0 0 34px rgba(21,169,233,.42);
}
.campo--corto .campo__input { max-width: 440px; }
/* i dati che il membro ricopia a mano — indirizzo, importo — in monospace:
   le lettere cifre non si confondono e si può contare il numero di caratteri */
.campo--dati .campo__input { font-family: var(--mono); letter-spacing: .02em; }
.campo--dati input.campo--dati { font-family: var(--mono); letter-spacing: .02em; }
.campo__aiuto { display: block; font-size: 13px; color: var(--testo-tenue); margin-top: 8px; }

/* ---------------------------------------------------------------- timbro */

.timbro {
  position: relative;
  display: inline-flex; flex-direction: column; align-items: center; gap: 3px;
  font-family: var(--mono); font-weight: 700;
  font-size: 12px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--giallo);
  border: 2px solid var(--giallo);
  border-radius: 10px;
  padding: 9px 15px 8px;
  transform: rotate(-4deg);
  box-shadow: 0 0 26px rgba(255,222,5,.55), 0 0 0 5px rgba(255,222,5,.10);
  animation: timbro-cala .6s cubic-bezier(.16,1,.3,1) both;
}
.timbro__chi {
  /* Era 10 px. Sotto i 12 px la riga non e' piu' leggibile con il contrasto
     che ha, e su uno schermo di telefono non e' piu' leggibile davvero. */
  font-size: 12px; letter-spacing: .1em; opacity: .85;
}
.timbro__lucchetto { width: 16px; height: 16px; flex: none; }
.timbro__testo { display: flex; flex-direction: column; align-items: center; gap: 1px; }

/* il timbro a scala: sulla scheda l'atto e' l'informazione principale, quindi
   prende la grandezza del titolo invece di restare un badge fra gli altri */
.timbro--cala {
  align-items: flex-start; gap: 6px;
  font-size: 15px; letter-spacing: .2em; padding: 16px 22px 15px;
  transform: rotate(-2deg);
  box-shadow: 0 0 44px rgba(255,222,5,.5), 0 0 0 6px rgba(255,222,5,.09);
}
.timbro--cala .timbro__chi {
  font-size: 12.5px; letter-spacing: .12em; color: var(--testo-muto);
}

/* Il timbro fermo: e' quello che appare in elenco, dove non c'e' spazio per
   un badge storto e la cosa da dire e' una sola. Con il lucchetto dentro,
   perche' «controfirmata» vuol dire che la voce non si tocca piu'. */
.timbro--ferma {
  transform: none; animation: none;
  display: inline-flex; flex-direction: row; align-items: center; gap: 7px;
  padding: 7px 14px 6px; font-size: 12px; letter-spacing: .14em;
  box-shadow: 0 0 18px rgba(255,222,5,.35), 0 0 0 4px rgba(255,222,5,.08);
}

/* l'atto: l'impronta scende e la luce si propaga */
@keyframes timbro-cala {
  from { transform: rotate(-16deg) scale(1.7); opacity: 0; filter: blur(9px); }
  55%  { opacity: 1; filter: blur(0); }
}

/* l'onda che parte dall'impronta: un solo cerchio che si dilata e muore.
   Niente scie multiple: il gesto deve restare un atto, non uno spettacolo. */
.onda {
  position: absolute; left: 50%; top: 50%;
  width: 140px; height: 140px; margin: -70px 0 0 -70px;
  border: 2px solid var(--giallo); border-radius: 50%;
  box-shadow: 0 0 30px rgba(255,222,5,.5), inset 0 0 30px rgba(255,222,5,.3);
  pointer-events: none;
  animation: onda 1.05s cubic-bezier(.16,1,.3,1) forwards;
}
@keyframes onda {
  0%   { transform: scale(.30); opacity: 1;   border-width: 4px; }
  70%  { opacity: .6; }
  100% { transform: scale(5);   opacity: 0;   border-width: 1px; }
}

.timbro--in-attesa {
  color: var(--ciano); border-color: rgba(21,169,233,.7); border-style: dashed;
  box-shadow: 0 0 22px rgba(21,169,233,.38), 0 0 0 5px rgba(21,169,233,.08);
  transform: rotate(-2deg);
  animation: respiro-attesa 3.2s ease-in-out infinite;
}
@keyframes respiro-attesa {
  0%, 100% { box-shadow: 0 0 18px rgba(21,169,233,.30), 0 0 0 5px rgba(21,169,233,.06); }
  50%      { box-shadow: 0 0 40px rgba(21,169,233,.60), 0 0 0 6px rgba(21,169,233,.14); }
}

.sigillo-oro {
  width: 62px; height: 62px; flex: none;
  color: var(--giallo);
  filter: drop-shadow(0 0 18px rgba(255,222,5,.7));
  animation: sigillo-cala .6s cubic-bezier(.16,1,.3,1) both;
}
@keyframes sigillo-cala {
  from { transform: rotate(-26deg) scale(1.5); opacity: 0; }
}

/* ------------------------------------------------------------- le voci */

.voci { display: grid; gap: 16px; margin-top: 22px; }

.voice {
  position: relative;
  display: grid; grid-template-columns: 1fr auto; gap: 18px;
  padding: 18px;
  border-radius: var(--r-passo);
  background: linear-gradient(140deg, rgba(255,255,255,.07), rgba(255,255,255,.02));
  border: 1px solid rgba(120,170,255,.16);
  box-shadow: var(--d1);
  transform-style: preserve-3d;
  transition: transform .3s cubic-bezier(.16,1,.3,1), box-shadow .3s, border-color .3s;
}
.voice:hover {
  transform: translateY(-5px);
  border-color: rgba(21,169,233,.5);
  box-shadow: var(--d2), 0 0 34px rgba(21,169,233,.28);
}
.voice--vuota { display: block; text-align: center; padding: 34px; }

.voice__dato {
  font-family: var(--mono); font-size: 14px; color: var(--ciano);
  word-break: break-all; text-shadow: 0 0 16px rgba(21,169,233,.45);
}
.voice__nota { color: var(--testo-muto); margin-top: 6px; }
.voice__azioni { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }

/* La scheda dell'amministratore: etichetta e valore affiancati.
   Senza l'etichetta una riga di numeri non dice niente: «500» puo' essere un
   importo, una quantita' o un numero a caso. */
.scheda_dati {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(140px, 200px) 1fr;
  gap: 10px 18px;
  align-items: baseline;
}
.scheda_dati dt {
  font-family: var(--mono); font-size: 12px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--testo-muto);
}
.scheda_dati dd {
  margin: 0; color: var(--testo); word-break: break-word;
}
.scheda_dati dd.monospazio { font-family: var(--mono); color: var(--ciano); }
@media (max-width: 720px) {
  .scheda_dati { grid-template-columns: 1fr; gap: 4px; }
  .scheda_dati dt { margin-top: 10px; }
}

/* la prova a scala registrata: cornice fissa, mai deformata */
.prova {
  height: 220px; margin: 0;
  border-radius: var(--r-passo);
  border: 1px solid rgba(120,170,255,.28);
  background:
    repeating-linear-gradient(45deg, rgba(21,169,233,.05) 0 10px, transparent 10px 20px),
    rgba(0,8,32,.5);
  box-shadow: var(--d1) inset;
  overflow: hidden;
  display: grid; place-items: center;
}
.prova img { width: 100%; height: 100%; object-fit: contain; display: block; }
.prova--vuota { color: var(--testo-tenue); font-size: 14px; }

/* ------------------------------------------------------------ la coda */

.conta {
  display: flex; align-items: baseline; gap: 14px;
  margin-top: 20px; padding-bottom: 14px;
  border-bottom: 1px solid rgba(120,170,255,.2);
}
.conta__numero {
  font-family: var(--mono); font-size: 46px; font-weight: 700; line-height: 1;
  color: var(--giallo);
  text-shadow: 0 0 34px rgba(255,222,5,.6);
}
.conta__etichetta {
  font-size: 13px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--testo-muto);
}
.filetto { margin-top: 14px; font-size: 13.5px; color: var(--testo-muto); }
.filetto .monospazio { color: var(--ciano); font-size: 15px; }

/* ------------------------------------------------------------ la tabella */

.tabella { width: 100%; border-collapse: collapse; margin-top: 20px; font-size: 14.5px; }
/* Il binario della tabella. Su tablet la tabella e' piu' larga del pannello
   (764 px dentro 700) e la colonna delle azioni finiva fuori; il corpo ha
   `overflow-x: hidden`, quindi non compariva una barra ma il pulsante «Apri
   la scheda» spariva. La tabella non puo' scorrere se stessa — per farlo dovrebbe
   smettere di essere una tabella — quindi il contenitore le gira attorno e
   scorre lui. Il corpo della pagina resta fermo. */
.tabella__corsia { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tabella th {
  /* Era 11 px: le intestazioni erano il testo piu' piccolo della pagina. */
  text-align: start; font-size: 12px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--ciano); padding: 10px 12px;
  border-bottom: 1px solid rgba(120,170,255,.24);
  white-space: nowrap;
}
.tabella td { padding: 14px 12px; border-bottom: 1px solid rgba(120,170,255,.10); vertical-align: middle; }
/* la riga viva: la luce insegue il puntatore e gli elementi che possono
   ruotare davvero si inclinano. Il fondo va su `tr` e non su un pseudo
   elemento perche' `transform` su `tr` e su `td` non e' applicabile in un
   layout tabulare: la profondita' la si da ai figli, che sono normali
   elementi di flusso. */
.tabella tbody tr {
  background-image:
    radial-gradient(340px circle at var(--luce-x, 50%) var(--luce-y, 50%),
      rgba(21,169,233,.20), transparent 68%);
  background-repeat: no-repeat;
  transition: background-color .22s;
}
.tabella tbody tr:hover { background-color: rgba(21,169,233,.06); }
.membro { font-weight: 600; color: #fff; }
.membro__id {
  font-family: var(--mono); font-size: 12px; color: var(--testo-tenue);
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
}

/* il contatto: il nome Telegram sul portale è un indirizzo che si apre e un
   testo che si copia. Senza il pulsante l'amministratore deve selezionare a
   mano una decina di caratteri a video, e lo fa una volta e poi basta. */
.contatto { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.telegram {
  display: inline-flex; align-items: center; min-height: 44px;
  font-family: var(--mono); font-size: 13px; color: var(--ciano);
  text-decoration: none; border-bottom: 1px solid rgba(21,169,233,.32);
}
.telegram:hover { color: #fff; border-bottom-color: var(--ciano); }
.copia {
  font-family: var(--sans); font-size: 12px; letter-spacing: .04em; font-weight: 600;
  min-height: 44px; padding: 10px 16px; cursor: pointer; color: var(--testo-muto);
  background: rgba(255,255,255,.05); border: 1px solid rgba(120,170,255,.24);
  border-radius: 999px;
  transition: color .18s, border-color .18s, background-color .18s;
}
.copia:hover { color: #fff; border-color: var(--ciano); background: rgba(21,169,233,.16); }
.copia--fatto {
  color: var(--verde); border-color: rgba(73,219,108,.55); background: rgba(73,219,108,.12);
}
.membro__id .copia { margin-inline-start: 6px; }
/* ciò che si inclina davvero dentro la riga: il nome e la prova.
   La prospettiva sta nella funzione `perspective()` dentro transform e non
   in un antenato: `td` e `tr` sono celle tabulari, su di esse la
   prospettiva non si applica e `transform` non gira. */
.tabella tbody tr .membro,
.tabella tbody tr .cella-prova .prova {
  transform: perspective(760px) rotateY(var(--rot, 0deg)) translateZ(var(--salto, 0px));
  transition: transform .3s cubic-bezier(.16,1,.3,1);
  transform-origin: left center;
}
.tabella tbody tr .cella-prova .prova { transform-origin: center; }
/* `.azioni` resta una cella: `display:flex` su un <td> lo promuove fuori dal
   calcolo delle colonne e la colonna si sfilaccia. Allineamento via text-align. */
.azioni { text-align: end; white-space: nowrap; }
.azioni > * + * { margin-inline-start: 8px; }

.registro_voci { list-style: none; margin: 18px 0 0; padding: 0; }
.registro_voci li {
  display: flex; gap: 12px; flex-wrap: wrap; align-items: baseline;
  padding: 11px 0; border-bottom: 1px solid rgba(120,170,255,.10);
  font-size: 14px;
}
.registro_voci__atto { font-weight: 700; color: var(--ciano); }
.registro_voci__dettaglio { color: var(--testo-muto); }
.registro_voci .quando { font-family: var(--mono); font-size: 12px; color: var(--testo-tenue); margin-left: auto; }

/* -------------------------------------------------------------- filtri */

.filtri { display: flex; gap: 9px; flex-wrap: wrap; align-items: center; margin-top: 18px; }
.filtro {
  font-size: 14px; font-weight: 600; text-decoration: none;
  color: var(--testo-muto);
  border: 1px solid rgba(120,170,255,.20);
  border-radius: 999px; padding: 11px 18px;
  display: inline-flex; align-items: center; min-height: 44px;
  transition: color .2s, border-color .2s, background .2s, box-shadow .2s;
}
.filtro:hover { color: #fff; border-color: var(--ciano); box-shadow: 0 0 20px rgba(21,169,233,.4); }
.filtro[aria-current="true"] {
  /* Qui il gradiente ciano-blu era un problema, non una decorazione: con un
     testo solo, il contrasto cambia da un capo all'altro del pulsante.
     Testo scuro sul blu: 2,19:1. Testo bianco sul ciano: 2,66:1. Entrambi
     sotto la soglia, e in entrambi i casi la parola sparisce verso una meta'
     del bottone.
     La correzione non e' scegliere il colore giusto — sul gradiente non ne
     c'e' uno giusto — ma togliere il gradiente: un campo uniforme ha un solo
     contrasto, ed e' quello che si misura. Il colore conserva il suo senso
     (il ciano del portale) e il filtro attivo resta riconoscibile per lo
     spessore del bordo e per il peso del carattere, non per un colore che
     si muove. */
  color: #000714; background: #15A9E9;
  border-color: #7FDBFF; font-weight: 700;
  box-shadow: 0 0 26px rgba(21,169,233,.5);
}

/* la riga di ricerca sta su una riga sola: `width:100%` sul campo, ereditato dal
   blocco campi, da solo basta a cacciare il bottone nella riga successiva */
.filtri--ricerca { flex-wrap: nowrap; }
.filtri--ricerca .campo--filtro {
  flex: 0 0 auto; width: 220px; max-width: 220px; margin-top: 0;
}
.filtri--ricerca .campo__input {
  flex: 1 1 140px; width: auto; min-width: 0; margin-top: 0;
}
.filtri--ricerca .bottone { flex: none; padding: 14px 20px; }

/* --------------------------------------------------------------- avvisi */

.avviso {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 15px 17px; margin-top: 20px;
  border-radius: var(--r-passo);
  background: rgba(21,169,233,.10);
  border: 1px solid rgba(21,169,233,.32);
  color: var(--testo);
  font-size: 14.5px;
}
.avviso svg { width: 20px; height: 20px; flex: none; color: var(--ciano); margin-top: 2px; }
.avviso--rosso {
  background: rgba(255,114,0,.12); border-color: rgba(255,114,0,.42);
}
.avviso--rosso svg { color: var(--arancio); }
/* errore e nota devono dirsi diversi: senza queste, un deposito respinto e
   una dichiarazione già vista uscivano entrambi con lo stesso riquadro ciano */
.avviso--errore {
  background: rgba(255,60,60,.10); border-color: rgba(255,114,0,.55);
  color: #FFD9C2;
}
.avviso--errore svg { color: var(--arancio); }
.avviso--nota {
  background: rgba(73,219,108,.10); border-color: rgba(73,219,108,.42);
  color: #D8FFE4;
}
.avviso--nota svg { color: var(--verde); }

/* ------------------------------------------------------------------ piee */

.piee {
  max-width: var(--respiro); margin: 40px auto 0;
  padding-inline: 4px;
  display: flex; justify-content: space-between; gap: 10px 24px; flex-wrap: wrap;
  font-size: 13px; line-height: 1.55; color: var(--testo-tenue);
}
.piee .monospazio { color: rgba(120,180,255,.55); }

/* ----------------------------------------------------------- l'ingresso */

.ingresso {
  min-height: calc(100dvh - 120px);
  display: grid; place-items: center;
  perspective: 1400px;
}

.ingresso__scena {
  display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(28px, 4vw, 56px);
  align-items: center;
  transform-style: preserve-3d;
}
.ingresso__scena > * { transform: translateZ(46px); }

/* la larghezza e' in px e non in `ch`: `ch` si calcola sul font di questo
   elemento (17px) e non su quello del titolo, quindi 22ch davano una
   colonna di 176px sotto un titolo da 62px */
.ingresso__testo { max-width: 640px; }
.ingresso__occhiello {
  font-family: var(--mono); font-size: 12.5px; letter-spacing: .3em;
  text-transform: uppercase; color: var(--verde);
  text-shadow: 0 0 20px rgba(73,219,108,.6);
  margin-bottom: 20px; white-space: nowrap;
}
.ingresso__big {
  font-family: var(--serif); font-weight: 700;
  font-size: clamp(34px, 4.9vw, 62px); line-height: 1.03;
  margin: 0;
  /* niente viola nel gradiente del titolo: e' il tono piu' scuro della palette
     e sul vetro scuro scendeva a 3.8:1. Il lilla tiene lo stesso movimento e
     la stessa lettura di colore, con 6.5:1 misurati sui pixel. */
  background: linear-gradient(100deg, #FFFFFF 4%, var(--ciano) 36%, var(--lilla) 66%, var(--giallo) 97%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  background-size: 240% 100%;
  animation: testo-scorrimento 11s ease-in-out infinite;
  filter: drop-shadow(0 6px 40px rgba(21,169,233,.30));
}
/* la seconda riga e' la risposta: piu' piccola e di un altro timbro, cosi'
   l'occhio va alla promessa e poi alla sua conclusione */
.ingresso__big--2 {
  font-size: clamp(17px, 1.85vw, 25px);
  line-height: 1.34; font-weight: 600;
  margin-top: 20px; max-width: 30ch;
  background: linear-gradient(100deg, var(--ciano), var(--lilla));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  animation-duration: 15s;
}

/* la pila di vetro: tre pannelli in prospettiva, piccola e in un angolo */
.pila {
  position: absolute; width: 300px; height: 190px;
  left: -40px; bottom: -190px;
  perspective: 1000px; transform-style: preserve-3d;
  pointer-events: none;
}
.pila__foglio {
  position: absolute; inset: 0;
  border-radius: 20px;
  border: 1px solid rgba(120,170,255,.24);
  background: linear-gradient(150deg, rgba(255,255,255,.09), rgba(255,255,255,.015));
  box-shadow: var(--d2);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  transform-style: preserve-3d;
  animation: pila-volo 11s ease-in-out infinite;
}
.pila__foglio:nth-child(1) { transform: translate3d(0,0,80px) rotateY(-13deg) rotateX(7deg); }
.pila__foglio:nth-child(2) { transform: translate3d(22px,22px,34px) rotateY(-7deg) rotateX(4deg); opacity: .55; animation-delay: -3.5s; }
.pila__foglio:nth-child(3) { transform: translate3d(44px,44px,-12px) rotateY(-1deg) rotateX(1deg); opacity: .28; animation-delay: -7s; }

.pila__luce {
  position: absolute; inset: -30% -10% auto auto; width: 210px; height: 210px;
  border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(21,169,233,.5), transparent 66%);
  filter: blur(28px);
  animation: pulse-luce 7s ease-in-out infinite;
}
@keyframes pila-volo {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -14px; }
}

@keyframes pulse-luce {
  0%, 100% { opacity: .55; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.22); }
}

/* le tre cose che il portale promette davvero: la promessa deve essere
   verificabile dalla pagina, non solo suggestiva */
.promemoria {
  list-style: none; margin: 34px 0 0; padding: 0;
  display: grid; gap: 14px;
}
.promemoria__voce {
  display: flex; align-items: center; gap: 13px;
  font-size: 15.5px; color: var(--testo);
  padding: 11px 15px;
  border-radius: 12px;
  background: rgba(255,255,255,.035);
  border: 1px solid rgba(120,170,255,.15);
  transition: transform .25s cubic-bezier(.16,1,.3,1), border-color .25s, background .25s;
}
.promemoria__voce:hover {
  transform: translateX(8px);
  border-color: rgba(21,169,233,.5);
  background: rgba(21,169,233,.10);
}
.promemoria__segnale {
  width: 9px; height: 9px; flex: none; border-radius: 50%;
  animation: battito 2.6s ease-in-out infinite;
}
.promemoria__segnale--ciano  { background: var(--ciano);  box-shadow: 0 0 16px var(--ciano); }
.promemoria__segnale--verde  { background: var(--verde);  box-shadow: 0 0 16px var(--verde); animation-delay: .5s; }
.promemoria__segnale--giallo { background: var(--giallo); box-shadow: 0 0 16px var(--giallo); animation-delay: 1s; }

@keyframes battito {
  0%, 100% { transform: scale(1);   opacity: 1; }
  50%      { transform: scale(1.5); opacity: .6; }
}

/* il pannello di accesso */
.accesso { width: 100%; max-width: 460px; justify-self: end; }
.accesso .titolo--2 { margin-bottom: 4px; }

/* ------------------------------------------------------------- rivelazione */

.rivela { opacity: 0; transform: translateY(26px); transition: opacity .7s, transform .7s; }
.rivela.visibile { opacity: 1; transform: none; }

/* le parti di voce che il nuovo mondo non aveva ancora vestite */
.voice__testata {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-bottom: 12px;
}
.voice__seriale {
  font-family: var(--mono); font-size: 12.5px; letter-spacing: .04em;
  color: var(--ciano); text-shadow: 0 0 14px rgba(21,169,233,.5);
}
.voice__cat {
  /* Era 11,5 px: sotto i 12 px l'etichetta della categoria non si legge con
     il contrasto che ha e non si legge nemmeno a occhio. */
  font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--testo-tenue);
  border: 1px solid rgba(120,170,255,.24); border-radius: 999px;
  padding: 3px 10px;
}
/* la prova in tabella è un francobollo, non l'anteprima a scala della pagina
   voce: dimensione fissa e cornice propria, altrimenti eredita i 220px di `.prova` */
.cella-prova { width: 150px; }
.cella-prova .prova { height: 78px; border-radius: 10px; }
.cella-prova .prova--vuota { height: 78px; }

.campo__area {
  min-height: 120px; resize: vertical;
  font-family: var(--sans); font-size: 16px;
}

/* T5 · I campi della stessa larghezza.

   I `<select>` avevano `max-width: 260px` e gli `<input>` no: sulla stessa
   colonna il bordo destro dei due non arrivava mai allo stesso punto, e il
   modulo sembrava due moduli sovrapposti. Il limite di 260 px esisteva per i
   FILTRI dell'area amministratore, che devono stare su una riga con il campo
   di ricerca: li si stringe nel loro contesto (`.campo--filtro`), non
  Ovunque. */
.campo__seleziona { max-width: none; }
.campo--filtro { max-width: 260px; }

/* La casella di spunta della tabella: il bersaglio e' la cella, non il
   quadratino. Il quadratino resta comodo ma non si schiaccia contro il
   vicino: il clic utile e' su tutta la cella. */
.cella-scelta { width: 48px; text-align: center; }
.cella-scelta input[type="checkbox"] {
  width: 22px; height: 22px; accent-color: var(--giallo); cursor: pointer;
}

/* ------------------------------------------------------- T4 · le schede */

.schede {
  list-style: none; margin: 18px 0 0; padding: 0;
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
}
.scheda {
  display: flex; flex-direction: column; gap: 9px;
  padding: 16px 18px;
  border-radius: var(--r-passo);
  border: 1px solid rgba(120,170,255,.18);
  background: linear-gradient(150deg, rgba(255,255,255,.06), rgba(255,255,255,.015));
  box-shadow: var(--d1);
}
.scheda--vuota { border-style: dashed; border-color: rgba(120,170,255,.30); }
/* Una scheda con roba dentro e' piena e lo si vede dal bordo, non da una
   dicitura: la piena ha il bordo acceso. Senza questa regola le due schede si
   distinguevano solo per il tratteggio del vuoto. */
.scheda--piena { border-color: rgba(120,170,255,.30); }
/* Il nome della categoria e la sua pastiglia stanno sulla stessa riga e non
   devono separarsi quando il nome va a capo. */
.scheda__stato { display: inline-flex; align-items: center; flex: none; }
.scheda__capo { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.scheda__nome { font-weight: 600; font-size: 15px; color: var(--testo); }
.scheda__conto {
  font-family: var(--mono); font-size: 13px; color: var(--testo-muto);
}
/* La pastiglia e' lo stato della CATEGORIA, non della pagina: dice se in
   questa categoria c'e' roba da controfirmare. */
.pastiglia {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 700; letter-spacing: .06em;
  padding: 4px 10px; border-radius: 999px; white-space: nowrap;
}
.pastiglia svg { width: 13px; height: 13px; }
.pastiglia--vuota {
  color: var(--testo-tenue); border: 1px solid rgba(120,170,255,.22);
}
.pastiglia--attesa {
  color: var(--ciano); border: 1px solid rgba(21,169,233,.5);
  background: rgba(21,169,233,.12);
}
.pastiglia--firmata {
  color: var(--giallo); border: 1px solid rgba(255,222,5,.5);
  background: rgba(255,222,5,.10);
}
/* Il vuoto non e' una colpa: la via per depositare sta lì, e deve sembrare
   un'azione e non un avviso. */
.scheda__via {
  display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
  min-height: 44px; padding: 10px 16px;
  border-radius: 999px; font-size: 14px; font-weight: 600;
  color: var(--ciano); text-decoration: none;
  border: 1px solid rgba(21,169,233,.4); background: rgba(21,169,233,.10);
}
.scheda__via svg { width: 15px; height: 15px; }
.scheda__via:hover { color: #fff; background: rgba(21,169,233,.22); }

/* -------------------------------------------------- T5 · il modulo a due livelli */

.modulo { display: block; }
.livello { margin-top: 26px; }
.livello > .titolo--3 { margin-bottom: 4px; }

/* Il `<details>` e' il meccanismo: si apre e si chiude senza JavaScript.
   Il marcatore di default del browser e' una freccia grigia che non
   appartiene a questo mondo, quindi la si sostituisce con un segno che sa
   cosa stiamo per fare: aprire o chiudere. */
.livello--dettagli {
  margin-top: 22px;
  border: 1px solid rgba(120,170,255,.18);
  border-radius: var(--r-passo);
  background: rgba(255,255,255,.025);
}
.livello__sommario {
  display: flex; flex-direction: column; gap: 3px;
  padding: 15px 18px; cursor: pointer; list-style: none;
  min-height: 44px;
}
.livello__sommario::-webkit-details-marker { display: none; }
.livello__sommario::after {
  content: "+"; position: absolute; right: 20px; top: 50%;
  transform: translateY(-50%);
  font-family: var(--mono); font-size: 20px; color: var(--ciano);
}
.livello--dettagli { position: relative; }
.livello--dettagli[open] > .livello__sommario::after { content: "−"; }
.livello__sommario:hover { background: rgba(21,169,233,.08); }
.livello__titolo { font-weight: 700; font-size: 15px; color: var(--testo); }
.livello__aiuto { font-size: 13px; color: var(--testo-tenue); }
.livello--dettagli[open] > .livello__sommario { border-bottom: 1px solid rgba(120,170,255,.16); }

/* La barra d'invio: su un telefono il bottone era a meta' schermo e il
   membro scorreva tutto il modulo per arrivarci. `sticky` la tiene in fondo
   finche' il modulo scorre. */
.modulo__barra {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; gap: 12px; flex-wrap: wrap;
  padding: 14px 0 4px;
  background: linear-gradient(180deg, rgba(2,10,28,0), rgba(2,10,28,.92) 34%);
}

/* L'anteprima: il membro deve vedere l'immagine che sta depositando. Sta
   dentro il riquadro di rilascio, accanto al nome del file. */
.deposito__testo { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.deposito__stato {
  font-size: 13px; color: var(--testo-tenue); line-height: 1.4;
}
.deposito__stato--errore { color: #FFC9A8; }
.deposito__stato--fatto { color: #B9F3C9; }
.deposito__anteprima {
  width: 76px; height: 76px; flex: none;
  object-fit: cover; border-radius: 10px;
  border: 1px solid rgba(120,170,255,.3);
  background: rgba(0,8,32,.5);
}

/* L'avviso d'errore prende il fuoco: ha una cornice per rendersi visibile
   anche quando riceve il fuoco. */
.avviso:focus { outline: 2px solid var(--giallo); outline-offset: 3px; }
.avviso__capo { display: block; margin-bottom: 3px; color: #fff; }
.avviso__testo { display: block; }
/* Le coincidenze non sono un errore e non sono un pericolo: sono un dato.
   Per questo stanno in AMBRA e non in rosso — un rosso qui sembrerebbe
   un'accusa a qualcuno che magari ha indicato lo stesso indirizzo per
   davvero. */
.avviso--coincidenza {
  background: rgba(255,179,5,.10); border-color: rgba(255,179,5,.42);
}
.avviso--coincidenza svg { color: var(--ambra); }

/* ------------------------------------------------------ T6 · la scheda a due lati */

/* Prova e dati affiancati: sono la stessa operazione mentale (guardare e
   confrontare) e prima erano due sezioni una sotto l'altra, da mettere in
   relazione scorrendo avanti e indietro. */
.doppio {
  display: grid; gap: clamp(20px, 3vw, 34px);
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  align-items: start;
  margin-top: 26px;
}
.doppio__lato { min-width: 0; }
.doppio__lato > .titolo--3 { margin-bottom: 12px; }
.prova--grande { height: 380px; }

/* Le due vicine: due collegamenti veri, quindi utilizzabili anche senza
   JavaScript; i tasti freccia sono la scorciatoia sopra, non il modo. */
.vicine {
  display: flex; gap: 10px; flex-wrap: wrap; margin-top: 20px;
}
.vicine__link {
  display: inline-flex; align-items: center; gap: 10px;
  min-height: 44px; padding: 10px 16px;
  border-radius: 999px; text-decoration: none;
  border: 1px solid rgba(120,170,255,.22);
  background: rgba(255,255,255,.04);
}
.vicine__link:hover { border-color: var(--ciano); background: rgba(21,169,233,.14); }
.vicine__link svg { width: 16px; height: 16px; flex: none; color: var(--ciano); }
.vicine__link--avanti { margin-left: auto; }
.vicine__etichetta { display: block; font-size: 12px; color: var(--testo-tenue); }
.vicine__seriale { display: block; font-family: var(--mono); font-size: 13px; color: var(--testo); }

/* La barra della controfirma in blocco: compare solo quando c'e' qualcosa di
   spuntato e dice quante sono. */
.azioni-blocco { display: flex; align-items: center; justify-content: flex-end; gap: 14px; }
.azioni-blocco__stato {
  font-family: var(--mono); font-size: 13px; color: var(--testo-muto);
}

/* l'area di deposito dello screenshot: senza `svg` e `input` dimensionati qui
   fuori, il glifo ereditava il 300×150 di default degli elementi sostituiti e
   il riquadro si spalava per metà pagina. Classe propria: `.deposito` da solo è
   anche il contenitore del widget Telegram in pagina di accesso. */
.deposito--file {
  display: flex; align-items: center; gap: 14px;
  padding: 20px 22px; cursor: pointer;
  border: 1px dashed rgba(21,169,233,.42);
  border-radius: var(--r-passo);
  background:
    repeating-linear-gradient(45deg, rgba(21,169,233,.045) 0 12px, transparent 12px 24px),
    rgba(0,8,32,.5);
  transition: border-color .22s, background .25s, box-shadow .25s, transform .22s;
}
.deposito--file:hover, .deposito--file:focus-within {
  border-color: var(--ciano);
  background:
    repeating-linear-gradient(45deg, rgba(21,169,233,.08) 0 12px, transparent 12px 24px),
    rgba(21,169,233,.10);
  box-shadow: 0 0 34px rgba(21,169,233,.34);
  transform: translateY(-2px);
}
/* file scelto: il bordo tratteggiato diventa pieno, come un campo riempito */
.deposito--file[caricato] { border-style: solid; border-color: var(--verde); }
.deposito--file[caricato] svg { color: var(--verde); }
.deposito--file svg {
  width: 34px; height: 34px; flex: none;
  color: var(--ciano);
  filter: drop-shadow(0 0 10px rgba(21,169,233,.55));
  transition: transform .25s cubic-bezier(.16,1,.3,1), color .25s;
}
.deposito--file:hover svg { transform: scale(1.12) rotate(-4deg); }
/* l'input resta focalizzabile per la tastiera, ma non si disegna */
.deposito--file input[type="file"] {
  position: absolute; width: 1px; height: 1px;
  opacity: 0; pointer-events: none;
}

.deposito__nome {
  font-family: var(--mono); font-size: 12px;
  color: var(--testo-tenue); word-break: break-all;
}
/* il widget Telegram: lo script inserisce un iframe al posto di se stesso. Lo
   si centra e gli si lascia un'altezza minima, cosi' la pagina non salta quando
   il pulsante compare. */
.telegram-accesso { display: flex; justify-content: center; align-items: center; min-height: 52px; }

/* il fieldset del modulo non deve portarsi il bordo e i margini del browser */
.campi { border: 0; margin: 0; padding: 0; min-width: 0; }
.campi[disabled] { opacity: .62; }
/* una voce controfirmata non ha azioni: dice il perche' */
.voice__bloccata {
  display: flex; align-items: center; gap: 10px;
  margin-top: 14px; font-size: 14px; color: var(--testo-muto);
}
.voice__bloccata svg { width: 20px; height: 20px; flex: none; color: var(--giallo); }
.errore { text-align: center; padding: 30px 0; }
.errore__codice { font-family: var(--mono); color: var(--testo-tenue); margin-top: 14px; }
.mono { font-family: var(--mono); }

/* ------------------------------------------------------------ responsive */

/* T2 · La modalita' calma.

   Il mondo animato e' una scelta, non un diritto. Nelle pagine dove si
   lavora — registro, deposito, amministrazione, scheda — la rete di nodi
   girava per ore e i sei cubi in 3D pure, insieme alla luce sulle righe e al
   paralasse della testata. Il risultato era una pagina che scalda e consuma
   la batteria del telefono di chi ci passa le giornate.

   `calma` sul corpo spegne i movimenti CONTINUI: rete assente, cubi fermi,
   griglia ferma, nebbia ferma. Non spegne i gesti — la controfirma e' un
   atto e deve muoversi — e non tocca `prefers-reduced-motion`, che resta la
   sua strada e piu' forte di questa.

   La classe la mette il template per pagina (`{% block classe_corpo %}`) e il
   JavaScript la accende anche da solo quando il dispositivo chiede risparmio
   (`saveData`, memoria e core bassi). */
body.calma .abisso__nebbia { animation: none; }
body.calma .abisso__griglia { animation: none; }
body.calma .cubi { display: none; }
body.calma .promemoria__segnale { animation: none; }
body.calma .timbro--in-attesa { animation: none; }
body.calma .rivela { opacity: 1; transform: none; transition: none; }
body.calma .marchio__logo { animation: none; }
/* Il titolo che sfuma il gradiente e' una luce che cammina: 9 secondi di
   `infinite` vuol dire che non si ferma MAI, nemmeno quando la pagina e' in
   calma. Il testo resta perfettamente leggibile (il fermo e' sul colore, non
   sul contrasto dichiarato: `background-position` al 50%), quindi qui si
   ferma la luce e si lascia il gradiente al suo posto. */
body.calma .titolo--intro { animation: none; background-position: 50% 50%; }
/* La rivelazione allo scroll, in calma, non nasconde nulla: ogni elemento
   e' visibile subito, anche quelli che non entrano mai nel viewport. */
body.calma .rivela:not(.visibile) { opacity: 1; transform: none; }

/* La pagina d'accesso e' l'unica che tiene la scena: e' il biglietto da
   visita, e la si guarda per tre secondi. */
body.scena .rivela { opacity: 1; transform: none; transition: none; }

@media (max-width: 980px) {
  .ingresso__scena { grid-template-columns: 1fr; }
  /* Qui dentro la profondita' spostava il blocco verso il lettore e basta:
     `translateZ(46px)` con `perspective: 1400px` lo ingrandisce del 3,4%, e
     una scena larga 371 finiva per 384 su una finestra di 375 — otto pixel
     di scorrimento laterale su un telefono, per un effetto che a una
     colonna non si vede. Sotto i 980 px il testo torna in piano. */
  .ingresso__scena > * { transform: none; }
  .accesso { justify-self: stretch; max-width: none; }
  .pila { height: 230px; order: -1; }
  .doppio { grid-template-columns: 1fr; }
  /* su schermo stretto la prova passa per prima: e' quella che si guarda
     per decidere, quindi non si deve doverla scorrere fino in fondo */
  .doppio__lato:first-child { order: -1; }
}

/* La tabella diventa un elenco a schede sotto i 960 px, non sotto i 720.
   Verifica del 15/10: a 768 px (un tablet in piedi) la tabella a sette colonne
   scorreva dentro il pannello e il pulsante «Apri la scheda» restava mezzo
   fuori bordo, con numeri di serie e stati spezzati su tre righe. Una scheda per
   riga si legge in due secondi anche li'; la corsia di scorrimento resta come
   rete di sicurezza per chi la forzi. */
@media (max-width: 960px) {
  .tabella thead { display: none; }
  .tabella tr { display: grid; gap: 6px 24px; padding: 16px 0; border-bottom: 1px solid rgba(120,170,255,.14); position: relative; }
  /* la casella di selezione non occupa una riga tutta sua: sta nell'angolo della scheda */
  .tabella .cella-scelta { position: absolute; top: 4px; right: 0; width: auto; padding: 0; }
  .tabella td {
    display: flex; flex-direction: column; align-items: flex-start;
    gap: 3px; padding: 3px 0; border: 0;
  }
  .tabella td::before {
    content: attr(data-etichetta);
    font-size: 12px; letter-spacing: .16em; text-transform: uppercase;
    color: var(--ciano); font-weight: 700;
  }
  .tabella td[data-etichetta=""]::before { content: none; }
  .tabella .azioni { text-align: start; padding-top: 8px; white-space: normal; }
  .tabella .azioni::before { content: none; }

  /* la prova resta un francobollo: senza larghezza fissa la cella, unica
     figlia della griglia della riga, si dilaterebbe per tutta la colonna */
  .cella-prova { width: 132px; }
  .cella-prova .prova { width: 132px; }
}

/* fra 721 e 960 px la scheda ha spazio per due colonne: la meta' di altezza */
@media (min-width: 721px) and (max-width: 960px) {
  .tabella tr { grid-template-columns: 1fr 1fr; padding-right: 44px; }
}

@media (max-width: 720px) {
  body { font-size: 16px; }
  .foglio { padding: 22px 18px; border-radius: var(--r-passo); }
  .voice { grid-template-columns: 1fr; }
  .voice .prova { order: -1; height: 170px; }
  .conta__numero { font-size: 38px; }

  /* T3 · la testata a una riga anche qui. I nomi dei comandi spariscono e
     restano le icone, che hanno gia' un `aria-label` nel template: il nome
     accessibile c'e' anche quando la parola non c'e'. */
  .barra { gap: 8px; padding-bottom: 12px; min-height: 52px; }
  .barra__voci { gap: 4px; margin-left: auto; }
  .lezione__nome, .marchio__nome { display: none; }
  /* `min-height` qui esplicito, anche se la regola generale lo dichiara gia':
     sotto schermo stretto il padding si stringe e il comando si appiattisce
     senza volerlo. Dichiararlo qui rende la misura non dipendente
     dall'ereditaggio, che e' la parte fragile. */
  .lezione { padding: 10px; gap: 0; min-height: 44px; }
  .lezione svg { width: 20px; height: 20px; }
  .timbro-lingua__codice { display: none; }
  .lingue__schiera { right: -2px; min-width: 190px; }
  .prova--grande { height: 240px; }
  .vicine__link--avanti { margin-left: 0; }
  .azioni-blocco { flex-direction: column; align-items: stretch; }
  .azioni-blocco .bottone { justify-content: center; }

  /* sul telefono la gramma si spegne: a pieno campo ruotata costa batteria e
     distrae proprio li' dove il modulo va letto */
  .abisso__griglia { opacity: .22; }

  /* la ricerca torna a potersi spezzare: su schermo stretto tre controlli
     in fila non ci stanno e il campo deve poter scendere */
  .filtri--ricerca { flex-wrap: wrap; }
  .filtri--ricerca .campo--filtro { width: 100%; max-width: none; }
  .filtri--ricerca .campo__input { flex: 1 1 160px; }
  .cubi { display: none; }
}

/* T7 · Zoom 200% e schermo stretto.

   A 320 px — che e' quello che resta con la pagina al 200% su un telefono —
   niente deve scorrere di lato. Le tre cose che lo facevano: la griglia del
   modulo a colonne fisse, il `-2` della `.promemoria__big` e i bordi larghi
   dei pannelli. Qui si lascia scorrere solo il contenuto, mai il corpo. */
@media (max-width: 380px) {
  .pagina { padding: 12px; }
  .foglio { padding: 18px 14px; }
  .marchio__logo { height: 26px; }
  .schede { grid-template-columns: 1fr; }
  .scheda_dati { grid-template-columns: 1fr; }
  /* Marchio, voci e selettore lingua sono tre elementi che non stanno in una
     riga sola a 320 px: il selettore lingua finiva oltre il bordo e con lui
     spariva la via per cambiare lingua. Meglio una testata alta due righe
     che un comando fuori portata. */
  .barra { flex-wrap: wrap; row-gap: 4px; padding-bottom: 12px; }
  .lingue { margin-left: 0; }
  /* L'occhiello dell'accesso e' l'ultima cosa che non entrava: a 12,5 px con
     0,3em di spaziatura fra le lettere «ISPAY CHAIN · REGISTRO DEI MEMBRI»
     misura 371 px, e il `nowrap` non solo tagliava il testo — pretendeva
     371 px di contenitore e trascinava fuori dal riquadro anche il titolo e
     i campi sotto. Su schermo stretto va a capo: due righe di un'etichetta
     decorativa costano meno di una barra di scorrimento laterale. */
  .ingresso__occhiello {
    white-space: normal; letter-spacing: .2em; font-size: 12px;
  }
}

/* chi non vuole il movimento non lo vede: resta un sito, non un'animazione */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .rivela { opacity: 1; transform: none; }
  .cubi { display: none; }
}

/* ---- coincidenze, selezione in blocco, paginazione (funzionali: la veste
   definitiva e' di chi cura l'interfaccia) ---- */
.segnali { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.segnale {
  font-size: 12.5px; line-height: 1.35; color: var(--ambra);
  border-left: 2px solid var(--ambra); padding-left: 8px;
}
.segnali--elenco .segnale { font-size: 14px; }
/* La casella di selezione sta dentro un'etichetta di 44 x 44 px: la casella
   resta di 20 px (si vede bene) ma l'area che si tocca e' quella dell'etichetta.
   Verifica del 15/10: 25 caselle da 20 x 20 px non erano bersagli accettabili. */
.cella-scelta__area {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; cursor: pointer;
}
.cella-scelta input[type="checkbox"] { width: 20px; height: 20px; accent-color: var(--giallo); }
/* il collegamento al numero di un'altra voce, dentro l'elenco delle coincidenze: un
   bersaglio da 44 px senza spostare il testo (margine negativo uguale al riempimento) */
.segnale a, .avviso--coincidenza a { display: inline-block; padding: 14px 6px; margin: -14px -6px; }
.paginazione { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 18px; flex-wrap: wrap; }
.paginazione__stato { font-family: var(--mono); font-size: 13px; color: var(--testo-muto); }
.filtro--esporta { margin-left: auto; }

/* ------------------ la barra degli strumenti dell'amministratore (15/10/2026)
   Sette filtri: quattro in pillola e tre dentro un modulo, piu' i due modi per
   toglierli tutti. La riga del modulo va a capo: sette controlli non ci stanno
   a 320 px e una barra di scorrimento laterale non e' un modo per mostrare un
   filtro. Sotto i 600 px ogni campo prende una riga intera. */

.strumenti { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; margin-top: 16px; }
.strumenti .campo { margin-top: 0; }
.strumenti .campo__etichetta { margin-bottom: 6px; }
.strumenti .campo--filtro { flex: 0 1 190px; min-width: 140px; max-width: 220px; }
.strumenti .campo--data { flex: 0 1 168px; min-width: 140px; }
.strumenti .campo--cerca { flex: 1 1 150px; width: auto; min-width: 0; margin-top: 0; }
.strumenti .bottone { flex: none; padding: 14px 20px; }

/* il pulsante che azzera tutto ha il bordo del portale, non il fondo pieno:
   e' un'azione, non la via principale della pagina */
.filtro--togli { border-color: rgba(255,179,5,.34); color: var(--ambra); }
.filtro--togli:hover { color: #000714; background: var(--giallo); border-color: var(--giallo); }

.filtri--scariche { margin-top: 16px; }
.scariche__nota { flex-basis: 100%; margin: 2px 0 0; font-size: 13px; color: var(--testo-tenue); }

/* il contesto del membro scelto riusa `.avviso`: un riquadro nuovo per
   l'unica cosa che la pagina dice sopra l'elenco sarebbe una quarta forma di
   pannello, e il pannello c'e' gia'. */
.banda-membro { margin-top: 18px; align-items: center; flex-wrap: wrap; }
.banda-membro__testo { flex: 1 1 240px; min-width: 0; }
.banda-membro__titolo { display: block; font-size: 15.5px; }
.banda-membro__conto { display: block; margin-top: 3px; font-size: 13.5px; color: var(--testo-muto); }
.banda-membro__torna { flex: none; }

/* Il nome del membro e' il collegamento al suo contesto. L'area che si tocca
   e' di 44 px senza spostare il testo: margine negativo uguale al riempimento,
   come i numeri delle voci vicine. Sottolineato perche' il colore da solo non
   basta a dire «questo si puo' cliccare». */
.membro__link {
  display: inline-block; padding: 14px 6px; margin: -14px -6px;
  color: var(--testo); text-decoration: underline; text-underline-offset: 3px;
  border-radius: 6px;
}
.membro__link:hover { color: var(--ciano); background: rgba(21,169,233,.16); }
.membro__link:focus-visible { outline: 3px solid var(--ciano); outline-offset: 2px; }

@media (max-width: 600px) {
  /* sotto i 600 px una riga sola e' piu' stretta dei numeri delle date: ogni
     campo prende la sua riga e l'etichetta resta sopra il campo */
  .strumenti { gap: 14px; }
  .strumenti .campo--filtro,
  .strumenti .campo--data { flex: 1 1 100%; max-width: none; }
  .strumenti .bottone { flex: 1 1 100%; }
}
