﻿/* Design system "passaporto d'inchiostro" — ibrido "ariosa + editoriale" (§3.1).
   I valori sono gli stessi di Colori.xaml dell'app: qui non si inventano colori, si
   traduce la palette in CSS custom properties guidate da data-accent/data-theme su
   <html>, così web e app restano coordinati. Supera la vecchia nota "il tema è materia
   dell'app": ora accento e tema si scelgono anche qui (§3.1, deciso 22 lug). */

/* ===== font locali (privacy §6: serviti da wwwroot, mai da un CDN) ===== */

@font-face { font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap; src: url('fonts/Inter-Regular.ttf') format('truetype'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap; src: url('fonts/Inter-Medium.ttf') format('truetype'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap; src: url('fonts/Inter-SemiBold.ttf') format('truetype'); }

/* Niente serif (corretto 23 lug, §3.1): il serif su titoli e numeri riportava le grazie
   sulla I maiuscola che l'app aveva scartato apposta (§7). Un carattere solo, Inter, e la
   differenza la fa il PESO — come le tre chiavi dell'app: 400 testo, 500 in evidenza,
   600 voce (titoli, wordmark, numeri). */

/* Solo i kanji che servono (印 e i quattro elementi): il file è un sottoinsieme di
   NotoSansJP, ~8 KB invece dei 9 MB del variabile completo. */
@font-face { font-family: 'Noto Sans JP'; font-style: normal; font-weight: 500; font-display: swap; src: url('fonts/NotoSansJP-Kanji.ttf') format('truetype'); }

/* ===== accenti: i quattro elementi (§3.1), valori grezzi identici a Colori.xaml =====
   Ogni accento porta: pieno (chiaro/scuro), fondo tenue (chiaro/scuro), testo leggibile
   sulla superficie (chiaro/scuro), tono di banda, e testo/icone sopra il pieno. Il tema
   sceglie poi QUALE variante è attiva. Terra è l'eccezione: su-accento chiaro è scuro,
   perché il suo pieno è troppo chiaro per reggere testo chiaro (deroga WCAG calcolata). */

:root,
html[data-accent="fuoco"] { --acc:#B5382C; --acc-scuro:#D9584C; --acc-tenue-l:#F5E4E1; --acc-tenue-d:#3A2320; --acc-testo-l:#8C2A20; --acc-testo-d:#EFA79E; --acc-banda:#7C2A20; --acc-su-l:#F7EEE9; --acc-su-d:#1C1A16; }
html[data-accent="terra"] { --acc:#A8792E; --acc-scuro:#CBA45C; --acc-tenue-l:#F4EBDA; --acc-tenue-d:#33291A; --acc-testo-l:#7A5717; --acc-testo-d:#DCC08A; --acc-banda:#5E4212; --acc-su-l:#1A1206; --acc-su-d:#1C1A16; }
html[data-accent="aria"]  { --acc:#2F6B42; --acc-scuro:#4E9968; --acc-tenue-l:#E2EFE6; --acc-tenue-d:#1B2C21; --acc-testo-l:#235233; --acc-testo-d:#8FC9A5; --acc-banda:#1C3F27; --acc-su-l:#F7EEE9; --acc-su-d:#1C1A16; }
html[data-accent="acqua"] { --acc:#2E4A7A; --acc-scuro:#5B7FBF; --acc-tenue-l:#E3E9F3; --acc-tenue-d:#1D2739; --acc-testo-l:#24395F; --acc-testo-d:#9FB8E0; --acc-banda:#1B2C4A; --acc-su-l:#F7EEE9; --acc-su-d:#1C1A16; }
html[data-accent="cenere"] { --acc:#6B6156; --acc-scuro:#8E8578; --acc-tenue-l:#F1EEE8; --acc-tenue-d:#2E2B25; --acc-testo-l:#574E44; --acc-testo-d:#CDBFA8; --acc-banda:#4E463B; --acc-su-l:#F7EEE9; --acc-su-d:#1C1A16; }

/* ===== tema chiaro (default) ===== */

:root {
  /* superfici (Colori.xaml) */
  --page:      #EFEBE1;
  --page-tenue:#F5F2EA;
  --card:      #FFFFFF;
  --card-alta: #FFFFFF;
  --border:    #E3DED2;
  --text:      #23201C;
  --muted:     #6B6E73;

  /* rail chiaro su washi + riga tabella al passaggio (specifici del web) */
  --rail:       #FBF9F4;
  --rail-border:#ECE6D9;
  --riga-hover: #FBF9F4;

  /* accento attivo: chiaro usa il pieno e il tenue-chiaro */
  --accent:      var(--acc);
  --accent-tenue:var(--acc-tenue-l);
  --accent-text: var(--acc-testo-l);
  --accent-on:   var(--acc-su-l);
  --accent-banda:var(--acc-banda);

  /* semantici — NON seguono l'accento (§3.1): verificato/mostrato restano sé stessi */
  --ok:#2F7D5B;   --ok-bg:#E4F0EA;   --ok-text:#245C41;
  --warn:#B07214; --warn-bg:#F6EBD6; --warn-text:#8A5A0B;
  /* Arancio delle BARRE di frequenza (§26 ago), a sé da `--warn`: quello è l'ocra dei badge
     d'avviso — «quota scaduta», «in pausa» — e su una barretta di 6px legge marrone. Qui
     serve un arancio che si distingua a colpo d'occhio dal rosso che gli sta sotto nella
     scala e dal verde che gli sta sopra, e `--warn` da solo non ci arrivava. Non si tocca
     `--warn`: cambiarlo ridipingerebbe ogni pastiglia d'avviso del pannello. */
  --arancio:#DD6B20; --arancio-text:#A9501A;
  --err:#A63125;  --err-bg:#F6E4E1;  --err-text:#7A231B;
  --demo:#6A4C93; --demo-on:#FFFFFF;

  /* bottone solido neutro (si inverte al buio) */
  --btn-bg:#17191C;  --btn-fg:#FFFFFF;

  --sans:  'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --jp:    'Noto Sans JP', var(--sans);

  --raggio: 12px;
  --raggio-s: 8px;

  /* MATERIA (strato di movimento, in fondo al file). L'ombra di prima erano due strati di
     blu-grigio al 5%: sul washi non si vedeva, e nessuna .carta leggeva come un foglio
     POSATO sulla pagina. Ora sono tre, e in inchiostro caldo (35,32,28 — la tinta del sumi,
     non un grigio freddo): un filo di contatto, una diffusione corta che dà lo SPESSORE del
     foglio, e un'ombra lunga e rientrata che stacca la carta dal fondo senza sporcarlo.
     --ombra-alta è la stessa mano un gradino più su: la usa solo l'hover di .sollevabile,
     dove il foglio si alza di 1px. Le ~20 regole che già chiamano --ombra ne beneficiano
     senza toccarne nessuna. */
  --ombra: 0 1px 1px rgba(35,32,28,.05),
           0 2px 5px -1px rgba(35,32,28,.055),
           0 14px 28px -12px rgba(35,32,28,.13);
  --ombra-alta: 0 1px 1px rgba(35,32,28,.05),
                0 4px 10px -2px rgba(35,32,28,.08),
                0 22px 40px -14px rgba(35,32,28,.20);

  /* Il washi "vuoto" dello scheletro di caricamento: un tono sotto --page-tenue, perché
     sopra --card (bianco) deve leggersi come una forma e non sparire. */
  --scheletro: #E8E3D6;
  --scheletro-luce: rgba(255,255,255,.85);   /* la luce che lo percorre */

  /* Le tre durate del movimento. Una scala sola, come i tre pesi del carattere: gli stati
     (hover, focus, pressione), le entrate, e il gesto che si guarda. Un quarto valore
     vorrebbe dire che non si è deciso. --t-lunga oggi non la chiama nessuno: è la durata
     dei gesti che vogliono JavaScript (sigillo, conteggio, transizione di pagina) e che
     sono un lavoro a parte — sta qui perché la scala si decide tutta insieme. */
  --t-corta: 120ms;
  --t-media: 260ms;
  --t-lunga: 320ms;   /* un foglio, un pannello: il tempo di un gesto intero (11) */
  --t-lunga: 620ms;
  --curva: cubic-bezier(.22,.68,.28,1);   /* esce svelta, si posa piano */

  /* scala dei caratteri dell'app (Stili.xaml: TitoloPagina 27, Titolo 19, Valore 15, Meta 12.5,
     Etichetta 11; deciso 2 set). La usano i pezzi condivisi — Sezione, Riga, Campo, Foglio. Il
     corpo di pagina resta a 14px finché le pagine non sono passate una per una: alzarlo adesso
     le sposterebbe tutte sotto i piedi. `--t-pagina` è 24 e non 27: il titolo del web è già una
     taglia sotto dal restyle. */
  --t-pagina: 24px;
  --t-titolo: 19px;
  --t-valore: 15px;
  --t-meta: 12.5px;
  --t-etichetta: 11px;
  --t-sezione: 12px;

  /* Cintura e badge del grado (§10): stessi valori di Colori.xaml dell'app. Bianco e
     nero SONO la cintura, non il tema — l'unica che il tema la segue è la nera, che su
     carta scura sparirebbe: in chiaro è quasi nera, al buio un carbone appena sopra la
     card. Il contorno segue il tema perché una cintura bianca senza bordo, di notte,
     scomparirebbe. */
  --cintura-bianca:   #FFFFFF;
  --cintura-nera:     #17140F;
  --cintura-contorno: rgba(0,0,0,.13);

  /* «Il mio percorso»: le tonalità di sabbia della linea del tempo (mockup). Fondo asse,
     tratto pieno (tessera), tratteggio (fermo/pausa), gambo — la tacca finale e l'alone
     seguono invece l'accento. */
  --perc-track:  #F0ECE3;
  --perc-pieno:  #B8AE97;
  --perc-tratto: #CBC3B2;
  --perc-gambo:  #C3BAA6;

  color-scheme: light;
}

/* ===== tema scuro ===== */

html[data-theme="dark"] {
  --page:      #1A1A19;
  --page-tenue:#201F1E;
  --card:      #242422;
  --card-alta: #2E2E2B;
  --border:    #474642;
  --text:      #E9E7E1;
  --muted:     #97968F;

  --rail:       #201F1E;
  --rail-border:#383734;
  --riga-hover: #292927;

  /* al buio è l'accento a dover risaltare sulla carta: pieno più chiaro, tenue scuro */
  --accent:      var(--acc-scuro);
  --accent-tenue:var(--acc-tenue-d);
  --accent-text: var(--acc-testo-d);
  --accent-on:   var(--acc-su-d);
  --accent-banda:var(--acc-banda);

  --ok:#5FA783;   --ok-bg:#24422F;   --ok-text:#9ED8B8;
  --warn:#D5A24A; --warn-bg:#493617; --warn-text:#E6C489;
  --arancio:#EF8B4B; --arancio-text:#F3AB7E;
  --err:#E0776B;  --err-bg:#4A2723;  --err-text:#F0A99F;
  --demo:#A98BD6; --demo-on:#1F1633;

  --btn-bg:#E9E7E1;  --btn-fg:#1A1A19;

  /* L'ombra al buio non può restare quella chiara: l'inchiostro caldo (35,32,28) è quasi il
     colore del fondo, quindi sparirebbe, e una .carta #242422 su una pagina #1A1A19 non
     leggerebbe più come un foglio posato ma come un rettangolo appena più chiaro. Stessa
     geometria a tre strati, nero pieno e molto più opaco: è l'opacità, non la forma, a
     cambiare col tema. */
  --ombra: 0 1px 1px rgba(0,0,0,.30),
           0 2px 5px -1px rgba(0,0,0,.34),
           0 14px 28px -12px rgba(0,0,0,.55);
  --ombra-alta: 0 1px 1px rgba(0,0,0,.32),
                0 4px 10px -2px rgba(0,0,0,.42),
                0 22px 40px -14px rgba(0,0,0,.68);

  /* Lo scheletro al buio va SOPRA la card (#242422), non sotto — al buio "vuoto" vuol dire
     più chiaro, non più scuro. E la luce che lo percorre è un bianco al 7%, non all'85%:
     quello, su fondo scuro, sarebbe un lampeggio. */
  --scheletro: #32312E;
  --scheletro-luce: rgba(255,255,255,.07);

  /* La nera diventa un carbone (non nero pieno) e il contorno si schiarisce (§10). */
  --cintura-nera:     #3D3C39;
  --cintura-contorno: #67655E;

  --perc-track:  #282826;
  --perc-pieno:  #575651;
  --perc-tratto: #474642;
  --perc-gambo:  #575651;

  color-scheme: dark;
}

/* "Di sistema": segue prefers-color-scheme quando il tema è system (o non impostato,
   pre-JS). Ripete i token scuri — è l'unico modo per farli valere senza l'attributo. */
@media (prefers-color-scheme: dark) {
  html[data-theme="system"],
  html:not([data-theme]) {
    --page:#1A1A19; --page-tenue:#201F1E; --card:#242422; --card-alta:#2E2E2B;
    --border:#474642; --text:#E9E7E1; --muted:#97968F;
    --rail:#201F1E; --rail-border:#383734; --riga-hover:#292927;
    --accent:var(--acc-scuro); --accent-tenue:var(--acc-tenue-d);
    --accent-text:var(--acc-testo-d); --accent-on:var(--acc-su-d); --accent-banda:var(--acc-banda);
    --ok:#5FA783; --ok-bg:#24422F; --ok-text:#9ED8B8;
    --warn:#D5A24A; --warn-bg:#493617; --warn-text:#E6C489;
    --arancio:#EF8B4B; --arancio-text:#F3AB7E;
    --err:#E0776B; --err-bg:#4A2723; --err-text:#F0A99F;
    --demo:#A98BD6; --demo-on:#1F1633;
    --btn-bg:#E9E7E1; --btn-fg:#1A1A19;
    --ombra: 0 1px 1px rgba(0,0,0,.30), 0 2px 5px -1px rgba(0,0,0,.34), 0 14px 28px -12px rgba(0,0,0,.55);
    --ombra-alta: 0 1px 1px rgba(0,0,0,.32), 0 4px 10px -2px rgba(0,0,0,.42), 0 22px 40px -14px rgba(0,0,0,.68);
    --scheletro:#32312E; --scheletro-luce:rgba(255,255,255,.07);
    --cintura-nera:#3D3C39; --cintura-contorno:#67655E;
    --perc-track:#282826; --perc-pieno:#575651; --perc-tratto:#474642; --perc-gambo:#575651;
    color-scheme: dark;
  }
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  font-family: var(--sans);
  color: var(--text);
  background: var(--page);
  font-size: 15px;
  line-height: 1.5;
}

/* Titoli in Inter 600 (la "voce" dell'app), non in serif: la I di "I Dan" resta ad asta
   pulita (§3.1, §7). Sentence case ovunque. */
h1, h2, h3 { font-weight: 600; letter-spacing: -.015em; color: var(--text); }
/* Titolo di pagina più stretto (§3.1, restyle): ~22px, non 27. Il sottotitolo (.sottotitolo)
   porta il contesto — stagione, conteggio — senza ripetere il nome dell'ente. */
h1 { font-size: 1.45rem; margin: 0 0 .2rem; }
h2 { font-size: 1.15rem; margin: 0 0 .7rem; }
h3 { font-size: 1rem; margin: 0 0 .5rem; }
/* FocusOnNavigate (Routes.razor) porta il focus sull'h1 di pagina a ogni navigazione, così
   lo screen reader riparte dal titolo. È un focus PROGRAMMATICO, non un gesto dell'utente:
   l'anello di focus del browser sull'h1 (largo quanto la pagina) è solo rumore visibile, si
   toglie. L'accessibilità resta — il focus c'è, non lo si disegna. */
h1:focus, h1:focus-visible { outline: none; }

/* Un nome o un grado dentro un elenco: in evidenza col peso 500, come il "valore" nell'app
   (era la vecchia classe `.serif`, rinominata quando il serif è caduto). */
.risalto { font-weight: 500; color: var(--text); }

.kanji { font-family: var(--jp); }

a { color: var(--accent-text); text-decoration: none; }
a:hover { text-decoration: underline; }
/* L'underline di a:hover è giusto per una parola-link in una frase, ma «cola» sui link che sono
   scatole (pulsanti, piastrelle, righe-card) o affordance di ritorno: lì l'hover si mostra con
   fondo/bordo, mai sottolineato. Questi opt-out lo spengono (la specificità :hover batte a:hover). */
.bottone:hover, .ev-riga:hover, .link-indietro:hover { text-decoration: none; }

.wordmark {
  font-weight: 600;
  font-size: 1.3rem;
  color: var(--text);
  padding: 0 1.25rem 1.1rem;
  display: flex;
  align-items: center;
  gap: .6rem;
}

.wordmark .bollo-logo {
  width: 32px; height: 32px;
  border-radius: 7px;
  object-fit: contain;
}
/* Card «in arrivo»: segnaposto centrato per una superficie disattivata nel pilota. */
.carta.in-arrivo { max-width: 480px; margin: 2rem auto; text-align: center; }
.carta.in-arrivo .in-arrivo-ico { color: var(--muted); margin-bottom: .4rem; }
.carta.in-arrivo .in-arrivo-ico svg { width: 40px; height: 40px; }

/* ===== Immagini pubbliche d'ente + moderazione (PILOTA) ===================== */
/* DORMIENTI dal 25 ago: .slot-immagine / .slot-anteprima / .slot-corpo vestivano la card
   «Immagini pubbliche» delle Impostazioni ente, che conteneva solo un rimando ai timbri (logo e
   copertina stanno nella testata, i timbri nel foglio di ogni maestro). Nessun markup le usa più;
   restano perché sono la resa di uno slot immagine, e la moderazione qui sotto è viva. */
.slot-immagine { display: flex; gap: 1rem; align-items: flex-start; padding: .8rem 0; border-top: 1px solid var(--border); flex-wrap: wrap; }
.slot-immagine:first-of-type { border-top: none; padding-top: 0; }
.slot-anteprima { flex: 0 0 auto; width: 130px; height: 84px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--page-tenue); display: flex; align-items: center; justify-content: center; overflow: hidden; color: var(--muted); }
.slot-anteprima img { max-width: 100%; max-height: 100%; object-fit: contain; }
.slot-corpo { flex: 1; min-width: 200px; }
.slot-corpo b { display: block; margin-bottom: .2rem; }

/* Badge di stato della moderazione: In revisione (ambra) / Pubblico (verde) / Da rivedere (rosso). */
.mod-badge { display: inline-block; font-size: .68rem; font-weight: 600; padding: .1rem .5rem; border-radius: 20px; }
.mod-badge.rev { background: var(--warn-bg); color: var(--warn-text); }
.mod-badge.pub { background: var(--ok-bg); color: var(--ok-text); }
.mod-badge.no  { background: var(--err-bg); color: var(--err-text); }
.mod-nota { font-size: .8rem; color: var(--err-text); margin: .35rem 0; }

/* Sfondo a scacchi per leggere la trasparenza dei PNG (anteprima nella coda admin). */
.scacchi {
  background-color: #fff;
  background-image:
    linear-gradient(45deg, #e6e6e6 25%, transparent 25%), linear-gradient(-45deg, #e6e6e6 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #e6e6e6 75%), linear-gradient(-45deg, transparent 75%, #e6e6e6 75%);
  background-size: 20px 20px; background-position: 0 0, 0 10px, 10px -10px, -10px 0;
}

/* Miniatura di una voce nella coda di moderazione media: quadratino con la scacchiera dietro
   (le immagini possono essere trasparenti). */
.media-thumb { width: 48px; height: 48px; flex: 0 0 auto; object-fit: contain; border-radius: 6px; border: 1px solid var(--border); }

.contenuto { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* LA COLONNA DEL CONTENUTO — la larghezza e le spalle stanno QUI, in due variabili, e non
   altrove: nel guscio a schede ci si allineano anche la barra e la fila delle schede (2 set), e
   una misura scritta in tre posti si disallinea alla prima modifica. Chi ha bisogno della
   colonna legge `--colonna` e `--colonna-lato`; nessuno riscrive i numeri. */
:root { --colonna: 1180px; --colonna-lato: 1.75rem; }

.pagina { padding: var(--colonna-lato); max-width: var(--colonna); width: 100%; }
.sottotitolo { color: var(--muted); margin: 0 0 1.25rem; }

/* --- superfici ---------------------------------------------------------- */

.carta {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--raggio);
  box-shadow: var(--ombra);
  padding: 1.25rem;
}
/* Carta-modulo: un form breve non deve stirarsi a tutta pagina (§leggibilità). Stessa misura
   che le pagine sorelle mettevano inline (DichiaraGrado, ChiediRatifica, ChiediAffiliazione). */
.carta.modulo { max-width: 560px; }

.griglia { display: grid; gap: 1rem; }
.griglia.tre { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.griglia.due { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

/* Tessere-statistica morbide: i numeri li porta il peso, non un secondo carattere (§3.1). */
.dato { font-weight: 600; font-size: 2.1rem; line-height: 1.1; letter-spacing: -.01em; color: var(--text); }
.etichetta { color: var(--muted); font-size: .82rem; }

/* Il "perché" accanto a un numero grande: "+3 nel mese", "la più vecchia da 3 giorni". Un 2
   nudo non dice se preoccuparsi. */
.dato-perche { font-size: .82rem; color: var(--muted); font-weight: 400; margin-left: .4rem; }

/* --- intestazione di pagina: titolo stretto + sottolinea di contesto ---
   Il sottotitolo non ripete il nome dell'ente (già a schermo due volte). */
.pagina-titolo { font-size: 1.4rem; font-weight: 600; letter-spacing: -.015em; margin: 0 0 .1rem; }
.pagina-sub { color: var(--muted); font-size: .88rem; margin: 0 0 1.25rem; }

/* --- carta: testa con titolo di sezione (maiuscolo, fioco) e azione ---- */
.carta-testa { display: flex; align-items: center; gap: .5rem; margin-bottom: .9rem; }
.carta-testa .spazio { flex: 1; }
.carta-titolo {
  font-size: 9.5px; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); opacity: .8;
}
.carta-azione, .carta-azione a { font-size: .8rem; }
/* La pastiglia di STATO accanto al titolo (§26 ago): non è un'azione — quindi non sta nello slot
   a destra — ed è lo stato di ciò che la carta contiene, non uno dei suoi dati. Fra i dati, per
   restare in colonna, si prendeva una riga intera per una parola sola.

   Il distacco dal titolo lo dà il `gap` della testa più un filo: deve leggersi come «TESSERA ·
   Valida», non come una seconda etichetta di sezione. I margini propri del badge si azzerano —
   sono pensati per un flusso di testo, e quello in basso qui lo scentrerebbe nella riga flex.
   `:empty` è la rete per la carta che dichiara lo slot e a volte non ha niente da metterci (la
   tessera in modifica, l'ente che non gestisce la scadenza): senza, resterebbe il `gap`. */
.carta-pastiglia { display: inline-flex; margin-left: .15rem; }
.carta-pastiglia:empty { display: none; }
.carta-pastiglia .badge { margin: 0; }
/* Periodo delle statistiche accanto al titolo di una carta: SOLO etichetta, mai un comando. */
.carta-periodo { font-size: .8rem; color: var(--muted); white-space: nowrap; }

/* Il periodo della «Salute del dojo» è un COMANDO (25 ago): stessa taglia e stesso tono di
   quando era etichetta — non deve gridare — ma con la freccina e il menù al clic, nello stile di
   quello della lingua. Il contenitore è l'àncora: .menu è position:absolute e senza un antenato
   posizionato scenderebbe dall'angolo della pagina. Allineato a destra perché nasce dallo slot
   azione, che sta a destra nella testata della carta. */
.periodo-scelta { position: relative; display: inline-block; }
.carta-periodo.comando {
  border: none; background: transparent; padding: 0; cursor: pointer;
  font-family: var(--sans); color: var(--muted);
}
.carta-periodo.comando:hover { color: var(--accent-text); }
.carta-periodo .freccia { font-size: .7rem; }
.menu-periodo { right: 0; width: 240px; }
/* La riga che dice la conseguenza della scelta: è dell'ente, non una lente personale. */
.menu-nota {
  margin: .35rem .55rem .1rem; font-size: .74rem; color: var(--muted); line-height: 1.4;
}

/* --- conteggio a pastiglia (accento / ambra / rosso) ------------------- */
.conteggio {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 .35rem; border-radius: 999px;
  font-size: .72rem; font-weight: 600;
  background: var(--accent-tenue); color: var(--accent-text);
}
.conteggio.ambra { background: var(--warn-bg); color: var(--warn-text); }
.conteggio.rosso { background: var(--err-bg); color: var(--err-text); }

/* Riga "richiede attenzione": etichetta a sinistra, pastiglia di conteggio a destra. */
.df {
  display: flex; align-items: center; gap: .5rem;
  padding: .55rem .15rem; border-bottom: 1px solid var(--border);
  color: var(--text); text-decoration: none;
}
.df:last-child { border-bottom: none; }
.df:hover { text-decoration: none; color: var(--accent-text); }
.df span:first-child { flex: 1; }

/* --- riga persona: quadratino-avatar + nome + meta + valore in coda ---- */
.riga-persona { display: flex; align-items: center; gap: .7rem; padding: .55rem 0; border-bottom: 1px solid var(--border); }
.riga-persona:last-child { border-bottom: none; }
.rp-av {
  flex: 0 0 36px; width: 36px; height: 36px; border-radius: 9px;
  background: var(--accent-tenue); color: var(--accent-text);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: .82rem;
  /* `--jp` è «Noto Sans JP, poi il sans»: la faccia incorporata è un sottoinsieme di soli kanji,
     quindi una lettera latina ci cade attraverso e resta nel carattere di sempre. Così la stessa
     casella regge sia le iniziali di una persona sia il kanji di una disciplina, senza che chi
     la riempie debba dire quale dei due sta passando (§26 ago). È la ricetta che `.hero .disc`
     usa da sempre, e infatti quella casella si chiamava «Glifo» già prima di averne uno. */
  font-family: var(--jp);
}
.rp-corpo { flex: 1; min-width: 0; }
.rp-nome { font-weight: 500; }
.rp-meta { font-size: .8rem; color: var(--muted); }
.rp-valore { margin-left: auto; flex: 0 0 auto; text-align: right; }
/* Riga persona come link: bersaglio tutto-riga, alone tenue, › discreto in coda. */
.riga-persona.linkabile {
  cursor: pointer; color: var(--text); text-decoration: none;
  margin: 0 -.6rem; padding-left: .6rem; padding-right: .6rem;
  border-radius: 9px; transition: background .12s ease;
}
.riga-persona.linkabile:hover { background: var(--accent-tenue); color: var(--accent-text); }
.riga-persona.linkabile:hover .rp-meta,
.riga-persona.linkabile:hover .rp-vai { color: var(--accent-text); }
.rp-vai { flex: 0 0 auto; margin-left: .45rem; color: var(--muted); }
/* Avatar della riga quando ospita un segno grafico (SegnoGrado) al posto delle iniziali:
   niente fondo accento, il token porta il suo, e l'SVG riempie la casella di 36px. */
.rp-av.rp-segno { background: transparent; padding: 0; }
.rp-av.rp-segno .token-svg { width: 36px; height: auto; display: block; }

/* --- barra strumenti delle liste (indice: ricerca + pastiglie filtro) --------------------
   Usata sopra gli elenchi persona/entità (Soci, Corsi, Discipline, Maestri). Colori dalle
   sole variabili, così luce/buio restano validi. La cerca cresce, i filtri stanno a destra. */
.toolbar { display: flex; gap: .75rem; align-items: center; flex-wrap: wrap; margin-bottom: 1rem; }
.toolbar .cerca {
  flex: 1 1 220px; min-width: 200px; max-width: 340px;
  border-radius: 999px; padding: .5rem .95rem;
}
.filtro { display: flex; flex-wrap: wrap; gap: .5rem; margin-left: auto; }
.filtro .f {
  display: inline-flex; align-items: center; gap: .35rem; width: auto;
  font-family: var(--sans); font-size: .85rem; font-weight: 500;
  padding: .4rem .8rem; border-radius: 999px;
  border: 1.4px solid var(--border); background: transparent; color: var(--muted);
  cursor: pointer; white-space: nowrap;
}
.filtro .f:hover { border-color: var(--accent); color: var(--text); }
.filtro .f.on { border-color: var(--accent); background: var(--accent-tenue); color: var(--accent-text); }
.filtro .f .spunta { visibility: hidden; }
/* Il conteggio in coda alla pastiglia (6 set): un gradino più tenue, cifre allineate. A zero la
   pastiglia è spenta. */
.filtro .f .n { margin-left: .15rem; opacity: .7; font-variant-numeric: tabular-nums; }
.filtro .f:disabled { opacity: .45; cursor: default; }
.filtro .f:disabled:hover { border-color: var(--border); color: var(--muted); }
.filtro .f.on .spunta { visibility: visible; color: var(--accent); }

/* --- intestazioni ordinabili (tabella Soci) ----------------------------------------------
   La colonna cliccabile ordina; ri-clic inverte. La freccia (.ar) sta sulla colonna attiva
   (.on), in accento. Colori dalle sole variabili. */
th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
th.sortable:hover { color: var(--accent-text); }
th.on { color: var(--accent-text); }
.ar { color: var(--accent); font-weight: 700; margin-left: .25rem; }

/* La cella «socio»: avatar (foto o iniziali) + gettone del grado + nome. */
.cell-socio { display: flex; align-items: center; gap: .6rem; }
.cell-socio .segno .token-svg { width: 34px; }
.cell-socio .rp-av { flex: 0 0 32px; width: 32px; height: 32px; }
/* La foto del socio nello slot in testa: stessa impronta della casella iniziali (.rp-av),
   ma tonda e ritagliata. */
.rp-foto { flex: 0 0 32px; width: 32px; height: 32px; border-radius: 50%; object-fit: cover; }
.cell-socio .rp-foto { flex: 0 0 32px; width: 32px; height: 32px; }
table.soci tbody tr { cursor: pointer; }

/* Barretta di presenza: traccia tenue + riempimento (verde ok), come su Home. */
.barrina { height: 6px; width: 64px; border-radius: 4px; background: var(--page-tenue);
  display: inline-block; vertical-align: middle; position: relative; overflow: hidden; }
.barrina i { position: absolute; left: 0; top: 0; bottom: 0; background: var(--ok); border-radius: 4px; }
/* Scala a tre (§26 ago), la stessa per tutte e quattro le barre di frequenza: rosso sotto il
   20%%, ambra fino al 60%%, verde sopra. Il verde non ha classe — è il colore di riposo scritto
   nella regola base, e così nel markup si vede solo ciò che devia. Le soglie stanno in
   `Budopass.Client.Frequenza`, non qui: il CSS sa i colori, non dove cadono. */
.barrina.media i { background: var(--arancio); }
.barrina.scarsa i { background: var(--err); }

/* Dettaglio corso: le sezioni della scheda Impostazioni su due colonne (a sinistra il corso e
   i gradi, a destra gli orari). Le carte impilate in una colonna si distanziano da sole. */
.corso-due { display: grid; grid-template-columns: 1.1fr .9fr; gap: 1rem; align-items: start; }
.corso-due > div { display: flex; flex-direction: column; gap: 1rem; }
@media (max-width: 820px) { .corso-due { grid-template-columns: 1fr; } }

/* Orari come lista pulita (al posto della tabella): giorno + fascia oraria + sala + azioni. */
.orario { display: flex; align-items: center; flex-wrap: wrap; gap: .75rem; padding: .6rem .75rem;
  border: 1px solid var(--border); border-radius: 10px; }
/* Conferma «rimuovi orario»: azione-prima. Va a capo a tutta larghezza dentro la riga (non
   schiaccia giorno/ora/azioni) e presenta due card-scelta impilate, ognuna con la sua conseguenza;
   la distruttiva usa il tono d'errore (washi hanko). */
.orario .orario-conferma { flex: 1 0 100%; display: flex; flex-direction: column; gap: .5rem;
  margin-top: .15rem; }
.orario-conferma .oc-domanda { font-size: .9rem; font-weight: 600; color: var(--text); }
/* Card-scelta full-width: bordo tenue, glifo a sinistra, titolo + sottotesto muted. */
.orario-conferma .oc-scelta { display: flex; align-items: flex-start; gap: .6rem; width: 100%;
  text-align: left; padding: .7rem .75rem; border: 1px solid var(--border); border-radius: 11px;
  background: var(--card); color: var(--text); cursor: pointer; transition: border-color .12s, background .12s; }
.orario-conferma .oc-scelta:hover:not(:disabled) { border-color: var(--muted); }
.orario-conferma .oc-scelta:disabled { opacity: .55; cursor: default; }
.orario-conferma .oc-ico { flex: 0 0 24px; width: 24px; height: 24px; border-radius: 7px;
  background: var(--page-tenue); color: var(--muted); display: grid; place-items: center; margin-top: .05rem; }
.orario-conferma .oc-ico svg { width: 15px; height: 15px; fill: none; stroke: currentColor;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.orario-conferma .oc-testo { display: flex; flex-direction: column; gap: .12rem; min-width: 0; }
.orario-conferma .oc-tit { font-size: .92rem; font-weight: 600; line-height: 1.25; }
.orario-conferma .oc-nota { font-size: .8rem; color: var(--muted); line-height: 1.35; }
/* Scelta distruttiva: tono hanko d'errore su fondo washi. */
.orario-conferma .oc-scelta.danno { background: var(--err-bg); border-color: var(--err-bg); }
.orario-conferma .oc-scelta.danno:hover:not(:disabled) { border-color: var(--err); }
.orario-conferma .oc-scelta.danno .oc-tit { color: var(--err-text); }
.orario-conferma .oc-scelta.danno .oc-ico { background: var(--err); color: #fff; }
/* Annulla discreto sotto le scelte. */
.orario-conferma .oc-annulla { align-self: flex-start; background: none; border: 0; padding: .1rem .1rem;
  color: var(--muted); font-size: .85rem; cursor: pointer; }
.orario-conferma .oc-annulla:hover:not(:disabled) { color: var(--text); text-decoration: underline; }
.orario-conferma .oc-azioni { display: flex; gap: .5rem; flex-wrap: wrap; }
.orario + .orario { margin-top: .5rem; }
.orario .g { font-weight: 600; min-width: 96px; }
.orario .h { font-family: monospace; }
.orario .sala { color: var(--muted); font-size: .82rem; }
/* Spaziatore flessibile generico (spinge a destra ciò che segue in una riga flex). Le regole
   .X .spazio scoped restano valide; questa le generalizza dove non erano previste (toolbar liste). */
.spazio { flex: 1; }

/* --- testata-hero della scheda corso (v2) + striscia KPI (dati già caricati) --------------
   Identità del corso a colpo d'occhio: tessera disciplina + nome + pastiglie, poi i numeri. */
.hero { display: flex; align-items: flex-start; gap: 1rem; }
.hero .disc {
  width: 52px; height: 52px; border-radius: 12px; flex: 0 0 auto;
  background: var(--accent-tenue); color: var(--accent-text);
  display: grid; place-items: center; font-family: var(--jp); font-size: 1.5rem;
}
.hero-corpo { flex: 1; min-width: 0; }
.hero-corpo h1 { margin: 0; }
.hero-sub { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; margin-top: .5rem; }
.dato-chip {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .78rem; font-weight: 600; color: var(--text);
  background: var(--page-tenue); border: 1px solid var(--border); border-radius: 18px; padding: .25rem .6rem;
}
.kpi { display: flex; margin-top: .9rem; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: var(--card); }
.kpi .k { flex: 1; padding: .7rem .9rem; border-right: 1px solid var(--border); }
.kpi .k:last-child { border-right: none; }
.kpi .n { font-size: 1.15rem; font-weight: 700; line-height: 1.15; }
.kpi .l { font-size: .68rem; color: var(--muted); margin-top: .2rem; text-transform: uppercase; letter-spacing: .04em; }
@media (max-width: 620px) { .kpi { flex-wrap: wrap; } .kpi .k { flex: 1 1 45%; } }

/* Riga settimana negli orari: 7 giorni, quelli con lezione in accento. */
.settimana { display: flex; gap: .35rem; margin-bottom: .75rem; }
.settimana .gg { flex: 1; text-align: center; font-size: .7rem; font-weight: 700; color: var(--muted);
  background: var(--page-tenue); border-radius: 8px; padding: .45rem 0; }
.settimana .gg.on { background: var(--accent); color: var(--accent-on); }

/* --- Impostazioni: anteprima viva «come ti vedono gli allievi» (v2) -----------------------
   Una scheda ente uguale a quella dell'app, legata ai campi @bind del form: si aggiorna dal vivo. */
.preview-lab { font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin-bottom: .5rem; }
.ente-card { border: 1px solid var(--border); border-radius: 16px; overflow: hidden; background: var(--card); box-shadow: var(--ombra); margin-bottom: 1rem; }
.ente-cover { height: 96px; position: relative; background: linear-gradient(120deg, var(--accent-tenue), var(--accent-banda)); }
.ente-cover > img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ente-logo {
  position: absolute; left: 16px; bottom: -24px; width: 56px; height: 56px; border-radius: 14px; overflow: hidden;
  background: var(--card); border: 2px solid var(--card); box-shadow: 0 3px 8px rgba(0,0,0,.15);
  display: grid; place-items: center; font-family: var(--jp); font-size: 1.5rem; color: var(--accent-text);
}
.ente-logo > img { width: 100%; height: 100%; object-fit: cover; }
.ente-body { padding: 2rem 1rem 1rem; }
.ente-body h3 { margin: 0; font-size: 1.05rem; }
.ente-body .m { font-size: .8rem; color: var(--muted); margin-top: .2rem; }
.ente-tag { margin-top: .6rem; display: flex; gap: .4rem; flex-wrap: wrap; }

/* --- archetipo dettaglio (schede socio/corso) --------------------------------------------
   Una testata piena + una griglia a due colonne di carte. Le classi qui sotto sostituiscono i
   vecchi style inline (flex a mano): spaziature e colori vengono solo dalle variabili. */
.det-griglia { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; align-items: start; }
/* Ogni colonna è una PILA che si impacchetta per conto suo (§26 ago), come `imp-griglia` nelle
   impostazioni. In auto-flow le carte si allineavano alla riga, cioè alla più alta delle due:
   fra una carta e la successiva restavano buchi che nessuno aveva scelto. */
.det-griglia > .det-col { display: grid; gap: 1rem; align-content: start; }
@media (max-width: 720px) { .det-griglia { grid-template-columns: 1fr; } }

/* Impostazioni utente: le carte su due colonne affiancate (assegnazione esplicita, niente
   auto-flow), ciascuna colonna una pila con lo stesso gap delle carte. Sotto soglia, una sola
   colonna con le carte impilate nell'ordine del markup. */
.imp-griglia { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; align-items: start; max-width: 960px; }
.imp-griglia > .imp-col { display: grid; gap: 1rem; align-content: start; }
@media (max-width: 720px) { .imp-griglia { grid-template-columns: 1fr; } }

/* Testata: avatar del socio + identità (col grado accanto al nome), con l'azione in alto a
   destra (slot Azione della carta). */
.det-intestazione { display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; }
.det-chi { flex: 1; min-width: 200px; }
/* Le azioni della testata stanno DENTRO la riga dell'identità (§26 ago), non nello slot `Azione`
   della carta. Quello slot vive nella testa della carta, accanto al titolo: qui un titolo non
   c'è, e la testa veniva su come una fascia vuota alta quanto due pulsanti, con mezza carta di
   niente accanto — spazio che non conteneva nulla e che si notava solo perché era vuoto.

   Nella riga si allineano al centro dell'identità, che con nome / codice socio / stato vuol dire
   proprio all'altezza del codice socio. A destra ci vanno da sé — `.det-chi { flex: 1 }` li
   spinge —, ma `margin-left: auto` è la rete per il giorno in cui quel flex cambiasse. */
.det-intestazione-azioni { display: flex; gap: .5rem; flex-wrap: wrap; flex: none; margin-left: auto; }
.det-chi h1 { margin: 0; }
.det-badge { margin-top: .4rem; display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; }
.segno.segno-grande .token-svg { width: 66px; }
/* Avatar di testata: la foto (o le iniziali) nello slot in testa, ~72px e tondo. */
.det-foto { flex: 0 0 72px; width: 72px; height: 72px; border-radius: 50%; object-fit: cover; }
.det-iniziali {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-tenue); color: var(--accent-text);
  font-weight: 600; font-size: 1.4rem;
}
/* Nome + gettone del grado su una riga: il segno sta accanto al titolo (non più in testa). */
.det-nome { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.det-nome .segno .token-svg { width: 40px; }
.mono { font-family: monospace; }
a.badge { text-decoration: none; }

/* Gruppo chiave/valore in lettura (etichetta fioca + valore in risalto). */
.det-dati { display: flex; flex-wrap: wrap; gap: 1.5rem; margin: .5rem 0 1rem; }

/* DATI e BOTTONI non si toccano (§26 ago): quando una carta mostra dei dati e poi delle azioni,
   fra i due ci va una riga. Senza, i pulsanti si leggono come un valore in più della fila —
   «Rinnova tessera» sembrava il contenuto della colonna che gli stava sopra.

   La regola sta QUI e non nelle singole pagine: vale ovunque i due blocchi si susseguano, e una
   carta nuova se la ritrova senza doversene ricordare. Il selettore di fratellanza è preciso di
   suo — scatta solo quando le azioni seguono davvero dei dati, non per ogni `.det-azioni` della
   pagina (nei form, dove i bottoni chiudono dei campi, la riga non ci va). `.det-rinnovo` è la
   stessa transizione col pannello inline aperto al posto del bottone. */
.det-dati + .det-azioni,
.det-dati + .det-rinnovo { border-top: 1px solid var(--border); margin-top: 0; padding-top: .9rem; }

/* Righe di campi in modifica: i .campo dentro si dividono lo spazio e vanno a capo. */
.det-campi { display: flex; gap: .75rem; flex-wrap: wrap; }
.det-campi .campo { flex: 1 1 150px; min-width: 140px; margin-bottom: 0; }

/* `pari`: le colonne restano della STESSA misura anche sull'ultima riga (§26 ago). In flex un
   campo che resta solo in coda si allarga per tutta la riga — «Scadenza» diventava largo il
   triplo di «Rinnovo» che gli sta sopra, e un campo data largo mezza carta promette uno spazio
   che non serve a nessuno. `auto-fill` tiene le tracce vuote; `auto-fit` le collassa, ed è tutta
   la differenza fra un campo che resta in colonna e uno che si mangia la riga.

   È un MODIFICATORE e non la nuova regola di `.det-campi`: in giro per l'app quel contenitore
   porta decine di pesi scritti a mano sui campi (`style="flex:2"` accanto a `flex:1`, per dare
   più spazio a un comune che a un CAP), e in griglia diventerebbero tutti uguali senza che
   nessuno se ne accorga. Si mette dove i campi sono davvero pari fra loro. */
.det-campi.pari { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr)); }

/* I bottoni di un FORM stanno in fondo a destra (§26 ago): dove finisce la lettura dei campi
   finisce anche la riga, e l'occhio li trova dove li ha lasciati l'ultimo campo. Vale solo per le
   azioni che seguono davvero dei campi — le azioni di una CARTA (che seguono dei dati, o stanno
   da sole) restano a sinistra, dove cominciano le cose che si leggono. */
.det-campi + .det-azioni { justify-content: flex-end; }

/* Riga di pulsanti; nella scheda quota ospita anche il campo data (largo quanto basta). */
.det-azioni { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; margin-top: .25rem; }
.det-azioni input[type="date"] { width: auto; }
/* Il filo fra due gruppi di azioni (§26 ago): a sinistra i gesti che si disfano, a destra quelli
   che non si disfano. `align-self: stretch` gli dà l'altezza dei bottoni senza fissarla a mano.
   Sotto la soglia i pulsanti vanno a capo e il filo non separerebbe più niente: sparisce. */
.det-sep { width: 1px; align-self: stretch; background: var(--border); margin: .1rem .35rem; }
@media (max-width: 720px) { .det-sep { display: none; } }

/* Il TAGLIO in fondo alla scheda socio (§26 ago), prima delle azioni sulla pratica: separa ciò
   che si LEGGE da ciò che AGISCE. Sfuma ai bordi invece di correre da parte a parte — così è una
   pausa nella pagina e non l'ennesima riga di tabella, che qui dentro ce ne sono già molte. Lo
   spazio sopra è il doppio di quello sotto: il filo appartiene a quello che viene DOPO. */
.det-taglio {
  border: 0; height: 1px; margin: 2.2rem 0 1.1rem;
  background: linear-gradient(to right, transparent, var(--border) 12%, var(--border) 88%, transparent);
}

/* Il pannello di modifica che si apre nella testata: staccato da una linea. */
.det-forma { margin-top: 1rem; border-top: 1px solid var(--border); padding-top: 1rem; }
.det-forma .det-campi { margin-bottom: .75rem; }
.det-forma h3 { margin-top: 0; }

/* Riga di azioni allineata a destra (in fondo a un form: es. Salva della scheda corso). */
.det-azioni.fine { justify-content: flex-end; }

/* Lista di spunte scorrevole (roster: aggiungi soci a un corso). */
.roster-scroll { max-height: 320px; overflow: auto; margin-bottom: .5rem; }

/* Avviso con cornice d'attenzione (conferme di generazione/disattivazione): il warn non segue
   l'accento, come i badge di stato. Sostituisce lo style inline «border:1px solid var(--warn)». */
.avviso.attenzione { border: 1px solid var(--warn); margin-top: .75rem; }

/* --- tabelle (in Inter, leggibili anche fitte — §3.1) ------------------- */

table { width: 100%; border-collapse: collapse; }
th {
  text-align: left;
  font-size: .74rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--muted);
  font-weight: 600;
  padding: .55rem .6rem;
  border-bottom: 1px solid var(--border);
}
td { padding: .6rem; border-bottom: 1px solid var(--border); }

/* --- la tabella dei gradi, dentro una carta di mezza pagina (§26 ago) ------------------
   Cinque colonne in poco più di 500px: la data andava a capo («30 mag / 26») e i due
   pulsanti si impilavano uno sotto l'altro — su sei gradi, dodici bottoni in colonna.

   La regola è che UNA sola colonna può cedere, quella del nome: a stringersi manda a capo
   una parola e non fa danno. Tutte le altre portano un dato che non si spezza — una data,
   un timbro, due comandi — e `width: 1%` su una cella di tabella è il modo di dire
   «prenditi lo stretto necessario»: il browser dà il minimo a chi lo chiede e tutto il
   resto a chi non dice niente.

   Il respiro orizzontale scende da .6 a .4rem: cinque colonne fanno dieci margini interni,
   ed erano quasi cento pixel spesi in aria dove l'aria non c'era. I pulsanti passano a
   `mini`, che è la misura pensata per le azioni di RIGA — qui sono esattamente quelle. */
.tab-gradi td { padding: .6rem .4rem; }
.tab-gradi td:first-child { padding-left: 0; }
.tab-gradi td:last-child { padding-right: 0; }
.tab-gradi .g-segno, .tab-gradi .g-data, .tab-gradi .g-timbro, .tab-gradi .g-azioni { width: 1%; }
.tab-gradi .g-data { white-space: nowrap; }
.tab-gradi .g-timbro { text-align: center; }
.tab-gradi .g-azioni > div { display: flex; gap: .35rem; justify-content: flex-end; flex-wrap: nowrap; }
/* `flex: none`: senza, in stretta i due pulsanti si comprimerebbero invece di chiedere spazio
   alla colonna del nome — ed è quella del nome, che manda a capo una parola, la sola che deve
   cedere. Un pulsante schiacciato non si legge, e qui non c'è niente da guadagnarci. */
.tab-gradi .g-azioni .bottone { white-space: nowrap; flex: none; }
tbody tr:hover { background: var(--riga-hover); }
tbody tr:last-child td { border-bottom: none; }

/* Intestazioni ordinabili (elenco «Soci»): tutta la cella è cliccabile, la freccia occupa
   sempre il suo spazio (anche vuota) così la larghezza non balla quando cambia colonna
   attiva. La freccia si accende solo sull'attiva; l'hover scurisce il testo per invitare al
   clic. */
th.ord { cursor: pointer; user-select: none; white-space: nowrap; }
th.ord:hover { color: var(--text); }
th.ord.attiva { color: var(--text); }
th.ord .freccia {
  display: inline-block; width: .8em; margin-left: .25rem;
  font-size: .7rem; text-align: center; opacity: .5;
}
th.ord.attiva .freccia { opacity: 1; }

/* --- controlli ---------------------------------------------------------- */

/* La famiglia dei controlli. input, select e textarea condividono con CampoData l'altezza
   (min 2.5rem, così vanno in fila col campo data), il raggio (--raggio-s) e — sul focus —
   l'anello morbido hanko (box-shadow + accent-tenue) al posto dell'outline netto.

   Caselle e radio sono fuori da TUTTA la regola, non solo dall'altezza (§27 ago). Prima
   l'esclusione stava solo sul `min-height` qui sotto, e la conseguenza vera era `width: 100%`:
   un radio grezzo misurava 859 px — tutta la riga — e mandava la sua etichetta a capo su tre
   righe; una casella dentro una riga flex si prendeva lo spazio di tutti gli altri elementi,
   che restavano a schermo larghi ZERO. Bordo, padding e sfondo il browser li ignora già sui
   controlli nativi (misurato: border 0px, padding 0px), quindi la larghezza era l'unica cosa
   che arrivava davvero — ed era quella sbagliata.

   Nessuno ci era cascato prima perché il design system ha i suoi componenti e quasi tutto li
   usa: le liste multi-scelta vanno con `Spunta`, gli on/off singoli con `Interruttore`. Questa
   riga esiste perché chi scriverà il prossimo input grezzo non ricada nella stessa buca. */
input:not([type="checkbox"]):not([type="radio"]), select, textarea {
  font-family: var(--sans);
  font-size: .92rem;
  padding: .5rem .65rem;
  border: 1px solid var(--border);
  border-radius: var(--raggio-s);
  background: var(--card);
  color: var(--text);
  width: 100%;
  min-height: 2.5rem;
}
/* Focus: l'anello morbido di CampoData (.campo-data:focus-within), non l'outline netto. */
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tenue);
}
/* Disabilitato: si spegne come .campo-data.dis — fondo tenue, testo muto, non cliccabile.

   `background-COLOR`, e non l'abbreviazione `background` (§28 ago). L'abbreviazione azzera tutto
   quello che non nomina, quindi si portava via anche il `background-repeat: no-repeat` del chevron
   qui sotto — e con specificità 0-1-1 batteva `select` (0-0-1), che è dove il no-repeat sta. Al
   buio l'immagine tornava lo stesso da `html[data-theme="dark"] select` (0-1-2, che vince su
   tutti e due): immagine sì, ripetizione sì, e il chevron si affiancava a sé stesso venti volte
   per la larghezza del controllo. In chiaro lo stesso difetto era invisibile e opposto —
   l'immagine non tornava affatto, e il select spento restava senza freccia.

   È la SECONDA volta che un'abbreviazione di questo foglio costa un pomeriggio: il 26 ago era la
   regola globale `input, select, textarea` che rompeva il modulo delle chiusure. Non si cura
   alzando la specificità di `select` né con un `!important` — quello nasconde la trappola invece
   di toglierla, e la lascia armata per il prossimo. Si cura nominando la proprietà che si voleva
   davvero cambiare. */
input:disabled, select:disabled, textarea:disabled {
  background-color: var(--page-tenue); color: var(--muted); cursor: not-allowed;
}

/* Select: via la freccia del sistema (appearance:none), mettiamo la NOSTRA — un chevron SVG
   come background-image (data-URI, tratto in --muted), con spazio a destra così il testo non
   ci finisce sotto. La tendina resta NATIVA: appearance:none veste solo la scatola, non il
   menu, che su mobile è quello di sistema (il migliore). Nessuna tendina custom. */
select {
  appearance: none; -webkit-appearance: none;
  padding-right: 2.1rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%236B6E73' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .7rem center;
  background-size: 1.05rem;
  cursor: pointer;
}
/* Il chevron è "cotto" nel data-URI, quindi il suo colore non segue il token: al buio lo si
   riscrive col --muted scuro (tema manuale e "di sistema"), così resta leggibile sulla carta scura. */
html[data-theme="dark"] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%2397968F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}
@media (prefers-color-scheme: dark) {
  html[data-theme="system"] select,
  html:not([data-theme]) select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%2397968F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  }
}

label { display: block; font-size: .82rem; color: var(--muted); margin-bottom: .3rem; }
.campo { margin-bottom: .9rem; }

/* CampoData — un solo campo data (componente CampoData.razor, mockup budopass_campo_data.html).
   La veste è nostra; al clic si apre un CALENDARIO nostro (.cd-pop qui sotto), tematizzato dai token
   → leggibile in chiaro e in scuro. Prima si apriva il picker del SISTEMA (un <input type=date>
   trasparente sotto la veste): su ROM che forzano lo scuro ignorando color-scheme i giorni finivano
   chiari su fondo chiaro, invisibili. Altezza e raggio come gli <input> del form, così cade in fila
   con gli altri campi senza stonare. */
.campo-data {
  position: relative;
  display: flex; align-items: center; gap: .55rem;
  min-height: 2.5rem; padding: 0 .7rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--raggio-s);
  cursor: pointer;
  transition: border-color .12s, box-shadow .12s;
}
.campo-data .val { flex: 1; font-size: .92rem; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Stato vuoto: nome dedicato (non `.vuoto`, che è la utility globale per liste/tabelle
   vuote e porterebbe padding 2.5rem — gonfiava il campo solo quando era vuoto). */
.campo-data .val.senza-valore { color: var(--muted); }
.campo-data .cal { width: 18px; height: 18px; flex: none; color: var(--muted); display: inline-flex; }
.campo-data .cal svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.campo-data:hover { border-color: var(--muted); }
/* focus / calendario aperto: l'anello segue l'accento, come gli altri campi (.auth .campo input:focus). */
.campo-data:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tenue); }
.campo-data:focus-within .cal { color: var(--accent); }
/* errore: vira il campo, non solo il testo sotto (§ mockup). */
.campo-data.err { border-color: var(--err); background: var(--err-bg); }
.campo-data.err .cal { color: var(--err); }
/* disabilitato: si spegne e non è cliccabile. */
.campo-data.dis { background: var(--page-tenue); border-color: var(--border); cursor: not-allowed; }
.campo-data.dis .val { color: var(--muted); }
/* ✕ per svuotare (solo con un valore e se non obbligatorio). Sta SOPRA lo scatto (z-index) così il
   suo clic svuota senza aprire il calendario. */
.campo-data .x { position: relative; z-index: 2; width: 18px; height: 18px; flex: none; padding: 0; border: 0; border-radius: 50%; background: var(--page-tenue); color: var(--muted); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
.campo-data .x:hover { color: var(--text); }
.campo-data .x svg { width: 11px; height: 11px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; }
/* Lo scatto: un <button> trasparente che copre tutta la scatola e apre/chiude il popover. INTERCETTA
   i clic (a differenza del vecchio <input> nascosto) ma resta invisibile e focalizzabile da tastiera.
   L'anello di focus lo disegna .campo-data:focus-within; qui niente outline proprio. */
.campo-data .cd-scatto { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; -webkit-appearance: none; appearance: none; }
.campo-data .cd-scatto:focus { outline: none; }
.campo-data.dis .cd-scatto { cursor: not-allowed; }

/* ── Il CALENDARIO nostro (popover) ─────────────────────────────────────────────────────────────
   Tutti i colori vengono SOLO dai token (--card/--text/--muted/--border/--accent/--accent-tenue,
   hover --riga-hover): così è corretto in ogni tema/skin, chiaro e scuro — è il punto di tutto.
   Niente colori cablati. Misure/forme dal mockup docs/mockup_campo_data_calendario.html. */
.cd-pop {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 30;
  width: 100%; min-width: 17rem; max-width: calc(100vw - 1.5rem);
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--raggio); padding: 12px;
  box-shadow: 0 12px 30px rgba(0, 0, 0, .18);
  cursor: default;
}
.cd-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.cd-nav {
  width: 32px; height: 32px; flex: none; border-radius: 9px;
  border: 1px solid var(--border); background: transparent; color: var(--text);
  display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 16px; line-height: 1;
}
.cd-nav:hover { background: var(--riga-hover); }
.cd-nav:disabled { opacity: .4; cursor: not-allowed; }
.cd-nav:disabled:hover { background: transparent; }
.cd-titolo {
  flex: 1; text-align: center; font-weight: 700; font-size: .95rem; color: var(--text);
  border: 0; background: transparent; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: .3rem;
  border-radius: 9px; padding: .3rem .2rem;
}
.cd-titolo:hover { background: var(--riga-hover); }
.cd-titolo.statico { cursor: default; }
.cd-titolo.statico:hover { background: transparent; }
.cd-titolo .cd-cv { color: var(--muted); font-size: .8rem; }
.cd-dow { display: grid; grid-template-columns: repeat(7, 1fr); margin-bottom: 4px; }
.cd-dow span { text-align: center; font-size: .66rem; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; padding: 4px 0; }
.cd-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cd-grid:focus { outline: none; }
.cd-grid:focus-visible { outline: none; }
.cd-day {
  aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
  font-size: .85rem; color: var(--text); border-radius: 50%; cursor: pointer; user-select: none;
}
.cd-day:hover { background: var(--riga-hover); }
.cd-day.mut { color: var(--muted); opacity: .45; }
/* selezionato = cerchio d'accento con testo sopra l'accento. */
.cd-day.sel { background: var(--accent); color: var(--accent-on); font-weight: 700; }
.cd-day.sel:hover { background: var(--accent); }
/* oggi = anello d'accento. */
.cd-day.today { box-shadow: inset 0 0 0 1.5px var(--accent); }
/* attivo (aria-activedescendant, quello che le frecce spostano) = fondo tenue d'accento. */
.cd-day.act:not(.sel) { background: var(--accent-tenue); }
.cd-day.dis { color: var(--muted); opacity: .35; cursor: not-allowed; }
.cd-day.dis:hover { background: transparent; }
/* griglia anni (salto rapido): stessa logica, celle più larghe. */
.cd-years { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.cd-yr { padding: .55rem 0; text-align: center; font-size: .85rem; border-radius: 9px; color: var(--text); cursor: pointer; user-select: none; }
.cd-yr:hover { background: var(--riga-hover); }
.cd-yr.sel { background: var(--accent); color: var(--accent-on); font-weight: 700; }
.cd-yr.sel:hover { background: var(--accent); }
.cd-yr.dis { color: var(--muted); opacity: .35; cursor: not-allowed; }
.cd-yr.dis:hover { background: transparent; }

/* Il primario è l'ACCENTO (hanko), non il sumi: "Nuovo", "Salva", "Pubblica", "Aggiungi"
   nascono rossi. Il sumi resta testo/struttura. Il secondario è .quieto (ghost); le azioni
   distruttive/neutre usano .quieto, mai un pieno. */
.bottone {
  font-family: var(--sans);
  font-size: .9rem;
  font-weight: 600;
  /* Altezza della famiglia: va in fila coi campi e col campo data (min 2.5rem); inline-flex
     centra il testo (e un'eventuale icona) tanto su <button> quanto su <a class="bottone">. */
  min-height: 2.5rem;
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  padding: .5rem .9rem;
  border-radius: var(--raggio-s);
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--accent-on);
  cursor: pointer;
  transition: filter .12s, background .12s, border-color .12s, box-shadow .12s;
}
/* Primario: hover più netto — un filo più acceso e un lieve stacco dalla pagina. */
.bottone:hover { filter: brightness(1.06); box-shadow: var(--ombra); }
.bottone:disabled { opacity: .5; cursor: not-allowed; filter: none; box-shadow: none; }
.bottone.accento { background: var(--accent); border-color: var(--accent); color: var(--accent-on); }
/* Verde affermativo per un'approvazione che «crea» (l'apertura di un ente lato piattaforma):
   il verde di stato distingue l'atto positivo dall'accento del brand. */
.bottone.ok { background: var(--ok); border-color: var(--ok); color: #fff; }
/* Secondario «quieto» (ghost): hover che si riempie di --riga-hover e alza il bordo a --muted,
   così si stacca senza diventare un pieno. */
.bottone.quieto { background: transparent; color: var(--text); border-color: var(--border); }
.bottone.quieto:hover { background: var(--riga-hover); border-color: var(--muted); filter: none; box-shadow: none; }
/* Tono distruttivo (elimina definitivo): su .quieto è solo il testo in rosso — resta defilato;
   su .accento è il pieno rosso della conferma nel modale. Il colore di stato --err non segue
   l'accento del brand, così «elimina» è rosso con qualsiasi tema. */
/* Azioni di RIGA: la famiglia .bottone, ma alla misura di una riga d'elenco. I 2,5rem della
   misura piena servono a stare in fila coi campi di un modulo; dentro una riga di lista, con
   due o tre azioni accanto, peserebbero più del contenuto che accompagnano. */
.bottone.mini { min-height: 1.95rem; padding: .25rem .6rem; font-size: .78rem; font-weight: 500; }
.bottone.quieto.danno { color: var(--err-text); border-color: var(--err); }
.bottone.quieto.danno:hover { background: var(--err-bg); border-color: var(--err); }
.bottone.accento.danno { background: var(--err); border-color: var(--err); color: #fff; }

/* --- badge di stato a pastiglia -----------------------------------------
   §3.1: NON seguono l'accento, devono restare leggibili con qualsiasi tema. */

.badge {
  display: inline-block;
  font-size: .74rem;
  padding: .15rem .5rem;
  border-radius: 999px;
  border: 1px solid transparent;
  white-space: nowrap;
  /* Due badge adiacenti in Razor non hanno spazio fra loro: senza questo si
     leggerebbero attaccati ("minoresenza account"). */
  margin: 0 .25rem .15rem 0;
}
.badge.ok { background: var(--ok-bg); color: var(--ok-text); border-color: var(--ok); }
.badge.attesa { background: var(--warn-bg); color: var(--warn-text); border-color: var(--warn); }
.badge.neutro { background: var(--page-tenue); color: var(--muted); border-color: var(--border); }
/* L'accento e' riservato al caso che tocca TUTTI (una chiusura di tutto il dojo, §27 ago):
   in un elenco dove la maggior parte delle righe riguarda un corso o due, quella che li ferma
   tutti si deve riconoscere senza leggerla. */
.badge.accento { background: var(--accent-tenue); color: var(--accent-text); border-color: var(--accent); }
.badge.errore { background: var(--err-bg); color: var(--err-text); border-color: var(--err); }
/* Anomalie di appartenenza (§«Elenco soci — impianto finale», 9 ago): «Affiliazione scaduta»
   malva, «Nessun corso» ardesia. Toni pastello fissi (come nel mockup render-verificato), a sé
   rispetto alle famiglie ok/attesa/errore. */
.badge.aff { background: #ECE1EC; color: #7a4a72; }
.badge.nocorso { background: #E6EAEF; color: #46566e; }
/* I flag STATO dell'elenco soci portano un'icona a tratto prima del testo (§2b, stile A): il
   badge diventa flex SOLO quando contiene un'icona (:has), così gli altri badge non cambiano.
   L'icona eredita il colore del testo (currentColor) e si dimensiona sul font del badge. */
.badge:has(svg) { display: inline-flex; align-items: center; gap: .28rem; }
.badge svg { width: 1.15em; height: 1.15em; flex: none; }
/* Una pastiglia che segue del TESTO sulla STESSA riga vuole aria a sinistra (§26 ago). Il margine
   di `.badge` è solo a destra — serve a staccare due pastiglie adiacenti — quindi dopo un nome
   («Aikido adulti» + «scaduta») restava il solo spazio della parola, e la pastiglia si legge
   appiccicata a quello che descrive. Un `:first-child` non servirebbe: un nodo di testo non conta
   come figlio, e la regola non scatterebbe mai proprio qui.

   `.risalto` non è più in elenco: la pastiglia della tessera è passata SOTTO il valore (v. sopra,
   `.det-dati .badge`), che è il rimedio migliore quando attorno c'è una fila di valori da tenere
   allineati. Qui resta il caso in cui la pastiglia sta in riga per forza, accanto a un nome. */
.corso-nome > .badge { margin-left: .4rem; }

/* Timbro hanko 印: segno di verifica accanto ai verificati (§3.1). Cerchio
   d'accento col carattere, come il bollo del maestro. */
.timbro {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px; height: 24px;
  flex: 0 0 24px;
  border: 1.5px solid var(--accent);
  border-radius: 50%;
  color: var(--accent);
  font-family: var(--jp);
  font-size: .8rem;
  line-height: 1;
  vertical-align: middle;
}
.timbro.piccolo { width: 20px; height: 20px; flex-basis: 20px; font-size: .7rem; }

/* Cintura piatta della scala gradi (ScalaGradi): lì è un campione di colore in un elenco,
   non il grado di un atleta, e il rettangolino basta. Il colore viene dal dato, quindi è
   inline; le bicolori arrivano come "#FFFFFF/#F7D046" e vanno rese come due metà. */
.cintura {
  display: inline-block;
  width: 26px; height: 12px;
  border-radius: 3px;
  border: 1px solid rgba(23,25,28,.25);
  vertical-align: middle;
  margin-right: .45rem;
}

/* Il segno del grado nel budopass dell'atleta (SegnoGrado): UN solo token, in SVG, come
   nell'app (§10). I colori sono variabili var(--cintura-*), così bianco/nero e il contorno
   seguono il tema senza ridisegnare — la nera diventa un carbone al buio.

   Il token è largo abbastanza da leggere la tinta della barra, non un francobollo: al buio il
   carbone del dan (#413C34) e il marrone del 1° kyu (#6B4423) hanno luminanze vicine, e su una
   banda di pochi pixel si confonderebbero. Il viewBox è quadrato, quindi width capa anche
   l'altezza. */
.segno .token-svg { width: 46px; height: auto; display: block; }
/* Non scoped a .segno: il glifo deve centrarsi ovunque SegnoGrado è usato — anche
   nell'intestazione della scheda socio, che avvolge il segno in un div senza classe .segno.
   Senza queste regole il glifo cade su text-anchor:start / baseline alfabetica (spostato a
   destra e in basso). La dimensione resta relativa al viewBox, quindi scala col token. */
.token-glifo {
  font-family: var(--jp);
  font-weight: 700;
  font-size: 19px;
  text-anchor: middle;
  dominant-baseline: central;
}

/* --- vista allievo: righe budopass e schede ente (§4.2) ----------------- */

/* Avatar a iniziali: il logo/foto arriva con la Fase 5, per ora le iniziali. */
.iniziali {
  width: 44px; height: 44px;
  flex: 0 0 44px;
  border-radius: 50%;
  background: var(--accent-tenue);
  color: var(--accent-text);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
/* Logo dell'ente al posto delle iniziali (catalogo «Cerca un ente»): riempie il cerchio. */
.iniziali img { width: 100%; height: 100%; object-fit: cover; }
.testa-carta { display: flex; align-items: center; gap: 1rem; }
.testa-carta .nome { font-size: 1.15rem; font-weight: 600; }

/* Il cartello del check-in non si compone più qui: è un PDF A4 che disegna il server (§10,
   20 ago), e la pagina lo SCARICA invece di mandare in stampa il browser. Con lui se ne sono
   andate le classi .cartello* e il foglio di stile @media print che serviva solo a quella
   stampa — insieme a .no-stampa, che esisteva per nascondere i comandi mentre si stampava. */

/* Check-in pubblico, esito «codice sconosciuto» (§10, 20 ago): il resto della schermata parla
   col vocabolario di pagina (carta, risalto, etichetta, bottone, badge ok), qui servono solo
   due cose che non c'erano. Il divisorio «oppure» stacca il caso frequente — ho sbagliato a
   digitare — dalle due porte per chi invece non ha sbagliato niente; e la barra d'accento a
   sinistra dice a colpo d'occhio che quelle due sono STRADE, non altri avvisi d'errore. */
.ck-oppure {
  display: flex; align-items: center; gap: .6rem; margin: 1rem 0 .8rem;
  color: var(--muted); font-size: .7rem; letter-spacing: .1em; text-transform: uppercase;
}
.ck-oppure::before, .ck-oppure::after { content: ""; flex: 1; height: 1px; background: var(--border); }

.carta.porta { padding: .9rem 1rem; margin-bottom: .6rem; border-left: 3px solid var(--accent); }
/* Chi socio non è: stessa forma, tono neutro — è una porta legittima, non quella principale. */
.carta.porta.ospite { border-left-color: var(--muted); }

/* La testa della card di ricerca è apribile → scheda dell'ente: cursore, hover e un chevron. */
.testa-carta.apribile { cursor: pointer; border-radius: var(--raggio-s); margin: -.2rem; padding: .2rem; }
.testa-carta.apribile:hover { background: var(--riga-hover); }
.testa-carta.apribile .apribile-chev { margin-left: auto; color: var(--muted); font-size: 1.3rem; }

/* La scheda dell'ente (pagina di valutazione): copertina piena in cima (banner stile Facebook),
   logo a cavallo del bordo in basso a sinistra, poi identità + azioni e il corpo. La carta perde
   il padding e taglia i bordi così la copertina è flush; testa e corpo portano il loro. */
.scheda-ente { max-width: 640px; padding: 0; overflow: hidden; }
.scheda-cover {
  position: relative; aspect-ratio: 16 / 9; overflow: hidden;
  background: radial-gradient(120% 140% at 80% -20%, rgba(255,255,255,.14), transparent 55%),
              linear-gradient(120deg, var(--accent-tenue), var(--accent-banda));
}
.scheda-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Copertina assente: banda washi neutra col kanji sfumato — mai un buco né un'immagine rotta. */
.scheda-cover.vuota { background: linear-gradient(120deg, var(--page-tenue), var(--accent-tenue)); }
.scheda-cover-wm {
  position: absolute; right: 1.1rem; bottom: .4rem; font-family: var(--jp);
  font-size: 7rem; line-height: 1; color: var(--accent-text); opacity: .12; user-select: none;
}

.scheda-testa {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 1rem;
  padding: 0 1.25rem 1rem; position: relative;
}
.scheda-logo {
  flex: 0 0 auto; width: 96px; height: 96px; margin-top: -48px; border-radius: 18px; overflow: hidden;
  background: var(--card); border: 4px solid var(--card); box-shadow: 0 6px 16px rgba(0,0,0,.18);
  display: grid; place-items: center; color: var(--accent-text); font-family: var(--jp); font-size: 2.2rem;
}
.scheda-logo img { width: 100%; height: 100%; object-fit: cover; }
.scheda-ident { flex: 1 1 12rem; min-width: 0; padding-bottom: .2rem; }
.scheda-ident h1 { margin: 0; font-size: 1.5rem; line-height: 1.15; }

.scheda-descr { margin: .4rem 0 0; color: var(--text); line-height: 1.55; white-space: pre-line; }

/* Larghezze strette: la copertina resta 16:9 (si abbassa da sé riducendosi la larghezza), logo
   più piccolo e kanji più contenuto, così la testata regge lo stesso. */
@media (max-width: 560px) {
  .scheda-cover-wm { font-size: 4.5rem; }
  .scheda-logo { width: 72px; height: 72px; margin-top: -36px; font-size: 1.7rem; }
  .scheda-ident h1 { font-size: 1.3rem; }
}
.link-indietro { color: var(--muted); text-decoration: none; font-size: .9rem; }
.link-indietro:hover { color: var(--text); }

/* ===== Impostazioni ente: testata copertina + logo EDITABILE (matite) =============
   Riusa la veste della vetrina (.scheda-ente / .scheda-cover / .scheda-testa / .scheda-logo);
   aggiunge le matite — un <label> che avvolge l'InputFile nascosto: il click apre il selettore
   file, cioè gli stessi upload di prima — e la pill di moderazione, ora sull'immagine stessa. */
/* Stessa larghezza della vetrina (640px, ereditati da .scheda-ente): così la cover delle
   impostazioni ha la stessa forma 16:9 di quella pubblica — è la stessa cover dello stesso dojo. */
.imp-testata { margin-bottom: 1.25rem; }

/* Matita copertina: pastiglia scura in alto a destra sul banner. */
.edit-cover {
  position: absolute; top: .8rem; right: .8rem; z-index: 2;
  display: inline-flex; align-items: center; gap: .4rem; cursor: pointer;
  background: rgba(20, 17, 14, .55); color: #fff; border: 1px solid rgba(255, 255, 255, .28);
  border-radius: 9px; padding: .4rem .7rem; font-size: .82rem; font-weight: 600;
  backdrop-filter: blur(2px);
}
.edit-cover:hover { background: rgba(20, 17, 14, .72); }
.edit-cover svg { width: 15px; height: 15px; }

/* Stato di moderazione sulla copertina, in alto a sinistra (riusa .mod-badge per i colori). */
.imp-testata .modpill { position: absolute; top: .8rem; left: .8rem; z-index: 2; }

/* Il logo regge la matita a cavallo dell'angolo: overflow visibile e la foto si arrotonda da
   sé, così la pastiglia non viene tagliata (il contenitore vetrina clippa, qui no). */
.imp-logo { position: relative; overflow: visible; }
.imp-logo img { border-radius: 14px; }
.edit-logo {
  position: absolute; right: -6px; bottom: -6px; width: 32px; height: 32px; cursor: pointer;
  border-radius: 50%; background: var(--accent); color: #fff; border: 3px solid var(--card);
  display: grid; place-items: center; box-shadow: 0 2px 6px rgba(0, 0, 0, .2);
}
.edit-logo:hover { filter: brightness(1.06); }
.edit-logo svg { width: 14px; height: 14px; }

/* Note di rifiuto e nota di moderazione: allineate al padding di testa/corpo della vetrina. */
.imp-testata-note { padding: 0 1.25rem; }
.imp-testata-nota { padding: 0 1.25rem 1.1rem; margin: .3rem 0 0; }

/* «Le mie affiliazioni»: una card per (ente × disciplina), stato in badge, dati sotto. */
/* L'identità dell'ente (logo + nome) è un link alla vetrina: occupa la riga come prima, lo
   stato resta accanto fuori dal link. */
/* La riga puntata da una notifica di esito (?ev=): un alone d'accento, non un colore pieno. */

.riga-budopass {
  display: flex;
  align-items: center;
  gap: .9rem;
  padding: .7rem 0;
  border-bottom: 1px solid var(--border);
}
.riga-budopass:last-child { border-bottom: none; }
.riga-budopass .segno {
  flex: 0 0 52px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .25rem;
}
.riga-budopass .glifo { font-family: var(--jp); font-size: 1.05rem; line-height: 1; color: var(--text); }
.riga-budopass .corpo { flex: 1; min-width: 0; }
.riga-budopass .titolo { font-size: 1rem; font-weight: 500; }
.riga-budopass .coda { margin-left: auto; flex: 0 0 auto; padding-left: .5rem; display: flex; flex-direction: column; align-items: flex-end; gap: .3rem; }

/* Riga-grado cliccabile → scheda esame (§2 ago): il link "steso" copre la riga; la coda torna
   sopra così i suoi bottoni (ratifica/rimuovi) restano premibili senza annidarli in un <a>. */
.sg-riga { position: relative; }
.sg-riga:hover { background: var(--page-tenue); }
.sg-riga-link { position: absolute; inset: 0; z-index: 1; }
.sg-riga .coda { position: relative; z-index: 2; }

/* Azione «Rimuovi» di una voce dichiarata (storia dichiarata): testo discreto, rosso al passaggio. */
.rimuovi-voce { background: none; border: 0; padding: 0; cursor: pointer; font-size: .8rem; color: var(--muted); text-decoration: underline; }
.rimuovi-voce:hover { color: #b5382c; }

/* Avviso richiudibile (es. l'invito ad aprire un ente): la X in alto a destra. */
.carta.richiudibile { position: relative; }
.chiudi-avviso {
  position: absolute;
  top: .6rem; right: .6rem;
  width: 26px; height: 26px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--muted);
  border-radius: 50%;
  cursor: pointer;
  font-size: .85rem;
  line-height: 1;
}
.chiudi-avviso:hover { background: var(--riga-hover); color: var(--text); }

/* La versione ridotta dell'invito, quando è stato chiuso: un link discreto ma sempre lì. */
.invito-quieto { margin-top: 1.5rem; font-size: .88rem; }

/* Mini-statistiche di frequenza nella scheda ente. */
.mini-stat { display: flex; gap: 1.5rem; flex-wrap: wrap; margin-top: .8rem; }
.mini-stat .voce .n { font-weight: 600; font-size: 1.25rem; line-height: 1.1; }
.mini-stat .voce .et { color: var(--muted); font-size: .78rem; }

/* --- chip di disciplina: selezione (apertura ente, affiliazione) e filtro
   (ricerca enti). Bordo tondo, kanji + nome, accesa = accento + spunta. Come le
   chip dell'app (EntiPage), qui in HTML. -------------------------------------- */
.chips { display: flex; flex-wrap: wrap; gap: .5rem; }
.chip {
  display: inline-flex; align-items: center; gap: .35rem; width: auto;
  font-family: var(--sans); font-size: .85rem; font-weight: 500;
  padding: .4rem .8rem; border-radius: 999px;
  border: 1.4px solid var(--border); background: transparent; color: var(--muted);
  cursor: pointer; white-space: nowrap;
}
.chip .kanji { font-size: .8rem; }
.chip:hover { border-color: var(--accent); color: var(--text); }
.chip.on { border-color: var(--accent); background: var(--accent-tenue); color: var(--accent-text); }
/* La spunta dell'accesa: sempre presente nel markup, si vede solo da accesa, così la
   larghezza non balla al tocco. */
.chip .spunta { visibility: hidden; }
.chip.on .spunta { visibility: visible; color: var(--accent); }

/* Il chip «N prove» dello storico: dietro di lui le miniature non sono ancora state scaricate.
   Riusa il chip tondo dei filtri — è la stessa cosa, un interruttore leggero — e da acceso dice
   che la card è aperta. Il glifo prende la misura del testo e il colore da currentColor. */
.chip.chip-prove svg { width: 1.05em; height: 1.05em; flex: none; }

/* La barra dello storico ratifiche: ricerca a sinistra, «N di Totale» spinto a destra. La
   casella non prende tutta la larghezza — un campo lungo mezzo schermo per due parole di
   ricerca promette un modulo, non un filtro. */
.storico-barra {
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  margin-bottom: .8rem;
}
.storico-cerca { width: min(22rem, 100%); margin: 0; }
.storico-barra .etichetta { margin-left: auto; white-space: nowrap; }

/* Avviso ambra: la nota della fase pilota sotto le discipline. I colori di stato
   (warn) non seguono l'accento, come i badge. */
.avviso.ambra { background: var(--warn-bg); color: var(--warn-text); border-color: var(--warn); }

/* Messaggio d'errore inline sotto un campo (es. "scegli una disciplina"). */
.campo-errore { color: var(--err-text); font-size: .82rem; margin: .45rem 0 0; }

/* --- allegati/prove: tessere con tipo, nome e rimozione, più la tessera "aggiungi"
   tratteggiata che nasconde l'<input file>. Immagini + PDF (apertura ente) o solo
   immagini (prove d'affiliazione). ------------------------------------------- */
.allegati { display: flex; flex-wrap: wrap; gap: .6rem; }
.allegato {
  position: relative; width: 84px; height: 98px; padding: .45rem;
  border: 1px solid var(--border); border-radius: var(--raggio-s);
  background: var(--page-tenue);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .3rem;
  text-align: center; overflow: hidden;
}
.allegato .tipo { font-size: .72rem; font-weight: 700; letter-spacing: .06em; color: var(--muted); }
.allegato .nome { font-size: .68rem; color: var(--muted); line-height: 1.15; word-break: break-word;
  max-height: 2.3em; overflow: hidden; }
.allegato .rimuovi {
  position: absolute; top: 3px; right: 3px; width: 20px; height: 20px; padding: 0;
  border: none; border-radius: 50%; background: rgba(0,0,0,.5); color: #fff;
  font-size: .68rem; line-height: 1; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.allegato.aggiungi { border-style: dashed; cursor: pointer; color: var(--muted); font-size: 1.5rem; font-weight: 300; }
.allegato.aggiungi:hover { border-color: var(--accent); color: var(--accent-text); }
.allegato.aggiungi input { display: none; }
/* Le tessere che portano un GLIFO invece del carattere «＋» (Icone.Media per «aggiungi una
   foto», Icone.Ics per la ✕): l'SVG nasce 18×18, che nel bottoncino da 20 di lato riempirebbe
   tutto. Si ridimensiona qui, una volta, invece di passare una misura a ogni chiamata. */
.allegato.aggiungi svg { width: 26px; height: 26px; }
.allegato .rimuovi svg { width: 12px; height: 12px; }

/* Miniatura di una prova (immagine allegata): riempie il box 84×98, la ✕ resta sopra. */
.allegato .prova-thumb { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Miniatura cliccabile lato gestore: il box è un bottone, senza stile nativo. */
.allegato.prova-apri { appearance: none; cursor: pointer; }
/* Le prove «in grande» sul dettaglio della richiesta: chi esamina le guarda, non le sbircia. */
.allegato.grande { width: 168px; height: 190px; }

/* Il perché di una ratifica non accolta, sotto il grado dichiarato: si nota senza gridare. */
.rifiuto-ratifica { color: var(--warn-text); }

/* L'esito della ratifica sotto il grado dichiarato: una PASTIGLIA tinta, non una riga di testo
   colorato. È la risposta alla domanda per cui si apre la pagina, e deve staccarsi dai metadati
   del grado invece di accodarsi a loro come una terza etichetta.

   Fondo --*-bg e testo --*-text: la stessa coppia dei badge di stato, nessun colore nuovo, ed
   entrambe già ridefinite per tema — quindi la pastiglia segue chiaro/scuro da sé. Il glifo
   prende il colore da `currentColor` e non va ritinto a parte. */
.esito-ratifica {
  display: flex; align-items: flex-start; gap: .4rem;
  margin-top: .45rem; padding: .4rem .6rem;
  border-radius: var(--raggio-s);
  font-size: .82rem; line-height: 1.35;
}
/* Il glifo si allinea alla PRIMA riga di testo, non al centro della pastiglia: quando c'è anche
   il motivo la pastiglia è alta due righe, e un'icona centrata finirebbe a metà fra le due. */
.esito-ratifica svg { width: 1.05em; height: 1.05em; flex: none; margin-top: .14em; }
.esito-ratifica.ok { background: var(--ok-bg); color: var(--ok-text); }
.esito-ratifica.attesa { background: var(--warn-bg); color: var(--warn-text); }
.esito-ratifica.errore { background: var(--err-bg); color: var(--err-text); }

/* Il motivo del rifiuto: seconda riga della STESSA frase, quindi dentro la stessa pastiglia e
   allineato al testo sopra. Smorzato — il rosso della pastiglia l'ha già detto. */
.esito-motivo { margin-top: .1rem; font-size: .78rem; opacity: .82; }

/* La riga di un grado dichiarato cresce in altezza (pastiglia + azioni): il segno del grado si
   allinea in ALTO, col titolo, invece di scivolare a metà di una riga alta il triplo. */
.riga-dichiarato { align-items: flex-start; }
.riga-dichiarato .segno { padding-top: .1rem; }
/* Il gettone «dichiarato» sta in linea col titolo: non deve ereditarne corpo e peso. */
.riga-dichiarato .titolo .badge { margin-left: .4rem; vertical-align: middle; font-weight: 500; }
/* Le azioni sotto la voce, in fila e non incolonnate a destra. */
.azioni-voce { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .5rem; }
/* Un glifo dentro un'azione di riga alla misura del testo che accompagna (lo spazio fra i due lo
   mette già il gap di .bottone). `currentColor` gli passa il rosso di .danno: un'emoji lo
   ignorerebbe. */
.azioni-voce .bottone svg { width: 1.05em; height: 1.05em; flex: none; }

/* La conferma della REVOCA di una ratifica (§«revoca di un grado ratificato», 24 ago), dentro la
   riga della voce e non in un modale: si sta guardando proprio quella pratica, e portarla via da
   sotto gli occhi per chiedere «sei sicuro?» costa più della conferma stessa. Tinta della coppia
   --err-bg/--err come le pastiglie di rifiuto — nessun colore nuovo, e segue il tema da sé. */
.revoca-conferma {
  margin-top: .5rem; padding: .55rem .65rem;
  border-radius: var(--raggio-s);
  background: var(--err-bg); border: 1px solid var(--err);
}
.revoca-conferma .tit { font-size: .85rem; font-weight: 700; color: var(--err-text); }
/* Il motivo è OBBLIGATORIO e lo legge l'atleta: campo a tutta larghezza, non un'appendice. */
.revoca-conferma textarea { width: 100%; margin-top: .4rem; }
.revoca-conferma .azioni-voce { margin-top: .45rem; }

/* Intestazione di gruppo dentro un elenco («In attesa di ratifica» / «Altri gradi dichiarati»):
   più piccola e più quieta di un <h2>, perché divide un elenco — non apre una sezione nuova. */
.gruppo-sez {
  font-size: .7rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); margin: 1rem .1rem .3rem;
}
.gruppo-sez:first-child { margin-top: .2rem; }

/* L'ingresso alle richieste ancora in attesa, sotto il gruppo dei gradi in attesa. Tinto
   d'ambra come le pastiglie d'attesa — è la stessa coda, vista dal lato della pratica invece
   che da quello del grado — e non un bottone accento: non è l'azione principale della pagina,
   è la scorciatoia per chi ha qualcosa in sospeso. Sparisce quando la coda si svuota. */
.ingresso-pendenti {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  margin: .2rem .1rem 0; padding: .6rem .75rem;
  border-radius: var(--raggio-s);
  background: var(--warn-bg); border: 1px solid var(--warn);
}
.ingresso-pendenti .lab { font-size: .85rem; font-weight: 700; color: var(--warn-text); }
.ingresso-pendenti .go {
  display: inline-flex; align-items: center; gap: .3rem; white-space: nowrap;
  font-size: .82rem; font-weight: 700; color: var(--accent-text); text-decoration: none;
}
.ingresso-pendenti .go svg { width: 1.05em; height: 1.05em; flex: none; }

/* L'ingresso allo STORICO delle richieste, subito sotto quello delle pendenti. Nessun fondo e
   nessun bordo: quello sopra è tinto d'ambra perché c'è qualcosa in sospeso, questo è solo una
   porta su ciò che è finito e non deve pesare uguale. Allineato a destra, dove finisce la riga
   d'ambra, così i due ingressi leggono come una cosa sola e non come due scatole. */
.ingresso-storico { display: flex; justify-content: flex-end; margin: .35rem .1rem 0; }
.ingresso-storico .go {
  display: inline-flex; align-items: center; gap: .3rem; white-space: nowrap;
  font-size: .82rem; font-weight: 600; color: var(--muted); text-decoration: none;
}
.ingresso-storico .go:hover { color: var(--accent-text); }
.ingresso-storico .go svg { width: 1.05em; height: 1.05em; flex: none; }

/* Le voci di una richiesta pendente: un elenco nudo, senza la griglia segno/corpo/coda della
   riga-budopass — qui non c'è nessun esito da incolonnare a destra, e la griglia lasciava una
   colonna vuota larga quanto un kanji. */
.voci-richiesta { margin-top: .55rem; padding-top: .5rem; border-top: 1px solid var(--border); }
.voce-richiesta { font-size: .88rem; font-weight: 500; padding: .15rem 0; }
/* La riga d'azione della richiesta: conteggio prove a sinistra, «Ritira» spinto a destra. */
.azioni-richiesta {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin-top: .6rem; padding-top: .55rem; border-top: 1px solid var(--border);
}

/* Logo e copertina della domanda d'apertura: due slot dedicati (uno quadrato, uno largo). */
.ne-immagini { display: flex; flex-wrap: wrap; gap: 1rem; align-items: flex-start; }
.ne-slot { display: flex; flex-direction: column; gap: .35rem; }
.ne-slot-tit { font-size: .78rem; color: var(--muted); }
.ne-drop {
  position: relative; display: grid; place-items: center; cursor: pointer; overflow: hidden;
  width: 96px; height: 96px; border: 1px dashed var(--border); border-radius: var(--raggio-s);
  background: var(--page-tenue); color: var(--muted);
}
.ne-drop.cover { width: 200px; height: 96px; }
.ne-drop.ha { border-style: solid; }
.ne-drop:hover { border-color: var(--accent); }
.ne-drop input { display: none; }
.ne-drop-piu { font-size: 1.6rem; font-weight: 300; }
.ne-logo-img, .ne-cover-img { width: 100%; height: 100%; object-fit: cover; }
.ne-slot-rimuovi {
  appearance: none; border: none; background: transparent; cursor: pointer;
  color: var(--muted); font-size: .74rem; text-decoration: underline; padding: 0;
}
.ne-slot-rimuovi:hover { color: var(--text); }

/* --- richieste (affiliazione + apertura ente): righe di lista e carte di dettaglio ----
   Righe pulite con chip avatar/logo e badge coerenti; nel dettaglio, etichette di sezione
   fioche, box d'aiuto in prosa e stato-vuoto dei suggerimenti. Tutto con prefisso ric- per
   non toccare le altre pagine: la .sez di Lezione, per esempio, resta un <h2> nudo. */

/* riga di elenco (una richiesta / una domanda) */
.ric-riga { display: flex; align-items: center; gap: .85rem; padding: .9rem .1rem; border-bottom: 1px solid var(--border); }
.ric-riga:last-child { border-bottom: none; }
.ric-riga-corpo { flex: 1 1 auto; min-width: 0; }
.ric-nome { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; font-weight: 600; font-size: 1.02rem; }
.ric-chips { display: flex; gap: .4rem; flex-wrap: wrap; margin-top: .45rem; }

/* chip avatar (iniziali del socio) e chip logo (iniziali dell'ente, kanji-friendly).
   Nel pilota non c'è immagine a livello d'elenco: due lettere si distinguono, due
   rettangoli grigi no (come Iniziali). */
.ric-av, .ric-logo {
  flex: 0 0 auto; width: 2.75rem; height: 2.75rem; border-radius: var(--raggio-s);
  display: grid; place-items: center; font-weight: 700; font-size: .95rem;
}
.ric-av { background: var(--accent); color: var(--accent-on); }
.ric-logo {
  background: var(--card); border: 1px solid var(--border);
  color: var(--accent-text); font-family: var(--jp); font-size: 1.15rem;
  box-shadow: 0 1px 3px rgba(0,0,0,.06);
}
.ric-av.grande, .ric-logo.grande { width: 3.5rem; height: 3.5rem; }
.ric-av.grande { font-size: 1.2rem; }
.ric-logo.grande { font-size: 1.5rem; }

/* testa di dettaglio: chip + identità (nome + badge, meta sotto) */
.ric-testa { display: flex; gap: .95rem; align-items: center; }
.ric-testa .ric-id { min-width: 0; }
.ric-testa .ric-id h1 { margin: 0; font-size: 1.4rem; display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }

/* etichetta di sezione fioca (maiuscoletto), come la testa-carta ma dentro una carta */
.ric-sez { font-size: .72rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); margin: 1.15rem 0 .6rem; }
.ric-sez:first-child { margin-top: 0; }

/* aiuto in prosa (a cosa serve collegare) e nota di chiusura */
.ric-aiuto { font-size: .86rem; color: var(--text); line-height: 1.55; margin: .1rem 0 .85rem; }
.ric-nota { font-size: .8rem; color: var(--muted); line-height: 1.5; margin-top: .65rem; }

/* messaggio del richiedente, in box morbido */
.ric-msg { background: var(--page-tenue); border: 1px solid var(--border); border-radius: var(--raggio-s); padding: .7rem .85rem; margin-top: .3rem; white-space: pre-wrap; line-height: 1.5; }

/* stato-vuoto dei suggerimenti automatici: dice che il controllo è stato fatto */
.ric-vuoto-sugg { display: flex; align-items: center; gap: .6rem; background: var(--page-tenue); border: 1px dashed var(--border); border-radius: var(--raggio-s); padding: .7rem .85rem; font-size: .85rem; color: var(--muted); }
.ric-vuoto-sugg .ck { flex: 0 0 auto; width: 1.3rem; height: 1.3rem; border-radius: 50%; background: var(--border); color: var(--muted); display: grid; place-items: center; font-size: .78rem; }

/* riga candidato (suggerimento automatico o risultato della ricerca) */
.ric-cand { display: flex; align-items: center; gap: .7rem; padding: .6rem .1rem; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.ric-cand:last-child { border-bottom: none; }
.ric-cand-info { flex: 1 1 auto; min-width: 8rem; }
.ric-cand-info b { font-weight: 600; }
.ric-cand-info small { display: block; color: var(--muted); font-size: .78rem; margin-top: .1rem; }
.ric-cand-azioni { flex: 0 0 auto; display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; }

/* box di ricerca (la barra col campo) — parità con «Cerca un ente» */
.ric-cerca { margin-top: .3rem; }

/* --- suggerimento doppioni nell'elenco soci (§26 ago) -------------------------------
   Stessa famiglia delle .ric-* qui sopra — riconciliare due schede della stessa persona è
   lo stesso mestiere, visto dall'anagrafica invece che dalla richiesta. Tono d'AVVISO
   (--warn) e non d'errore: è un «forse», e i due fratelli Marrelli sono un caso legittimo
   in cui la risposta giusta è «no». Mai un tono che pretenda un'azione. */
.dop { border-color: var(--warn); background: var(--warn-bg); }
.dop-testa { font-size: .82rem; font-weight: 700; color: var(--warn-text); margin-bottom: .7rem; }
.dop-blocco + .dop-blocco { border-top: 1px solid var(--border); margin-top: .9rem; padding-top: .9rem; }
.dop-coppia { display: flex; gap: .7rem; flex-wrap: wrap; }
/* Le due schede una accanto all'altra e alla STESSA larghezza: confrontarle è tutto il
   lavoro che il gestore deve fare, e due riquadri di misura diversa lo fanno male. Ognuno
   è un link alla propria scheda — «vedi le due schede» sono due link, perché sono due. */
.dop-lato {
  flex: 1 1 15rem; min-width: 13rem; display: block; text-decoration: none; color: inherit;
  background: var(--card-alta); border: 1px solid var(--border); border-radius: var(--raggio-s);
  padding: .55rem .7rem;
}
.dop-lato:hover { border-color: var(--accent); }
.dop-lato b { display: block; font-weight: 600; font-size: .92rem; }
.dop-lato small { display: block; color: var(--muted); font-size: .78rem; margin-top: .1rem; }
.dop-lato .badge { margin-top: .35rem; }
.dop-azioni { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; margin-top: .6rem; }

/* elenco chiave-valore dei recapiti */
.ric-kv { display: flex; flex-direction: column; gap: .4rem; }
.ric-kv .r { display: flex; gap: .6rem; font-size: .88rem; flex-wrap: wrap; }
.ric-kv .r .k { color: var(--muted); min-width: 7rem; flex: 0 0 auto; }

/* Visore a tutto schermo di una prova (tocca-per-ingrandire, parità con l'app). */
.lightbox {
  position: fixed; inset: 0; z-index: 1000; background: rgba(0,0,0,.75);
  display: flex; align-items: center; justify-content: center; padding: 2rem; cursor: zoom-out;
}
.lightbox img { max-width: 92vw; max-height: 88vh; border-radius: var(--raggio-s); box-shadow: 0 8px 40px rgba(0,0,0,.5); }
.lightbox-chiudi {
  position: absolute; top: 1rem; right: 1rem; width: 40px; height: 40px; padding: 0;
  border: none; border-radius: 50%; background: rgba(0,0,0,.5); color: #fff; font-size: 1.1rem;
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}

/* --- tag di disciplina sulle card della ricerca enti -------------------------- */
.tags { display: flex; flex-wrap: wrap; gap: .4rem; margin: .1rem 0 .2rem; }
/* Con il logo dell'ente nel cerchio 44px della testata, la chip disciplina subito sotto lo
   sfiorava (.1rem): un po' d'aria, ma solo quando segue davvero l'header con l'avatar. */
.testa-carta + .tags { margin-top: .5rem; }
.tag {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .78rem; color: var(--muted);
  padding: .15rem .55rem; border-radius: 999px;
  border: 1px solid var(--border); background: var(--page-tenue);
}
.tag .kanji { font-size: .78rem; }

/* Piede della card ente nella ricerca: tipo a sinistra, azioni (segui + richiedi) a destra. */
.ente-fondo { display: flex; align-items: center; justify-content: space-between; gap: .6rem; margin-top: .5rem; }
.ente-fondo .bottone { flex: 0 0 auto; }
.ente-azioni { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; justify-content: flex-end; }

/* Bottone «Segui / Segui già»: bordo d'accento da spento, tinta piena da acceso. */
.segui {
  display: inline-flex; align-items: center; gap: .3rem; white-space: nowrap; cursor: pointer;
  font-family: var(--sans); font-size: .82rem; font-weight: 500;
  padding: .4rem .7rem; border-radius: var(--raggio-s);
  border: 1px solid var(--accent); background: transparent; color: var(--accent-text);
}
.segui .s { font-weight: 700; }
.segui:hover { background: var(--accent-tenue); }
.segui.on { background: var(--accent-tenue); border-color: var(--accent-tenue); color: var(--accent-text); }

/* Le due porte dell'empty-state allievo (cerca dojo / apri ente): stessa larghezza. */
.due-porte { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1rem; }
.due-porte .bottone { flex: 1 1 auto; text-align: center; }

/* Testa di sezione del budopass con l'azione «+ Aggiungi» a destra (storia dichiarata). */
.storia-testa { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.storia-testa h2 { margin: 0; }
.storia-aggiungi { font-size: .85rem; font-weight: 600; white-space: nowrap; text-decoration: none; }

/* --- selettore accento + tema (masthead / impostazioni, §3.1) ----------- */

.scelta-tema { display: flex; align-items: center; gap: .8rem; }

.accento-punti { display: inline-flex; gap: .4rem; }
.accento-punti button {
  width: 22px; height: 22px;
  flex: 0 0 22px;
  padding: 0;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
}
.accento-punti button.attivo {
  border-color: var(--text);
  box-shadow: 0 0 0 2px var(--card-alta), 0 0 0 4px currentColor;
}

.seg {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: var(--raggio-s);
  overflow: hidden;
  background: var(--card);
}
.seg button {
  font-family: var(--sans);
  font-size: .82rem;
  padding: .35rem .6rem;
  border: none;
  border-right: 1px solid var(--border);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  width: auto;
}
.seg button:last-child { border-right: none; }
.seg button.attivo { background: var(--accent); color: var(--accent-on); }

/* Marchio e nome/ruolo: condivisi dal menù dei contesti (le voci .ctx e, nella sidebar, la riga
   brandizzata non li usa — ha i suoi .brand-*). Restano qui perché il menù ne dipende. */
.menu .mk {
  flex: 0 0 30px; width: 30px; height: 30px; border-radius: 8px;
  background: var(--accent); color: var(--accent-on);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: .95rem;
  overflow: hidden;
}
/* Col logo dell'ente al posto delle iniziali (deciso 3 ago): riempie il marchio, angoli come
   il riquadro; senza logo restano le iniziali su fondo accento. */
.menu .mk img {
  width: 100%; height: 100%; object-fit: cover; border-radius: inherit;
}
.menu .cn { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.menu .cn b { font-weight: 600; font-size: .92rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.menu .cn span { font-size: .74rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chev { color: var(--muted); font-size: .7rem; }

.ico-btn {
  width: 34px; height: 34px; padding: 0; border-radius: 8px;
  border: 1px solid var(--border); background: var(--card);
  color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.ico-btn:hover { background: var(--riga-hover); color: var(--text); }
.ico-btn svg { width: 18px; height: 18px; }

/* Selettore lingua in testata (stile sito adattato alla barra): globo + sigla + ▾, come una
   pillola accanto alla campana. Il globo è a tratto (currentColor), il codice in --text. */
.lingua {
  display: inline-flex; align-items: center; gap: .35rem; height: 34px;
  padding: 0 .5rem; border-radius: 8px; border: 1px solid var(--border);
  background: var(--card); color: var(--muted); cursor: pointer; font: inherit;
}
.lingua:hover { background: var(--riga-hover); color: var(--text); }
.lingua svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 1.5; stroke-linecap: round; }
.lingua .cx { font-size: .6rem; color: var(--muted); }
.av {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--accent-tenue); color: var(--accent-text);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: .76rem;
}

/* Fondale invisibile che chiude i menù al clic fuori — niente JS per una cosa così. */
.menu-backdrop { position: fixed; inset: 0; z-index: 40; }

.menu {
  position: absolute; top: calc(100% - .25rem); z-index: 50;
  background: var(--card-alta); border: 1px solid var(--border);
  border-radius: var(--raggio); box-shadow: var(--ombra); padding: .5rem;
}
.menu-pref { right: 4rem; width: 268px; }

/* Voce del menù lingua (stile sito .langmenu a): endonimo a sinistra, ✓ dell'attiva a destra in
   accento. L'attiva in accent-text e in grassetto, come sul sito. */
.lvoce {
  display: flex; align-items: center; gap: .6rem; width: 100%;
  padding: .5rem .55rem; border: none; background: transparent;
  border-radius: var(--raggio-s); cursor: pointer; color: var(--text);
  font-family: var(--sans); font-size: .9rem; text-align: left;
}
.lvoce:hover { background: var(--riga-hover); }
.lvoce.on { color: var(--accent-text); font-weight: 700; }
.lvoce .tick { margin-left: auto; color: var(--accent); }

.menu-sez {
  padding: .55rem .5rem .2rem; font-size: 9.5px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--muted); opacity: .7;
}
.menu .seg, .menu .accento-punti, .menu .skins { margin: .1rem .4rem .5rem; }
.menu .seg { display: flex; }
.menu .seg button { flex: 1; }

.ctx {
  display: flex; align-items: center; gap: .6rem; width: 100%;
  padding: .45rem .5rem; border: none; background: transparent;
  border-radius: var(--raggio-s); cursor: pointer; text-align: left;
  color: var(--text); font-family: var(--sans);
}
.ctx:hover { background: var(--riga-hover); }
.ctx.attivo { background: var(--accent-tenue); }
.ctx .cn { flex: 1; }
.ctx .tick { color: var(--accent); font-weight: 700; }

.skins { display: flex; gap: .4rem; }
.sk {
  flex: 1; display: flex; flex-direction: column; gap: .15rem;
  padding: .45rem .4rem; border: 1px solid var(--border);
  border-radius: var(--raggio-s); background: var(--card); cursor: pointer;
  color: var(--text); font-family: var(--sans); text-align: left;
}
.sk:hover { background: var(--riga-hover); }
.sk.attivo { border-color: var(--accent); background: var(--accent-tenue); }
.sk b { font-size: .8rem; font-weight: 600; }
.sk span { font-size: .66rem; color: var(--muted); line-height: 1.2; }
.menu-sep { height: 1px; background: var(--border); margin: .3rem 0; }

/* ===== skin: quanto inchiostro sulla carta (§3.1) =====================
   Ma è il default (lo spazio vuoto: teste di sezione nude); Obi mette una fascia d'accento
   sulle teste; Sumi lava pagina e barre nell'accento. Come nell'app, si tocca solo il set di
   token e la resa delle teste — i colori di stato (ok/attesa/errore) NON cambiano mai, in
   nessuna skin né tema. */

/* Obi — la fascia d'accento sulle teste di sezione (rail, carta, menù). */
html[data-skin="obi"] .carta-titolo, html[data-skin="obi"] .menu-sez { color: var(--accent-text); opacity: 1; }
html[data-skin="obi"] .carta-titolo { border-left: 2px solid var(--accent); padding-left: .5rem; }

/* Sumi — l'inchiostro: pagina nell'accento tenue, rail e testata in accento pieno con testo
   su-accento (var(--accent-on) gestisce da sé la deroga Terra). */
html[data-skin="sumi"] { --page: var(--accent-tenue); }
html[data-skin="sumi"] .wordmark { color: var(--accent-on); }

/* --- messaggi ----------------------------------------------------------- */

.avviso {
  border-radius: var(--raggio);
  padding: .7rem .9rem;
  font-size: .9rem;
  margin-bottom: 1rem;
  border: 1px solid;
}
.avviso.errore { background: var(--err-bg); color: var(--err-text); border-color: var(--err); }
.avviso.info { background: var(--page-tenue); color: var(--muted); border-color: var(--border); }

/* --- toast avvisi (componente <Avviso>): fisso, basso al centro, sopra ogni scroll -------
   Gli avvisi transitori (validazioni, esiti) vivono qui invece che in cima alla pagina, dove
   sui form lunghi nascevano fuori campo. Errore persistente (× per chiudere), esito auto-4s.
   §«avvisi in un toast fisso» (7 ago), mockup docs/mockup_avvisi_toast.html. */
.avviso-host {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: .5rem;
  align-items: stretch;
  width: min(560px, calc(100% - 32px));
}
.avviso-toast {
  display: flex;
  align-items: flex-start;
  gap: .7rem;
  padding: .75rem .75rem .75rem .9rem;
  border-radius: 12px;
  border: 1px solid;
  box-shadow: 0 6px 16px rgba(14, 15, 18, .14), 0 2px 6px rgba(14, 15, 18, .10);
  animation: avviso-su .18s ease-out;
}
@keyframes avviso-su {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.avviso-ico {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: .82rem;
  margin-top: 1px;
  color: #fff;
}
.avviso-corpo { flex: 1; min-width: 0; font-size: .88rem; line-height: 1.4; }
.avviso-x {
  flex: 0 0 auto;
  border: none;
  background: transparent;
  color: inherit;
  opacity: .55;
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
  margin: -2px -2px 0 0;
}
.avviso-x:hover { opacity: .9; }
.avviso-toast.errore { background: var(--err-bg); color: var(--err-text); border-color: var(--err); }
.avviso-toast.errore .avviso-ico { background: var(--err); }
.avviso-toast.esito { background: var(--ok-bg); color: var(--ok-text); border-color: var(--ok); }
.avviso-toast.esito .avviso-ico { background: var(--ok); }

.vuoto { text-align: center; color: var(--muted); padding: 2.5rem 1rem; }
.vuoto .grande { font-weight: 600; font-size: 1.1rem; color: var(--text); margin-bottom: .3rem; }

/* Il vuoto di una SEZIONE, che non è il vuoto di una carta (28 ago). `.vuoto` qui sopra è lo
   stato a carta intera: centrato e con il respiro di una pagina, giusto quando non c'è proprio
   niente da mostrare («nessuna chiusura», «nessun socio»). Dentro un elenco a sezioni è
   sbagliato due volte: centra il testo sotto un titolo allineato a sinistra, e gli dà il vuoto
   di una pagina per dire che manca una manciata di righe. Su «Non ci sarò (0)» il trattino
   finiva in mezzo alla carta e sembrava fuori posto — ed è così che è stato segnalato.

   Quindi: allineato dove sarebbero cominciate le righe che sostituisce (`.6rem`, il padding di
   una `td`) e alto come una riga, non come una pagina. La tinta resta quella di `.vuoto`: è
   sempre un'assenza, cambia solo quanto spazio si prende. */
.vuoto-sez { color: var(--muted); padding: .6rem; }

/* --- pagine di accesso (a pagina intera, due pannelli) ------------------ */

/* Le quattro pagine pre-login (accesso, registrazione, recupera/reimposta password) sono a
   PAGINA INTERA a due pannelli (deciso 2 ago): a sinistra la copertina brandizzata (gradiente
   hanko + kanji in filigrana), a destra il form su washi chiaro. Via l'overlay-iframe della
   landing — prima era un quadratino centrato dentro un iframe. Sono SEMPRE il look washi chiaro
   del sito, a prescindere dal tema/skin scelto nell'app: la palette si riasserisce qui (le stesse
   variabili che tema e skin cambiano), così il login non esce scuro o skinnato — la specificità
   (0,1,0) di .auth batte html:not([data-theme]) di default, e lo script inline imposta data-theme
   sul solo <html>, non su .auth; color-scheme:light per i controlli nativi; accento rosso hanko. */
.auth {
  display: flex;
  min-height: 100vh;

  --page:      #EFEBE1;
  --page-tenue:#F5F2EA;
  --card:      #FFFFFF;
  --card-alta: #FFFFFF;
  --border:    #E3DED2;
  --text:      #23201C;
  --muted:     #6B6E73;
  --riga-hover:#FBF9F4;
  --ok:#2F7D5B;   --ok-bg:#E4F0EA;   --ok-text:#245C41;
  --warn:#B07214; --warn-bg:#F6EBD6; --warn-text:#8A5A0B;
  /* Arancio delle BARRE di frequenza (§26 ago), a sé da `--warn`: quello è l'ocra dei badge
     d'avviso — «quota scaduta», «in pausa» — e su una barretta di 6px legge marrone. Qui
     serve un arancio che si distingua a colpo d'occhio dal rosso che gli sta sotto nella
     scala e dal verde che gli sta sopra, e `--warn` da solo non ci arrivava. Non si tocca
     `--warn`: cambiarlo ridipingerebbe ogni pastiglia d'avviso del pannello. */
  --arancio:#DD6B20; --arancio-text:#A9501A;
  --err:#A63125;  --err-bg:#F6E4E1;  --err-text:#7A231B;
  --demo:#6A4C93; --demo-on:#FFFFFF;
  --btn-bg:#17191C; --btn-fg:#FFFFFF;
  --accent:      #B5382C;
  --accent-tenue:#F3E4E1;
  --accent-text: #FFFFFF;
  --accent-on:   #FFFFFF;
  color-scheme: light;
  background: var(--page);
}

/* Pannello brandizzato a sinistra: inchiostro rosso-hanko, kanji in filigrana. */
.auth-hero {
  width: 44%;
  flex: 0 0 auto;
  position: relative;
  overflow: hidden;
  padding: 2.4rem 2.2rem;
  color: #fff;
  display: flex;
  flex-direction: column;
  background:
    radial-gradient(130% 120% at 85% -10%, rgba(255,255,255,.14), transparent 55%),
    linear-gradient(150deg, #B5382C 0%, #8C2A20 55%, #5F1C15 100%);
}
.auth-hero .wm {
  position: absolute; right: -18px; bottom: -34px;
  font-family: var(--jp); font-size: 17rem; line-height: 1;
  color: #fff; opacity: .08; user-select: none; pointer-events: none;
}
/* Marchio in alto a sinistra sull'hero rosso: tessera washi (non più medaglione tondo) col bollo
   hanko, handle vivo e claim. Bianco-carta così il rosso del bollo si stacca dall'hero rosso. */
.auth-logo-hero {
  position: relative;
  align-self: stretch;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 16px;
  background: #EFEBE1;
  border-radius: 16px;
  padding: 20px;
  box-shadow: 0 8px 22px rgba(0, 0, 0, .28);
  margin-bottom: .25rem;
}
/* Testo del marchio accanto al bollo quando la tessera è a tutta larghezza. */
.auth-marchio-testo { display: flex; flex-direction: column; min-width: 0; }
.auth-marchio-testo .auth-marchio-handle { margin-top: 0; }
.auth-marchio-bollo {
  width: 88px; height: 88px; border-radius: 18px; display: block;
}
.auth-marchio-handle {
  margin-top: .7rem; font-size: 1.02rem; font-weight: 800; letter-spacing: -.01em; line-height: 1;
}
.auth-marchio-handle .nome { color: #23201C; }
.auth-marchio-handle .tld { color: #A8792E; }
.auth-marchio-claim {
  margin-top: .4rem; font-size: .64rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .12em; color: #8A8272; white-space: nowrap;
}
.auth-claim { position: relative; margin-top: auto; }
.auth-claim h2 { font-size: 1.7rem; line-height: 1.2; font-weight: 800; letter-spacing: -.01em; }
.auth-claim p { font-size: .92rem; opacity: .9; margin-top: .65rem; line-height: 1.55; max-width: 320px; }
.auth-punti { margin-top: 1.3rem; display: flex; flex-direction: column; gap: .6rem; }
.auth-punto { display: flex; align-items: center; gap: .65rem; font-size: .84rem; opacity: .95; }
.auth-punto .t {
  width: 20px; height: 20px; border-radius: 50%; background: rgba(255,255,255,.18);
  display: grid; place-items: center; font-size: .72rem; flex: 0 0 auto;
}

/* Lato form a destra, su washi chiaro. */
.auth-formside {
  flex: 1; min-width: 0;
  background: var(--page);
  display: flex; align-items: center; justify-content: center;
  padding: 2.2rem 2rem;
}
.auth-form { width: 100%; max-width: 360px; }
.auth-logo { display: flex; align-items: center; gap: .6rem; margin-bottom: .3rem; }
.auth-logo .kk {
  width: 26px; height: 26px; border-radius: 7px; background: var(--accent); color: #fff;
  display: grid; place-items: center; font-family: var(--jp); font-size: .95rem; font-weight: 700;
}
.auth-logo b { font-size: .9rem; }
.auth-form h1 { font-size: 1.5rem; margin: 1rem 0 .2rem; color: var(--text); }
.auth-sub { font-size: .82rem; color: var(--muted); margin-bottom: 1.25rem; }

/* Campi: il look washi del mockup, dentro le pagine auth (l'InputText rende un <input>). */
.auth .campo { margin-bottom: .8rem; }
.auth .campo label { display: block; font-size: .74rem; font-weight: 600; color: #5b544c; margin-bottom: .3rem; }
.auth .campo input {
  width: 100%; border: 1px solid var(--border); border-radius: 9px; padding: .62rem .75rem;
  font-size: .9rem; font-family: inherit; background: #fff; color: var(--text);
}
.auth .campo input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tenue); }
.auth .due { display: flex; gap: .7rem; }
.auth .due .campo { flex: 1; }

/* Bottone primario a tutta larghezza (hanko). */
.auth .bottone.accento {
  width: 100%; border: none; background: var(--accent); color: #fff;
  border-radius: 10px; padding: .72rem; font-size: .95rem; font-weight: 700; cursor: pointer; margin-top: .4rem;
}
.auth .bottone.accento:disabled { opacity: .6; cursor: default; }

/* Link secondari sotto il form (rosso hanko scuro, non l'accento pieno). */
.auth-sotto { text-align: center; font-size: .82rem; color: var(--muted); margin-top: .9rem; }
.auth-link { text-align: center; font-size: .82rem; margin-top: .8rem; }
.auth-sotto a, .auth-link a { color: #8C2A20; font-weight: 600; text-decoration: none; }
.auth-sotto a:hover, .auth-link a:hover { text-decoration: underline; }

/* L'avviso d'errore dentro il form. */
.auth .avviso { margin-bottom: .9rem; }

/* Su schermo stretto: la copertina si accorcia sopra il form; sotto i 480 si nasconde e il
   form va a tutta larghezza. */
@media (max-width: 820px) {
  .auth { flex-direction: column; }
  .auth-hero { width: 100%; padding: 1.6rem 1.4rem; }
  .auth-claim { margin-top: 1rem; }
  .auth-claim h2 { font-size: 1.45rem; }
  .auth-hero .wm { font-size: 10rem; bottom: -22px; }
  .auth-punti { display: none; }
  .auth-formside { padding: 1.8rem 1.3rem; }
}
@media (max-width: 480px) {
  .auth-hero { display: none; }
}

/* --- validazione (dal template) ----------------------------------------- */

.valid.modified:not([type=checkbox]) { outline: 1px solid var(--ok); }
.invalid { outline: 1px solid var(--err); }
.validation-message { color: var(--err-text); font-size: .82rem; }

#blazor-error-ui {
  color: #F5F2EA;
  background: var(--ink-deep, #0E0F12);
  bottom: 0;
  display: none;
  left: 0;
  padding: .7rem 1.25rem;
  position: fixed;
  width: 100%;
  z-index: 1000;
}
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 1rem; top: .7rem; }

/* ===== cruscotto del gestore (schermata A, docs/budopass_webadmin.html) =====
   Tre domande, non «quanti soci ho»: cosa c'è STASERA, cosa devo FARE, come sta ANDANDO.
   Due colonne — il grosso a sinistra, i numeri e le liste corte a destra — che collassano
   a una su schermo stretto. */
.cru { display: grid; grid-template-columns: 1.6fr 1fr; gap: 1rem; align-items: start; }
.cru > .col { display: grid; gap: 1rem; align-content: start; }
@media (max-width: 900px) { .cru { grid-template-columns: 1fr; } }

/* I due numeri secchi (soci attivi, lezioni svolte): piccoli, di lato, col loro perché
   sotto — contesto, non titolo. */
.cru-kpi { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.cru-kpi .carta { padding: .9rem 1rem; }
/* Tessere-KPI cliccabili (Soci attivi → soci, Lezioni svolte → calendario). Il bordo che vira
   all'accento e il fondo tenue erano nati qui: ora sono il gesto condiviso .sollevabile (strato
   di movimento, in fondo al file), che ci aggiunge l'alzata di 1px e l'ombra alta. La vecchia
   transizione .12s è confluita là — non se ne tengono due. */
.cru-kpi a.carta { display: block; color: inherit; text-decoration: none; }
.cru-kpi .dato { font-size: 1.55rem; }
.cru-kpi .dato-perche { display: block; margin-left: 0; margin-top: .15rem; }

/* Stasera: fascia oraria a sinistra, corso al centro, azione (o il conteggio) a destra. */
.lezione-oggi { display: flex; align-items: center; gap: .9rem; padding: .55rem 0; border-bottom: 1px solid var(--border); }
.lezione-oggi:last-child { border-bottom: none; }
.lezione-oggi .ora { flex: 0 0 auto; min-width: 3.2rem; text-align: center; line-height: 1.15; }
.lezione-oggi .ora b { display: block; font-weight: 600; font-size: 1.05rem; }
.lezione-oggi .ora span { font-size: .78rem; color: var(--muted); }
.lezione-oggi .corpo { flex: 1; min-width: 0; }
.lezione-oggi .corpo b { font-weight: 500; }
.lezione-oggi .corpo p { margin: .15rem 0 0; font-size: .82rem; color: var(--muted); }
.lezione-oggi .coda { flex: 0 0 auto; margin-left: auto; display: flex; align-items: center; gap: .6rem; }
.lezione-oggi .presenti { font-weight: 600; white-space: nowrap; }
/* La riga è un link (4 set): niente colore né sottolineatura da <a>, e il chevron come le faccende. */
a.lezione-oggi { color: inherit; text-decoration: none; }
.lezione-oggi .vai { flex: 0 0 auto; color: var(--muted); }

/* La riga sottile quando stasera non c'è niente: la prossima in calendario. */
.prossima-riga { font-size: .88rem; color: var(--muted); }

/* Riga "da fare": pastiglia-conteggio colorata + titolo e chi/da-quando + chevron. Il colore
   porta l'urgenza — accento = normale, ambra = da riscuotere, rosso = non può allenarsi:
   semantici, non seguono accento né skin (§3.1). Mai lo stesso colore per due urgenze. */
.faccenda { display: flex; align-items: center; gap: .7rem; padding: .55rem 0; border-bottom: 1px solid var(--border); color: var(--text); text-decoration: none; }
.faccenda:last-child { border-bottom: none; }
.faccenda:hover { text-decoration: none; color: var(--accent-text); }
.faccenda .segna {
  flex: 0 0 28px; width: 28px; height: 28px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: .8rem;
  background: var(--accent-tenue); color: var(--accent-text);
}
.faccenda .segna.ambra { background: var(--warn-bg); color: var(--warn-text); }
.faccenda .segna.rosso { background: var(--err-bg); color: var(--err-text); }
.faccenda .corpo { flex: 1; min-width: 0; }
.faccenda .corpo b { font-weight: 500; display: block; }
.faccenda .corpo p { margin: .1rem 0 0; font-size: .8rem; color: var(--muted); }
.faccenda .vai { flex: 0 0 auto; margin-left: auto; color: var(--muted); }

/* Come va: una riga per corso — quadratino, nome e "N iscritti · ultima …", la frequenza e
   una barra sotto. La barra segue l'accento: è un colpo d'occhio sull'andamento, non un
   semaforo (per quello ci sono i colori di stato altrove). */
.corso-and { padding: .6rem 0; border-bottom: 1px solid var(--border); }
.corso-and:last-child { border-bottom: none; }
.corso-and .testa { display: flex; align-items: center; gap: .7rem; margin-bottom: .5rem; }
.corso-and .glifo {
  flex: 0 0 32px; width: 32px; height: 32px; border-radius: 9px;
  background: var(--accent-tenue); color: var(--accent-text);
  display: inline-flex; align-items: center; justify-content: center; font-weight: 600;
}
.corso-and .corpo { flex: 1; min-width: 0; }
.corso-and .corpo b { font-weight: 500; display: block; }
.corso-and .corpo p { margin: .1rem 0 0; font-size: .8rem; color: var(--muted); }
.corso-and .pc { margin-left: auto; flex: 0 0 auto; }
/* Riga corso come link (Come va → dettaglio corso): stesso alone tenue delle righe persona. */
.corso-and.linkabile {
  display: block; color: var(--text); text-decoration: none;
  margin: 0 -.6rem; padding-left: .6rem; padding-right: .6rem;
  border-radius: 9px; transition: background .12s ease;
}
.corso-and.linkabile .pc { margin-left: auto; }
.corso-and.linkabile:hover { background: var(--accent-tenue); }
.corso-and.linkabile .rp-vai { margin-left: .45rem; }
.pc { font-weight: 600; }
.barra-freq { height: 5px; border-radius: 3px; background: var(--page-tenue); overflow: hidden; }
.barra-freq > i { display: block; height: 100%; border-radius: 3px; background: var(--accent); }

/* --- Salute del dojo (cruscotto, parità con la card MAUI §5-bis) ----------------------------
   Donut della frequenza a sinistra (AhAnello), a destra il blocco coi numeri della stagione:
   la griglia stat 2×2 e, sotto un filo, i due estremi datati. Estremi e stat condividono la
   STESSA griglia 1fr/1fr dentro lo stesso blocco a destra: le colonne si incolonnano da sé:
   l'offset «larghezza donut + gap» nasce dal flex, non da un numero cablato. I valori riusano
   la misura di .corso-and (600, ~1rem) così la card e l'elenco «Come va» leggono come un sistema. */
.salute-corpo { display: flex; align-items: center; gap: 1rem; }
.salute-donut { flex: 0 0 auto; }
.salute-dx { flex: 1 1 auto; min-width: 0; }
.salute-griglia { display: grid; grid-template-columns: 1fr 1fr; gap: .7rem 1rem; }
.salute-sep { height: 1px; background: var(--border); margin: .85rem 0; }
.salute-cella .v { font-weight: 600; font-size: 1.05rem; line-height: 1.15; color: var(--text); }
.salute-cella .et { font-size: .75rem; color: var(--muted); margin-top: .12rem; }
/* Sotto una certa larghezza il donut va sopra il blocco, non a fianco: niente overflow. */
@media (max-width: 560px) {
  .salute-corpo { flex-direction: column; align-items: stretch; }
  .salute-donut { align-self: flex-start; }
}

/* ===== calendario del gestore (docs/budopass_webadmin_calendario.html) =====
   Su schermo grande la griglia del mese è la forma giusta: lo spazio c'è (§8). Il colore
   dice la NATURA della lezione, non l'accento — in programma sull'accento tenue, svolta
   verde, annullata ambra, seminar blu — e il pallino la ribadisce. I semantici (ok/warn)
   restano sé stessi con ogni tema e skin (§3.1); il blu del seminar non è nella palette
   dell'app, quindi vive qui come token dedicato (chiaro/scuro), mai inline. */
:root {
  --blu:#3B6EA5; --blu-bg:#E7ECF4; --blu-text:#2C477A;
  /* Le linee INTERNE della griglia sono più tenui del bordo (che resta al contorno e alla
     testata): una calligrafia leggera, non una tabella. E i giorni fuori mese sono un washi
     quasi bianco, appena staccato dalla carta — presenti ma zitti. */
  --cal-linea:#EFEAE0; --cal-fuori:#FBFAF6;
}
html[data-theme="dark"] { --blu:#5B7FBF; --blu-bg:#233149; --blu-text:#A9C0E6; --cal-linea:#322E27; --cal-fuori:#201D18; }
@media (prefers-color-scheme: dark) {
  html[data-theme="system"], html:not([data-theme]) {
    --blu:#5B7FBF; --blu-bg:#233149; --blu-text:#A9C0E6; --cal-linea:#322E27; --cal-fuori:#201D18;
  }
}

/* Intestazione: titolo del mese, navigazione ‹ Oggi ›, e il ＋ Nuova lezione (azione di
   gestione, resa solo per chi può gestire, §4). */
.cal-head { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; margin-bottom: 1.1rem; }
.cal-head h1 { text-transform: capitalize; }
.cal-nav { display: flex; align-items: center; gap: .4rem; margin-left: auto; }
.cal-navbtn {
  min-width: 32px; height: 32px; padding: 0 .4rem;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); background: var(--card); color: var(--muted);
  border-radius: var(--raggio-s); box-shadow: var(--ombra); cursor: pointer;
  font-family: var(--sans); font-size: 1rem;
}
.cal-navbtn:hover { background: var(--riga-hover); color: var(--text); }
.cal-navbtn.oggi { padding: 0 .8rem; font-size: .82rem; font-weight: 600; color: var(--accent-text); }
.cal-nuova {
  display: inline-flex; align-items: center; gap: .45rem;
  height: 32px; padding: 0 .95rem; margin-left: .2rem;
  border: 1px solid var(--accent); background: var(--accent); color: var(--accent-on);
  border-radius: var(--raggio-s); box-shadow: var(--ombra); cursor: pointer;
  font-family: var(--sans); font-size: .82rem; font-weight: 600;
}
.cal-nuova:hover { filter: brightness(1.06); }
.cal-nuova .piu { font-size: 1rem; line-height: 0; }

/* Sottotitolo (vista allievo): dice se guardi tutti i dojo o uno solo (§7). */
.cal-sub { color: var(--muted); font-size: .88rem; margin: -.55rem 0 1rem; }

.cal-grid { background: var(--card); border: 1px solid var(--border); border-radius: var(--raggio); overflow: hidden; box-shadow: var(--ombra); }
/* La testata dei giorni è la stessa carta, non una fascia: la separa solo una linea. Stesso
   gap della griglia sotto, così le colonne dei nomi combaciano esattamente con le caselle. */
.cal-gh { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 1px; background: var(--cal-linea); border-bottom: 1px solid var(--border); }
.cal-gh div { padding: .6rem .7rem .5rem; background: var(--card); font-size: .66rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); opacity: .75; }
/* Le linee interne le disegna la griglia (gap colorato dal fondo), non i bordi di ogni
   cella: una cornice sottile e continua invece di tanti riquadri. */
.cal-gb {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); grid-auto-rows: minmax(92px, 1fr);
  gap: 1px; background: var(--cal-linea);
}

/* Ogni casella è un bersaglio: cliccandola si seleziona il giorno e il pannello mostra le
   sue lezioni. Nessuna cella morta. */
.cal-cell {
  padding: .4rem .5rem; position: relative;
  border: none; background: var(--card); cursor: pointer; text-align: left; width: 100%;
  font-family: var(--sans); color: inherit; display: block;
  transition: background .12s ease;
}
.cal-cell:hover { background: var(--riga-hover); }
.cal-daynum { font-size: .78rem; color: var(--muted); font-weight: 600; }
.cal-cell.fuori { background: var(--cal-fuori); }
.cal-cell.fuori:hover { background: var(--cal-fuori); }
.cal-cell.fuori .cal-daynum { color: var(--muted); opacity: .5; }
.cal-cell.oggi { background: var(--accent-tenue); }
.cal-cell.oggi .cal-daynum { color: var(--accent-text); font-weight: 700; }
/* Selezionata: un anello d'accento verso l'interno, sopra il resto (z-index perché il gap
   della griglia non lo tagli). */
.cal-cell.sel { box-shadow: inset 0 0 0 2px var(--accent); z-index: 1; }
/* Chiusura: tratteggio diagonale e l'etichetta in linea — dentro non c'è niente, ed è il
   punto (§3). Il tratteggio si adatta al tema variando le due tinte del washi. */
.cal-cell.chiusa {
  background: repeating-linear-gradient(45deg,
    var(--cal-fuori), var(--cal-fuori) 7px, var(--cal-linea) 7px, var(--cal-linea) 14px);
  cursor: default;
}
.cal-cell.chiusa:hover { background: repeating-linear-gradient(45deg,
    var(--cal-fuori), var(--cal-fuori) 7px, var(--cal-linea) 7px, var(--cal-linea) 14px); }
.cal-close-label { margin-top: .4rem; font-size: .68rem; font-weight: 600; color: var(--muted); }

/* Chip di lezione: pallino + testo, colore per stato. La coda (presenti/attesi) è tabellare
   e allineata a destra: un mese di numeri in fila è la statistica del corso senza aprirla. */
.cal-ev {
  margin-top: .3rem; border-radius: 6px; padding: .18rem .42rem;
  font-size: .7rem; font-weight: 600; line-height: 1.3;
  display: flex; align-items: center; gap: .32rem;
}
.cal-ev .dot { width: 6px; height: 6px; border-radius: 50%; flex: none; }
.cal-ev .et { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-ev .cnt { font-weight: 700; font-variant-numeric: tabular-nums; }
.cal-ev.prog { background: var(--accent-tenue); color: var(--accent-text); }
.cal-ev.prog .dot { background: var(--accent); }
.cal-ev.fatta { background: var(--ok-bg); color: var(--ok-text); }
.cal-ev.fatta .dot { background: var(--ok); }
.cal-ev.ann { background: var(--warn-bg); color: var(--warn-text); text-decoration: line-through; }
.cal-ev.ann .dot { background: var(--warn); }
.cal-ev.sem { background: var(--blu-bg); color: var(--blu-text); }
.cal-ev.sem .dot { background: var(--blu); }
/* Neutro (allievo §7): il passato senza il proprio fatto, o l'assenza — carta tenue, muto. */
.cal-ev.neutro { background: var(--page-tenue); color: var(--muted); }
.cal-ev.neutro .dot { background: var(--muted); }
/* Corso CHIUSO (§28 ago): niente fondo e un tratteggio — è una cosa che NON succede, in mezzo a
   cose che succedono, e il tratteggio è già il segno della chiusura altrove (la casella del dojo
   chiuso, il pannello «genera»). Il padding scala di 1px perché questa è l'unica variante con un
   bordo: senza, la pastiglia chiusa sarebbe due pixel più alta di quelle che le stanno accanto. */
.cal-ev.chiuso {
  background: transparent; color: var(--muted);
  border: 1px dashed var(--border);
  padding: calc(.18rem - 1px) calc(.42rem - 1px);
}
.cal-ev.chiuso .dot { background: var(--muted); }

/* Legenda: il colore mappato al significato, sotto la griglia. */
.cal-leg { display: flex; gap: 1rem; flex-wrap: wrap; font-size: .74rem; color: var(--muted); padding: .8rem .15rem 0; }
.cal-leg span { display: inline-flex; align-items: center; gap: .4rem; }
.cal-leg i { width: 9px; height: 9px; border-radius: 3px; display: inline-block; }
.cal-leg i.i-prog { background: var(--accent); }
.cal-leg i.i-fatta { background: var(--ok); }
.cal-leg i.i-ann { background: var(--warn); }
.cal-leg i.i-sem { background: var(--blu); }
.cal-leg i.i-chiusa { background: var(--border); }

/* --- fascia del giorno SOPRA la griglia (PannelloGiorno.razor) -----------
   Il giorno a sinistra, le lezioni al centro (ogni card è cliccabile = apri la lezione), il
   contesto a destra. Sopra la griglia così la griglia prende tutta la larghezza. */
.cal-daybar { margin-bottom: 1rem; }
.dp-bar {
  display: flex; align-items: stretch; gap: 1rem; flex-wrap: wrap;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--raggio);
  box-shadow: var(--ombra); padding: .75rem 1rem;
}
.dp-when { flex: 0 0 auto; min-width: 150px; display: flex; flex-direction: column; justify-content: center; }
.dp-when .occhiello { font-size: 9.5px; font-weight: 600; letter-spacing: .13em; text-transform: uppercase; color: var(--muted); opacity: .8; }
.dp-when h3 { font-size: 1.05rem; margin: .2rem 0 0; text-transform: capitalize; }

.dp-lessons { flex: 1 1 320px; display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; min-width: 0; }
.dp-vuoto { font-size: .85rem; color: var(--muted); align-self: center; }

/* Card lezione: tutta la card apre il registro (§5). */
.dp-lz {
  display: inline-flex; align-items: center; gap: .7rem; min-width: 0;
  padding: .45rem .5rem .45rem .7rem; border: 1px solid var(--border); border-radius: var(--raggio-s);
  background: var(--page-tenue); color: var(--text); text-decoration: none;
}
.dp-lz:hover { border-color: var(--accent); background: var(--card); text-decoration: none; }
.dp-ora { flex: 0 0 auto; text-align: center; line-height: 1.05; }
.dp-ora b { font-size: .9rem; font-weight: 700; display: block; }
.dp-ora span { font-size: .66rem; color: var(--muted); }
.dp-corpo { min-width: 0; display: flex; flex-direction: column; }
.dp-corpo b { font-size: .86rem; font-weight: 500; white-space: nowrap; }
.dp-corpo .meta { font-size: .72rem; color: var(--muted); margin-top: .05rem; white-space: nowrap; }
.dp-pill { font-size: .68rem; font-weight: 600; border-radius: 999px; padding: .1rem .5rem; white-space: nowrap; }
.dp-pill.prog { background: var(--accent-tenue); color: var(--accent-text); }
.dp-pill.fatta { background: var(--ok-bg); color: var(--ok-text); }
.dp-pill.ann { background: var(--warn-bg); color: var(--warn-text); }
.dp-pill.neutro { background: var(--page-tenue); color: var(--muted); border: 1px solid var(--border); }
/* Intento RSVP dell'allievo (§7): a CONTORNO — il fatto è pieno, l'intento è un bordo. Chi non
   ha risposto trova «Rispondi» tratteggiato: un invito, non uno stato. */
.dp-pill.si { background: transparent; color: var(--ok-text); border: 1px solid var(--ok); }
.dp-pill.no { background: transparent; color: var(--muted); border: 1px solid var(--border); }
.dp-pill.rispondi { background: transparent; color: var(--accent-text); border: 1px dashed var(--accent); }
/* I due conti RSVP della lezione futura (§27 ago), al posto della pastiglia: stessa riga, stesso
   posto a destra. Nessuno sfondo — sono numeri, non stati: la pastiglia piena qui accanto direbbe
   «Annullata» e non deve avere concorrenza. Il «ci sono» prende --ok-text, il «non ci sono» --muted
   (informazione, non allarme); entrambi sono token di tema, quindi chiaro e scuro vengono da sé. */
.dp-rsvp { display: inline-flex; align-items: center; gap: .5rem; white-space: nowrap; }
.dp-rs { display: inline-flex; align-items: center; gap: .2rem; font-size: .72rem; font-weight: 600; }
.dp-rs svg { width: 14px; height: 14px; flex: 0 0 auto; }
.dp-rs.si { color: var(--ok-text); }
.dp-rs.no { color: var(--muted); }
/* Chi ha già timbrato (4 set): l'accento, il colore del timbro — distinto dal verde del «ci sarò». */
.dp-rs.checkin { color: var(--accent-text); }
.dp-vai { color: var(--muted); font-size: 1rem; line-height: 0; }
/* La card lezione può essere un bottone (RSVP allievo) o inerte (passato): reset e cursore. */
button.dp-lz { font-family: var(--sans); font-size: inherit; text-align: left; cursor: pointer; }
.dp-lz.statica { cursor: default; }
.dp-lz.statica:hover { border-color: var(--border); background: var(--page-tenue); }

.dp-context { flex: 0 0 auto; max-width: 280px; padding-left: 1rem; border-left: 1px solid var(--border); display: flex; flex-direction: column; justify-content: center; }
.dp-context .occhiello { font-size: 9.5px; font-weight: 600; letter-spacing: .13em; text-transform: uppercase; color: var(--muted); opacity: .8; margin-bottom: .25rem; }
.dp-nota { font-size: .78rem; color: var(--muted); line-height: 1.5; }
.dp-nota b { color: var(--text); }
@media (max-width: 720px) { .dp-context { max-width: none; padding-left: 0; border-left: none; } }

/* --- verifica del registro (Lezione.razor, schermata B) ----------------
   Non è un appello da compilare: si apre già piena dei check-in. In alto i numeri che
   contano, poi i nomi dei mancanti, poi da dove arriva ogni presenza. */
.reg-head { display: flex; align-items: center; gap: .8rem; margin-bottom: 1.1rem; }
.reg-back {
  flex: 0 0 auto; width: 32px; height: 32px; border-radius: var(--raggio-s);
  border: 1px solid var(--border); background: var(--card); color: var(--muted);
  display: inline-flex; align-items: center; justify-content: center; font-size: 1rem;
}
.reg-back:hover { background: var(--riga-hover); color: var(--text); text-decoration: none; }
.reg-head h1 { margin: 0; }
.reg-head .giorno { font-size: .82rem; color: var(--muted); text-transform: capitalize; }

/* --- carta «Dati della lezione» (Lezione.razor, §27 ago) ----------------
   Sta subito sotto la testata e prima di tutto il resto: sono i dati della sera, non un'azione
   defilata. Il margine in basso è quello fra due blocchi della pagina (come .reg-kpis). */
.dati-lezione { margin-bottom: 1.1rem; }

/* Griglia etichetta/valore per i valori CORTI, dove incolonnare serve davvero. Una frase non ci
   va (vedi .lez-lunga): spezzata in una colonna da 150px si romperebbe ogni tre parole lasciando
   metà carta vuota. */
.lez-griglia { display: grid; grid-template-columns: 150px 1fr; gap: .6rem; padding: .45rem 0; }
.lez-griglia .et { color: var(--muted); font-size: .82rem; }
.lez-griglia .va { font-size: .88rem; }
/* Il «dal corso» accanto al trattino: fioco, perché è la spiegazione del trattino e non un
   secondo valore. */

/* Il valore che è una FRASE: etichetta sopra, testo a tutta riga. Il filo sotto lo separa dalle
   righe incolonnate che seguono — sono due forme diverse nella stessa carta, e senza il filo la
   seconda sembrerebbe la continuazione della prima. */
.lez-lunga { padding-bottom: .7rem; margin-bottom: .3rem; border-bottom: 1px solid var(--border); }
.lez-lunga .etichetta { margin-bottom: .15rem; }
.lez-lunga > div:last-child { font-size: .88rem; white-space: pre-line; }

/* In modifica l'argomento sta a tutta larghezza SOTTO le due colonne: non è un campo pari agli
   altri, ed entrare nella griglia lo ridurrebbe a una casella d'una riga. */
.lez-argomento textarea { width: 100%; min-height: 4.5rem; resize: vertical; }

.reg-kpis { display: flex; gap: .8rem; margin-bottom: 1.1rem; flex-wrap: wrap; }
.reg-kpi { flex: 1 1 120px; background: var(--card); border: 1px solid var(--border); border-radius: var(--raggio); padding: .8rem 1rem; box-shadow: var(--ombra); }
.reg-kpi span { font-size: .72rem; font-weight: 600; color: var(--muted); }
.reg-kpi b { display: block; font-size: 1.5rem; font-weight: 700; letter-spacing: -.02em; margin-top: .25rem; line-height: 1; font-variant-numeric: tabular-nums; }
.reg-kpi b.ok { color: var(--ok); }

/* «Mancano N: …» ad ALTEZZA FISSA (§1 set). Il contenuto resta vivo — si accorcia a ogni spunta —
   ma il riquadro no: crescendo e calando tirerebbe su la tabella sotto, e sposterebbe righe che
   nessuno ha toccato mentre il dito scorre la colonna dei nomi.
   Tre righe di testo sempre: una per il conto (ferma: è la risposta che si cerca, non deve
   scorrere via) e due per i nomi, che scorrono dentro. L'interlinea è ESPLICITA e l'altezza si
   deriva da lei — sono due righe vere, non una misura a occhio che scivola col font. */
.reg-miss { --reg-miss-interlinea: 1.35; background: var(--warn-bg); border: 1px solid var(--warn); border-radius: var(--raggio); padding: .7rem .9rem; margin-bottom: 1.1rem; font-size: .84rem; line-height: var(--reg-miss-interlinea); color: var(--warn-text); }
.reg-miss b { display: block; font-weight: 700; }
.reg-miss-nomi { height: calc(2 * var(--reg-miss-interlinea) * 1em); overflow-y: auto; }

/* Tabella su carta con angoli tondi (come le altre tabelle, §3.1). */
.reg-tab { border: 1px solid var(--border); border-radius: var(--raggio); overflow: hidden; box-shadow: var(--ombra); }
.reg-tab table { background: var(--card); }
.reg-tab th { background: var(--page-tenue); }
.reg-tab td { vertical-align: middle; }
/* Sezioni dentro la carta RSVP (Futura «ci sarò»/«non ci sarò», InCorso «check-in»/«attesi»):
   l'h2.sez è nudo e incollerebbe un gruppo all'altro. Le successive staccate — stesso respiro
   di .reg-actions, non un numero a caso.

   E RIENTRATE come il contenuto che intestano (1 set). `.reg-tab` non ha spaziatura propria,
   le celle sì (`td`, .6rem): il titolo cadeva dieci pixel più a sinistra della colonna di nomi
   che stava intestando, e la prima riga toccava il bordo alto della carta. Il rientro sta sul
   TITOLO e non sul contenitore perché lo stesso `.reg-tab`, a lezione conclusa, avvolge una
   tabella nuda col `<thead>`: là la banda dell'intestazione deve arrivare fino agli angoli
   tondi, ed è la ragione per cui questa carta nasce senza spaziatura. Il respiro sopra e sotto
   lo prende solo la variante A SEZIONI, che si riconosce da `:has(.sez)`.

   Sopra .9rem pieni (il titolo non ha spaziatura sua); sotto .3rem, perché gli ultimi .6rem li
   mette già il contenuto — cella o stato vuoto che sia. Fanno la stessa aria da tutt'e due i
   lati, che è il punto: sommare due volte .6rem avrebbe dato un fondo più largo del capo. */
.reg-tab .sez { margin: 1.1rem .6rem .7rem; }
.reg-tab:has(.sez) { padding: .9rem 0 .3rem; }
.reg-tab .sez:first-child { margin-top: 0; }
/* L'ultima riga dell'ultima tabella appoggiava la propria riga di separazione sul bordo della
   carta: due fili a un pixel l'uno dall'altro. A chiudere l'elenco è la carta, non un filo. */
.reg-tab:has(.sez) > table:last-child tbody tr:last-child td { border-bottom: none; }
.reg-av {
  width: 28px; height: 28px; border-radius: 8px; flex: 0 0 28px;
  background: var(--accent-tenue); color: var(--accent-text);
  display: inline-grid; place-items: center; font-size: .7rem; font-weight: 600;
  vertical-align: middle; margin-right: .6rem;
}
.reg-src { font-size: .7rem; font-weight: 600; border-radius: 999px; padding: .12rem .55rem; white-space: nowrap; }
.reg-src.qr { background: var(--ok-bg); color: var(--ok-text); }
.reg-src.man { background: var(--page-tenue); color: var(--muted); border: 1px solid var(--border); }
.reg-src.vuoto { color: var(--muted); }
/* Riga di chi manca: evidenziata, con la sorgente vuota e l'interruttore spento. */
.reg-missrow td { background: var(--warn-bg); }

/* Interruttore di presenza: verde acceso, grigio spento. È un bottone vero (tocco grande,
   raggiungibile da tastiera), disegnato come lo switch del mockup. */
.reg-toggle {
  width: 40px; height: 23px; border-radius: 12px; padding: 0; border: none;
  background: var(--ok); position: relative; cursor: pointer; display: inline-block;
  vertical-align: middle;
}
.reg-toggle::after { content: ""; position: absolute; width: 19px; height: 19px; border-radius: 50%; background: #fff; top: 2px; right: 2px; }
.reg-toggle.off { background: var(--border); }
.reg-toggle.off::after { right: auto; left: 2px; }
.reg-toggle:disabled { opacity: .6; cursor: default; }

/* Riga dell'OSPITE (§1 set): fondo proprio, perché a colpo d'occhio si veda che quella riga non
   è di un socio — e perché la sua coda porta un cestino dove tutte le altre hanno un
   interruttore. Non ambra come .reg-missrow: quella segnala un'ANOMALIA (chi era atteso e
   manca), questa un TIPO. Un fondo d'allarme su chi è semplicemente venuto direbbe altro. */
.reg-ospite td { background: var(--page-tenue); }
.reg-ospite .etichetta { margin-top: .1rem; }

/* Il cestino sulla riga dell'ospite: stessa forma delle altre icone d'azione del pannello
   (.ev-fld-x in Impostazioni, .nz-ib in Notizie), col rosso solo al passaggio — l'azione è
   distruttiva ma non è un allarme permanente sulla riga. */
.reg-cestino {
  color: var(--muted); cursor: pointer; border: none; background: none; padding: .2rem .3rem;
  display: inline-flex; align-items: center; justify-content: center; vertical-align: middle;
}
.reg-cestino svg { width: 17px; height: 17px; }
.reg-cestino:hover { color: var(--err); }
.reg-cestino:disabled { opacity: .5; cursor: default; }

.reg-actions { display: flex; gap: .7rem; margin-top: 1.1rem; flex-wrap: wrap; }

/* --- modale (la creazione della lezione-eccezione, §4): un velo e una carta centrata.
   I campi e i bottoni sono quelli condivisi (.campo, input, .bottone). --------------- */
.modale-fondo { position: fixed; inset: 0; background: rgba(14, 15, 18, .4); z-index: 60; display: grid; place-items: center; padding: 1rem; }
/* max-height + scroll (§26 ago): da quando le conferme distruttive dicono cosa succede IN
   NUMERI — l'elenco di «Elimina», e soprattutto quello di «Unisci» — il corpo può arrivare a
   una quindicina di righe. Senza tetto la carta cresce oltre la finestra e i due bottoni
   finiscono sotto il bordo: la conferma resterebbe leggibile e non premibile. */
.modale { width: 100%; max-width: 420px; max-height: 85vh; overflow-y: auto; background: var(--card-alta); border: 1px solid var(--border); border-radius: var(--raggio); box-shadow: var(--ombra); padding: 1.25rem; }
.modale h2 { margin-top: 0; }

/* «Assegna presenze» (§1 set). Più larga delle conferme: qui non si legge una frase, si sceglie
   fra righe che portano un nome, un corso e un elenco di date. */
.modale.assegna { max-width: 620px; }
.modale.assegna .sez { margin: 0 0 .4rem; }

/* Un gruppo: la spunta prende tutta la riga (è il bersaglio), il numero di sere resta a destra
   come un contatore e non come un'azione. */
.assegna-gruppo {
  display: flex; align-items: center; gap: .6rem;
  border: 1px solid var(--border); border-radius: var(--raggio-s);
  padding: .15rem .5rem .15rem .1rem; margin-bottom: .4rem; background: var(--card);
}
.assegna-gruppo.sel { border-color: var(--accent); }
.assegna-gruppo .spunta { flex: 1; min-width: 0; }
.assegna-nome { display: block; font-weight: 600; }
.assegna-sere-riga { display: block; font-size: .78rem; color: var(--muted); }
.assegna-num {
  flex: none; background: var(--page-tenue); border-radius: 8px;
  padding: .15rem .5rem; font-weight: 700; font-size: .82rem;
}
.assegna-altre { width: 100%; margin-top: .2rem; }

/* Il piede: il conteggio a sinistra — che somma FRA i gruppi e sopravvive alla ricerca — e i
   due bottoni a destra. */
.assegna-piede {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  margin-top: .9rem; padding-top: .8rem; border-top: 1px solid var(--border);
}
.assegna-scartate { margin-top: .9rem; padding-top: .8rem; border-top: 1px solid var(--border); }
.assegna-sere { margin: .3rem 0 .7rem; padding-left: 1.1rem; font-size: .84rem; color: var(--muted); }
.modale .fila { display: flex; gap: .7rem; }
.modale .fila .campo { flex: 1; }
.modale .azioni { display: flex; justify-content: flex-end; gap: .6rem; margin-top: 1rem; }
/* Occhiello del modale: la piccola etichetta maiuscola sopra il titolo, come le teste di
   sezione (day panel, carte). */
.modale-occhiello { font-size: 9.5px; font-weight: 600; letter-spacing: .13em; text-transform: uppercase; color: var(--muted); opacity: .8; margin-bottom: .25rem; }

/* Avviso «pilota» all'apertura della registrazione (DECISIONI_STORICO, «Registrazione —
   modale «pilota»»): stessa card di conferma (.modale), ma centrata attorno al sigillo 武 su
   hanko rosso — il marchio prima delle parole. Occhiello tinto d'accento, testo tenue, la CTA
   piena in basso. Niente riquadro «gestisci un dojo»: qui siamo già sul pannello web. */
.modale.pilota { max-width: 380px; text-align: center; }
.pilota-sigillo {
  width: 52px; height: 52px; margin: 0 auto .5rem; border-radius: 14px;
  background: var(--accent); color: #F7EEE9;
  display: grid; place-items: center; font-family: var(--jp); font-size: 1.55rem; font-weight: 700;
}
.modale.pilota .modale-occhiello { color: var(--accent); opacity: 1; margin-bottom: .35rem; }
.modale.pilota h2 { margin: .1rem 0 .4rem; }
.pilota-testo { color: var(--muted); font-size: .9rem; line-height: 1.55; margin: 0 0 1.15rem; }
.modale.pilota .bottone.accento {
  width: 100%; border: none; background: var(--accent); color: #fff;
  border-radius: 10px; padding: .72rem; font-size: .95rem; font-weight: 700; cursor: pointer;
}

/* Avviso «pilota» IN PAGINA sulla registrazione web (variante B, ricalibrato il 5 ago): sul web
   c'è spazio, quindi niente popup — un banner tinto d'accento in cima al modulo con la spunta
   obbligatoria. Riusa .pilota-sigillo e .pilota-testo. Le pagine auth pinnano una palette hanko
   chiara a prescindere da tema/skin, perciò l'occhiello va in --accent (rosso), non in
   --accent-text (che qui è bianco); il corpo in --text. */
.pilota-banner {
  display: flex; gap: .8rem; align-items: flex-start;
  background: var(--accent-tenue); border: 1px solid var(--accent);
  border-radius: 12px; padding: .9rem 1rem; margin-bottom: 1.1rem;
}
.pilota-banner .pilota-sigillo {
  margin: 0; flex: 0 0 auto; width: 40px; height: 40px; font-size: 1.25rem; border-radius: 11px;
}
.pilota-banner-corpo { min-width: 0; flex: 1; }
.pilota-banner .modale-occhiello { color: var(--accent); opacity: 1; margin-bottom: .25rem; }
.pilota-banner .pilota-testo { color: var(--text); font-size: .84rem; line-height: 1.5; margin: 0 0 .65rem; }
/* La spunta obbligatoria: casella + testo su una riga cliccabile. */
.pilota-spunta { display: flex; align-items: flex-start; gap: .5rem; font-size: .86rem; font-weight: 600; color: var(--text); cursor: pointer; }
.pilota-spunta input { margin-top: .12rem; flex: 0 0 auto; accent-color: var(--accent); width: 1rem; height: 1rem; }

/* Scelta-tra-N (il foglio delle scelte, §validazione): righe selezionabili con la corrente
   accesa e la spunta, come le voci del selettore di contesto (.ctx). Ogni voce porta un
   pallino del colore che ha nel calendario, così la scelta e la riga parlano la stessa
   lingua. */
.scelte { display: flex; flex-direction: column; gap: .3rem; margin: .5rem 0 .2rem; }
.scelta {
  display: flex; align-items: center; gap: .6rem; width: 100%;
  padding: .6rem .7rem; border: 1px solid var(--border); background: var(--card);
  border-radius: var(--raggio-s); cursor: pointer; text-align: left;
  color: var(--text); font-family: var(--sans); font-size: .92rem;
}
.scelta:hover { background: var(--riga-hover); }
.scelta.attiva { border-color: var(--accent); background: var(--accent-tenue); color: var(--accent-text); }
.scelta .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.scelta .dot.si { background: var(--ok); }
.scelta .dot.no { background: var(--muted); }
.scelta .dot.forse { background: var(--accent); }
.scelta .et { flex: 1; min-width: 0; font-weight: 500; }
.scelta .tick { color: var(--accent); font-weight: 700; }

/* === Home allievo ricca (budopass_home_allievo_web.html) ==================
   Il corpo della Home che aggrega: saluto + data, eventuale banda del certificato, poi
   due colonne (1.5fr / 1fr). Tutte le carte seguono il contesto (aggregato / un ente).
   I colori stanno qui, non inline: i toni di stato (ok/warn/err) non seguono l'accento. */

.ah-sub { color: var(--muted); font-size: .9rem; margin: 0 0 1.4rem; text-transform: capitalize; }

/* Banda a tutta larghezza: la scadenza del certificato medico. warn = in scadenza, err = scaduto. */
.ah-banda { display: flex; align-items: flex-start; gap: .7rem; padding: .85rem 1rem;
  border: 1px solid transparent; border-radius: var(--raggio); margin-bottom: 1.4rem; }
.ah-banda.warn { background: var(--warn-bg); color: var(--warn-text); border-color: var(--warn); }
.ah-banda.err  { background: var(--err-bg);  color: var(--err-text);  border-color: var(--err); }
.ah-banda .punto { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%;
  background: currentColor; margin-top: .42rem; }
.ah-banda .b { font-weight: 600; }
/* La banda è un LINK (porta al certificato in «Impostazioni»): niente sottolineatura da <a>, e
   il colore resta quello dello stato — che le due regole qui sopra vincono per specificità. */
a.ah-banda { text-decoration: none; }
a.ah-banda:hover { text-decoration: none; filter: brightness(0.97); }

/* Due colonne: rich cards a sinistra, tessere + promesse a destra. */
.ah-cols { display: grid; grid-template-columns: 1.5fr 1fr; gap: 1rem; align-items: start; }
.ah-colonna { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
@media (max-width: 900px) { .ah-cols { grid-template-columns: 1fr; } }

/* Prossima lezione: tessera-data + testo + badge RSVP. */
.ah-lezione { display: flex; gap: .9rem; align-items: flex-start; }
/* Più lezioni di oggi nella stessa carta: si separano con un filo e un po' d'aria, così le
   card non si confondono l'una nell'altra. */
.ah-lezione + .ah-lezione { margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--border); }
.ah-data { flex: 0 0 auto; width: 54px; text-align: center; padding: .4rem 0;
  background: var(--page-tenue); border: 1px solid var(--border); border-radius: var(--raggio-s); }
.ah-data .g { font-size: 1.45rem; font-weight: 700; line-height: 1; color: var(--text); }
.ah-data .m { font-size: .7rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.ah-lezione .corpo { flex: 1; min-width: 0; }
.ah-lezione .titolo { font-weight: 600; }
.ah-lezione .meta { color: var(--muted); font-size: .85rem; }

.ah-rsvp { display: inline-block; font-size: .74rem; padding: .12rem .5rem; border-radius: 999px;
  border: 1px solid transparent; white-space: nowrap; margin-top: .3rem; }
.ah-rsvp.si    { background: var(--ok-bg);  color: var(--ok-text);  border-color: var(--ok); }
.ah-rsvp.no    { background: var(--err-bg); color: var(--err-text); border-color: var(--err); }
.ah-rsvp.forse { background: transparent;   color: var(--muted);    border-style: dashed; border-color: var(--border); }
/* Il badge RSVP cliccabile (Home allievo, come il calendario): stesso aspetto a pillola, ma è un
   <button> — reset del font e cursore/affordance d'hover. La pastiglia «Presente» resta uno <span>. */
button.ah-rsvp { font-family: inherit; cursor: pointer; }
button.ah-rsvp:hover { filter: brightness(.97); }
button.ah-rsvp.forse:hover { border-color: var(--muted); color: var(--text); }

/* Il codice socio da dettare al chiosco: riquadro morbido, codice in monospazio. */
.ah-codice { margin-top: .9rem; padding: .7rem .85rem; background: var(--page-tenue);
  border: 1px solid var(--border); border-radius: var(--raggio-s); }
.ah-codice .l { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.ah-codice .v { font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 1.3rem; font-weight: 600; letter-spacing: .14em; color: var(--text); }
.ah-codice .h { font-size: .78rem; color: var(--muted); }

/* Anelli presenze: conic-gradient riempito fino a --v, ciambella col foro al centro.
   --v è un numero (0..100), non un colore: si può passare inline. */
/* Due metà uguali, ognuna centrata, col filo in mezzo come sull'app (6 set, Fudo: «allinea al
   centro tutto lasciando un buon margine fra lezioni e seminar»). */
.ah-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; align-items: center; }
.ah-stats > * { display: flex; justify-content: center; min-width: 0; }
.ah-stats > :first-child { border-right: 1px solid var(--border); }
.ah-st { display: flex; align-items: center; gap: .7rem; }
.ah-ring { --ah-ac: var(--ok); position: relative; width: 66px; height: 66px; flex: 0 0 auto;
  border-radius: 50%; background: conic-gradient(var(--ah-ac) calc(var(--v, 0) * 1%), var(--border) 0); }
.ah-ring.blu { --ah-ac: #3B6EA5; }
/* Il tono della frequenza (3 set): stessi terzi e stessi colori delle barrine dei soci. */
.ah-ring.media { --ah-ac: var(--arancio); }
.ah-ring.scarsa { --ah-ac: var(--err); }
.ah-ring-in { position: absolute; inset: 7px; border-radius: 50%; background: var(--card);
  display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: .95rem; color: var(--text); }
.ah-st-meta .b { font-weight: 600; }
.ah-st-meta .et { color: var(--muted); font-size: .8rem; }
/* Il bollo di un conteggio (i seminar, 3 set): stessa misura dell'anello, quadrato smussato,
   il numero grande nel tono dei seminar. Un conteggio non ha un «su quanti»: niente arco. */
/* L'anello che è un link (3 set): stessa resa, il cursore dice che si apre. */
.ah-link { color: inherit; text-decoration: none; display: block; border-radius: var(--raggio); }
/* Niente sottolineatura al passaggio (6 set, Fudo): il link resta, il testo non cambia. */
.ah-link:hover, .ah-link:hover * { text-decoration: none; }
.ah-tile { width: 66px; height: 66px; flex: 0 0 auto; border-radius: 18px; background: var(--page-tenue);
  display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 1.45rem;
  color: #3B6EA5; font-variant-numeric: tabular-nums; }

/* Il mio percorso: token del grado (SegnoGrado) + grado + provenienza/data, una riga per ente×disciplina. */
.ah-perc { display: flex; align-items: center; gap: .9rem; }
.ah-perc + .ah-perc { border-top: 1px solid var(--border); margin-top: .85rem; padding-top: .85rem; }
/* Il segno va incassato in un .segno di larghezza fissa: senza, l'SVG del token non ha vincolo
   di larghezza e riempie tutta la carta (§10, come .riga-budopass .segno). La regola
   `.segno .token-svg` cappa poi l'SVG a 46px. */
.ah-perc .segno { flex: 0 0 52px; display: flex; flex-direction: column; align-items: center; gap: .25rem; }
.ah-perc .glifo { font-family: var(--jp); font-size: 1.05rem; line-height: 1; color: var(--text); }
.ah-perc .corpo { flex: 1; min-width: 0; }
.ah-perc .titolo { font-weight: 600; }
.ah-perc .meta { color: var(--muted); font-size: .85rem; }

/* Le mie tessere: carta scura, come un budopass fisico (uguale nei due temi). */
.ah-tessere-tit { font-size: 9.5px; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); opacity: .8; margin-bottom: .1rem; }
.ah-tessera { border-radius: var(--raggio); padding: 1rem; border: 1px solid var(--border);
  background: linear-gradient(135deg, #2A2620, #3A3025); color: #F2ECDD; }
.ah-tessera .r { display: flex; align-items: center; gap: .6rem; margin-bottom: .8rem; }
.ah-tessera .mk { flex: 0 0 auto; width: 38px; height: 38px; border-radius: 9px;
  background: rgba(255, 255, 255, .12); display: flex; align-items: center; justify-content: center; font-weight: 600; }
.ah-tessera .en { font-weight: 600; }
.ah-tessera .en small { display: block; font-weight: 400; opacity: .7; font-size: .78rem; }
.ah-tessera .num { font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 1.1rem; letter-spacing: .1em; }
.ah-tessera .apri { display: inline-block; margin-top: .6rem; color: #F2ECDD; opacity: .85; font-size: .85rem; }
.ah-tessera .apri:hover { opacity: 1; text-decoration: none; }

/* === Bacheca / notizie (budopass_notizie_gestione|allievo.html) ==========
   Gestione: elenco (fissate prima) + editor con anteprima viva del feed. Allievo: feed di
   card e dettaglio. I colori stanno qui; i toni di stato non seguono l'accento. */

/* Testata di pagina con azione a destra (＋ Nuova notizia). */
.nz-head { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.nz-head h1 { margin: 0; }
.nz-head .spazio { flex: 1; }

/* --- elenco gestione --- */
/* Le notizie della gestione a tutta larghezza, due per riga quando ci stanno (3 set): la colonna da
   760px lasciava mezzo schermo vuoto. */
.nz-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(440px, 1fr)); gap: .8rem; }
.nz-item {
  display: flex; gap: .9rem; padding: .8rem;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--raggio); box-shadow: var(--ombra);
}
.nz-cover {
  flex: 0 0 120px; width: 120px; height: 84px; border-radius: var(--raggio-s); overflow: hidden;
  background: var(--page-tenue); display: flex; align-items: center; justify-content: center;
}
.nz-cover img { width: 100%; height: 100%; object-fit: cover; }
.nz-cover.k span { font-family: var(--jp); font-size: 2rem; color: var(--muted); opacity: .45; }
.nz-body { flex: 1; min-width: 0; }
.nz-r1 { display: flex; align-items: center; gap: .4rem; }
.nz-r1 h3 { margin: 0; font-size: 1rem; }
.nz-pin { flex: 0 0 auto; }
.nz-snip {
  margin: .3rem 0 .4rem; color: var(--muted); font-size: .88rem; white-space: pre-wrap;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.nz-meta { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; font-size: .8rem; color: var(--muted); }
.nz-chip {
  display: inline-block; font-size: .72rem; padding: .1rem .45rem; border-radius: 999px;
  border: 1px solid var(--border); background: var(--page-tenue);
}
.nz-chip.pin { background: var(--warn-bg); color: var(--warn-text); border-color: var(--warn); }
.nz-act { display: flex; flex-direction: column; gap: .3rem; flex: 0 0 auto; }
.nz-ib {
  width: 30px; height: 30px; padding: 0; border: 1px solid var(--border); border-radius: var(--raggio-s);
  background: transparent; color: var(--muted); cursor: pointer;
}
.nz-ib:hover { background: var(--riga-hover); color: var(--text); }

/* --- editor --- */
.nz-ed { display: grid; grid-template-columns: 1.35fr .9fr; gap: 1rem; align-items: start; max-width: 900px; }
@media (max-width: 820px) { .nz-ed { grid-template-columns: 1fr; } }
.nz-big { font-size: 1.05rem; font-weight: 600; }

/* Dropzone copertina: tratteggiata, mostra l'anteprima quando c'è. */
.nz-drop {
  border: 1.5px dashed var(--border); border-radius: var(--raggio-s); min-height: 120px; cursor: pointer;
  overflow: hidden; text-align: center; display: flex; align-items: center; justify-content: center; color: var(--muted);
}
.nz-drop:hover { border-color: var(--accent); }
.nz-drop input { display: none; }
.nz-drop img { width: 100%; height: 180px; object-fit: cover; display: block; }
.nz-drop-txt { padding: 1.5rem; font-size: .9rem; }
.nz-drop-txt small { color: var(--muted); opacity: .8; }
.link-rimuovi {
  display: inline-block; margin-top: .4rem; background: none; border: none; padding: 0;
  color: var(--accent-text); font-size: .82rem; cursor: pointer;
}

/* Destinatari: righe selezionabili con spunta e conteggio. */
.nz-aud {
  display: flex; align-items: center; gap: .6rem; margin-bottom: .5rem;
  padding: .6rem .7rem; border: 1px solid var(--border); border-radius: var(--raggio-s); cursor: pointer;
}
.nz-aud.on { border-color: var(--accent); background: var(--accent-tenue); }
.nz-aud .cbx {
  flex: 0 0 auto; width: 18px; height: 18px; border: 1.5px solid var(--muted); border-radius: 4px;
  display: flex; align-items: center; justify-content: center; font-size: .72rem;
}
.nz-aud.on .cbx { border-color: var(--accent); background: var(--accent); color: var(--accent-on); }
.nz-aud .al { flex: 1; min-width: 0; }
.nz-aud .al b { display: block; }
.nz-aud .al span { font-size: .8rem; color: var(--muted); }
.nz-aud .cnt { font-weight: 600; color: var(--muted); }

/* Interruttori (fissa / push). */
.nz-sw { display: flex; align-items: center; gap: .6rem; padding: .6rem 0 0; }
.nz-sw .al { flex: 1; }
.nz-sw .al b { display: block; }
.nz-sw .al span { font-size: .8rem; color: var(--muted); }
.nz-tog {
  flex: 0 0 auto; width: 38px; height: 22px; border-radius: 999px; border: none;
  background: var(--border); position: relative; cursor: pointer; transition: background .15s;
}
.nz-tog.on { background: var(--accent); }
.nz-tog::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%;
  background: #fff; transition: left .15s;
}
.nz-tog.on::after { left: 18px; }

.nz-foot { display: flex; align-items: center; gap: .6rem; margin-top: 1rem; max-width: 900px; }
.nz-foot .spazio { flex: 1; }

/* --- feed dell'allievo + anteprima gestione (stessa card) --- */
.nz-fc { position: relative; border: 1px solid var(--border); border-radius: var(--raggio); overflow: hidden;
  background: var(--card); box-shadow: var(--ombra); }
.nz-fc.clic { cursor: pointer; }
.nz-fc.clic:hover { border-color: var(--accent); }
/* La × d'archivio sta sopra la copertina: un pallino scuro semitrasparente, sennò sparisce
   sull'immagine. z-index sopra la cover; il click ferma la propagazione al dettaglio. */
.nz-fcv { position: relative; height: 140px; background: var(--page-tenue);
  display: flex; align-items: center; justify-content: center; }
.nz-fcv img { width: 100%; height: 100%; object-fit: cover; }
.nz-fcv.k span { font-family: var(--jp); font-size: 2.4rem; color: var(--muted); opacity: .5; }
.nz-fcm { padding: .85rem; }
.nz-fcm h4 { margin: .3rem 0 .2rem; font-size: 1.05rem; }
.nz-fcm .more { display: inline-block; margin-top: .35rem; font-size: .85rem; color: var(--accent-text); }
.nz-ent { display: flex; align-items: center; gap: .4rem; font-size: .8rem; color: var(--muted); }
.nz-ent .mk {
  flex: 0 0 auto; width: 24px; height: 24px; border-radius: 6px; background: var(--accent-tenue);
  color: var(--accent-text); display: flex; align-items: center; justify-content: center;
  font-size: .7rem; font-weight: 600;
}

/* --- dettaglio notizia (allievo): la copertina e il testo restano SUOI (15) — la copertina è
   l'arte della pagina e il testo va a capo come l'ha scritto l'ente; non sono pezzi. --- */
.nz-dcover { height: 200px; border-radius: var(--raggio); overflow: hidden; background: var(--page-tenue);
  display: flex; align-items: center; justify-content: center; margin-bottom: 1rem; }
.nz-dcover img { width: 100%; height: 100%; object-fit: cover; }
.nz-dcover.k span { font-family: var(--jp); font-size: 3rem; color: var(--muted); opacity: .5; }
.nz-txt { white-space: pre-wrap; line-height: 1.6; }

/* Home allievo: mini-righe «Ultime notizie». */
.nz-mini { display: flex; gap: .6rem; padding: .5rem 0; border-bottom: 1px solid var(--border); }
.nz-mini:last-of-type { border-bottom: none; }
.nz-mini .mc { flex: 0 0 44px; width: 44px; height: 44px; border-radius: var(--raggio-s); overflow: hidden;
  background: var(--page-tenue); display: flex; align-items: center; justify-content: center; }
.nz-mini .mc img { width: 100%; height: 100%; object-fit: cover; }
.nz-mini .mc.k span { font-family: var(--jp); font-size: 1.1rem; color: var(--muted); opacity: .5; }
.nz-mini .mb { flex: 1; min-width: 0; }
.nz-mini .mb .t { font-weight: 500; font-size: .92rem; }
.nz-mini .mb .e { font-size: .78rem; color: var(--muted); }

/* === Centro notifiche: campana + pannello (budopass_notifiche.html) =======
   Campana in testata col badge delle non lette; un pannello a discesa con la lista, le
   non lette in evidenza (tinta + grassetto + pallino). I toni di stato non seguono l'accento. */

.camp { position: relative; display: inline-flex; }
.camp-btn { position: relative; }
.camp-badge {
  position: absolute; top: -3px; right: -3px; min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 999px; background: var(--accent); color: var(--accent-on);
  border: 2px solid var(--card-alta); font-size: .68rem; font-weight: 700; line-height: 13px;
  display: inline-flex; align-items: center; justify-content: center;
}

.camp-backdrop { position: fixed; inset: 0; z-index: 40; }
.camp-panel {
  position: absolute; top: calc(100% + .35rem); right: 0; width: 340px; max-width: 92vw; z-index: 50;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--raggio);
  box-shadow: var(--ombra-alta, 0 12px 32px rgba(0, 0, 0, .18)); overflow: hidden;
}
.camp-testa { display: flex; align-items: center; gap: .5rem; padding: .7rem .85rem; border-bottom: 1px solid var(--border); }
.camp-testa .spazio { flex: 1; }
.camp-testa a { font-size: .78rem; }

.camp-vuoto { padding: 1.8rem 1rem; text-align: center; color: var(--muted); }
.camp-vuoto .grande { font-weight: 600; color: var(--text); margin-bottom: .2rem; }

.camp-lista { max-height: 60vh; overflow-y: auto; }
.camp-riga {
  position: relative; display: flex; align-items: center; gap: .6rem; width: 100%; text-align: left;
  padding: .6rem .7rem; background: transparent; border: none;
  border-bottom: 1px solid var(--border); cursor: pointer; color: var(--text);
}
.camp-riga:last-child { border-bottom: none; }
.camp-riga:hover { background: var(--riga-hover); }
.camp-riga.un { background: var(--page-tenue); }
.camp-riga.un .t { font-weight: 700; }
/* (Il pallino «non letta» delle righe della campana è sparito il 4 set: lo sfondo diverso e il
   grassetto del titolo lo dicono già, e sporgeva a sinistra della riga.) */
.camp-ico {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--jp); font-size: .95rem;
}
.camp-ico.news    { background: var(--page-tenue);   color: var(--muted); }
.camp-ico.aff     { background: var(--ok-bg);        color: var(--ok-text); }
.camp-ico.grado   { background: var(--accent-tenue); color: var(--accent-text); }
.camp-ico.avv     { background: var(--warn-bg);      color: var(--warn-text); font-family: var(--sans); font-weight: 700; }
.camp-ico.sistema { background: var(--page-tenue);   color: var(--muted); }
.camp-tx { flex: 1; min-width: 0; }
.camp-tx .t { display: block; font-size: .9rem; font-weight: 500; }
.camp-tx .b {
  display: block; font-size: .8rem; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.camp-tm { flex: 0 0 auto; font-size: .74rem; color: var(--muted); align-self: flex-start; padding-top: .1rem; }
.camp-piede { text-align: center; padding: .55rem; border-top: 1px solid var(--border); }
.camp-piede a { font-weight: 600; font-size: .85rem; }

/* === Comunicazioni di sistema (budopass_comunicazioni.html) ===============
   Composizione a due colonne (form + anteprima nella campana), selettore di segmento coi
   conteggi, e il dialogo di conferma con il numero sul bottone. Solo admin di piattaforma. */

.com-ed { display: grid; grid-template-columns: 1.4fr .9fr; gap: 1rem; align-items: start; max-width: 900px; }
@media (max-width: 820px) { .com-ed { grid-template-columns: 1fr; } }
.com-foot { display: flex; gap: .6rem; margin-top: 1rem; max-width: 900px; }

/* Selettore di segmento: opzioni a radio con il conteggio a destra. */
.com-seg { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }
@media (max-width: 560px) { .com-seg { grid-template-columns: 1fr; } }
.com-so {
  display: flex; align-items: center; gap: .6rem; text-align: left; cursor: pointer;
  padding: .6rem .7rem; border: 1px solid var(--border); border-radius: var(--raggio-s); background: transparent;
}
.com-so.on { border-color: var(--accent); background: var(--accent-tenue); }
.com-so .rd { flex: 0 0 auto; width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--muted); }
.com-so.on .rd { border-color: var(--accent); background: radial-gradient(var(--accent) 42%, transparent 46%); }
.com-so .l { flex: 1; min-width: 0; }
.com-so .l b { display: block; font-size: .9rem; }
.com-so .l span { font-size: .78rem; color: var(--muted); }
.com-so .cnt { font-weight: 600; color: var(--muted); }
.com-so.on .cnt { color: var(--accent-text); }

/* Il picker dell'ente (riusa la ricerca enti — solo nomi). */
.com-ente { margin-top: .6rem; }
.com-ente input { margin-bottom: .4rem; }
.com-ente-lista { border: 1px solid var(--border); border-radius: var(--raggio-s); overflow: hidden; }
.com-ente-riga {
  display: flex; align-items: center; gap: .5rem; width: 100%; text-align: left; padding: .45rem .6rem;
  background: transparent; border: none; border-bottom: 1px solid var(--border); cursor: pointer; color: var(--text);
}
.com-ente-riga:last-child { border-bottom: none; }
.com-ente-riga:hover { background: var(--riga-hover); }
.com-ente-scelto {
  display: flex; align-items: center; gap: .5rem; padding: .45rem .6rem;
  border: 1px solid var(--accent); background: var(--accent-tenue); border-radius: var(--raggio-s);
}
.com-ente-scelto .nome { font-weight: 500; }

.com-dest { margin: .8rem 0 0; color: var(--muted); font-size: .9rem; }
.com-dest b { color: var(--accent-text); font-size: 1rem; }

/* L'anteprima: la stessa riga della campana. */
.com-prev { display: flex; align-items: center; gap: .6rem; padding: .3rem; }

/* Dialogo di conferma (sopra .modale-fondo). */
.com-dlg {
  width: 420px; max-width: 94vw; background: var(--card); border: 1px solid var(--border);
  border-radius: var(--raggio); box-shadow: var(--ombra-alta, 0 16px 40px rgba(0, 0, 0, .24)); padding: 1.25rem;
}
.com-rec { margin: 0 0 .2rem; }
.com-rec b { color: var(--text); }

/* === Statistiche di piattaforma (budopass_statistiche.html) ===============
   KPI, grafici a serie unica (un accento, griglia recessiva), lo split enti attivi/dormienti
   (verde/neutro con etichette), la striscia dei totali. Dataviz: mai due assi, mai colore da
   solo. I colori dei marchi SVG stanno nelle classi, così seguono il tema. */

.st-head { display: flex; align-items: center; gap: 1rem; margin-bottom: .2rem; flex-wrap: wrap; }
.st-head h1 { margin: 0; }
.st-head .spazio { flex: 1; }

/* KPI */
.st-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: .8rem; margin: 1.25rem 0; }
@media (max-width: 760px) { .st-kpis { grid-template-columns: repeat(2, 1fr); } }
.st-kpi {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--raggio);
  box-shadow: var(--ombra); padding: 1rem;
}
.st-kpi .lb { color: var(--muted); font-size: .78rem; }
.st-kpi .v { font-size: 1.7rem; font-weight: 600; line-height: 1.1; letter-spacing: -.01em; }
.st-kpi .v small { font-size: .95rem; color: var(--muted); font-weight: 400; }
.st-kpi .d { font-size: .78rem; margin-top: .25rem; }
.st-kpi .d.up { color: var(--ok-text); }
.st-kpi .d.down { color: var(--err-text); }
.st-kpi .d.mut { color: var(--muted); }

/* Il numero «Utenti attivi» E' LA PORTA di «Statistiche › Utenti» (§31 ago): la pagina non ha
   voce di menu, si entra da qui. E' un <button> vero, non un div con un @onclick — la tastiera lo
   raggiunge, lo screen reader lo annuncia, e il focus si vede. Il vestito lo riporta a essere il
   numero che era: nessun bordo, nessuno sfondo, il carattere del KPI. */
.st-kpi.porta .v {
  font: inherit; font-size: 1.7rem; font-weight: 600; line-height: 1.1; letter-spacing: -.01em;
  border: 0; background: none; padding: 0; margin: 0; cursor: pointer;
  color: var(--accent-text); display: inline-flex; align-items: center; gap: .3rem;
  border-bottom: 1.5px solid var(--accent-tenue); font-variant-numeric: tabular-nums;
}
.st-kpi.porta .v:hover { border-bottom-color: var(--accent); }
.st-kpi.porta .v:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }
.st-kpi.porta .v .fr { font-size: .9rem; font-weight: 500; }

/* Grafici */
.st-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 760px) { .st-grid2 { grid-template-columns: 1fr; } }
.st-card {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--raggio);
  box-shadow: var(--ombra); padding: 1rem;
}
.st-ct { display: flex; align-items: baseline; gap: .5rem; margin-bottom: .5rem; }
.st-ct b { font-size: .95rem; }
.st-ct span { margin-left: auto; color: var(--muted); font-size: .78rem; }
.st-svg { width: 100%; height: auto; display: block; }

/* Marchi SVG — un solo accento per le serie uniche; verde/neutro per lo split. */
.st-grid { stroke: var(--border); stroke-width: 1; }
.st-area { fill: var(--accent-tenue); opacity: .55; }
.st-line { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.st-dot { fill: var(--accent); }
.st-bar { fill: var(--accent); }
.st-vlab { fill: var(--muted); font-size: 10px; font-weight: 600; font-family: var(--sans); }
.st-xlab { fill: var(--muted); opacity: .8; font-size: 9.5px; font-family: var(--sans); }
.st-attivi { fill: var(--ok); }
.st-dormienti { fill: var(--neutro, #C9C2B4); }

.st-legend { display: flex; gap: 1.2rem; margin-top: .6rem; font-size: .82rem; color: var(--muted); }
.st-legend .pt { display: inline-flex; align-items: center; gap: .35rem; }
.st-legend .dot { width: 10px; height: 10px; border-radius: 3px; }
.st-legend .dot.ok { background: var(--ok); }
.st-legend .dot.neu { background: var(--neutro, #C9C2B4); }

/* Totali */
.st-tot {
  display: flex; flex-wrap: wrap; gap: 1.8rem; margin-top: 1.25rem; padding: 1rem 1.1rem;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--raggio); box-shadow: var(--ombra);
}
.st-tot .it b { display: block; font-size: 1.3rem; font-weight: 600; line-height: 1.1; }
.st-tot .it span { color: var(--muted); font-size: .8rem; }

/* === Eliminazione di una notifica (× sulla riga) ==========================
   Nascosta di default, compare sull'hover della riga (pattern desktop) e diventa rossa al
   passaggio; prende il posto dell'ora. Su touch (niente hover) resta sempre visibile. */
.camp-del {
  position: absolute; top: 50%; right: .45rem; transform: translateY(-50%);
  width: 28px; height: 28px; border-radius: 50%; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--muted); font-size: .8rem; cursor: pointer;
  opacity: 0; transition: opacity .12s ease, background .12s ease, color .12s ease;
}
.camp-riga:hover .camp-del { opacity: 1; }
.camp-riga:hover .camp-tm { opacity: 0; }
.camp-del:hover { background: var(--err-bg); color: var(--err-text); }
@media (hover: none) {
  .camp-del { opacity: 1; }
  .camp-riga .camp-tm { opacity: 0; }
}

/* Anteprima gradi nella scheda corso (§10, 2ª parte): campione curato reso col VERO
   SegnoGrado, che si ridisegna al cambio dei comandi. Il segno riusa i cap SVG di .segno. */
.cg-anteprima { display: flex; flex-wrap: wrap; gap: 14px; }
.cg-cella { width: 112px; }
.cg-segno { min-height: 52px; display: flex; align-items: center; }
.cg-testo { margin-top: 5px; font-size: .86rem; font-weight: 600; min-height: 1.1em; color: var(--text); }
.cg-testo.vuoto { color: var(--muted); }
.cg-sub { font-size: .7rem; color: var(--muted); }

/* ===== controlli di selezione d'inchiostro (mockup budopass_controlli_corso.html) =========
   Due controlli, una regola: Spunta per le liste multi-scelta, Interruttore per gli on/off
   singoli. Niente <input type="checkbox"> grezzo. */

/* Spunta: riquadro 22px, da spuntato pieno d'ACCENTO (come .nz-aud .cbx) con la spunta in
   --accent-on. Tutta la riga è bersaglio, con hover e stato selezionato. */
.spunta {
  display: flex; align-items: center; gap: .7rem;
  padding: .45rem .55rem; border-radius: var(--raggio-s);
  cursor: pointer; user-select: none;
}
.spunta:not(.dis):hover { background: var(--riga-hover); }
.spunta.on { background: var(--accent-tenue); }
.spunta.dis { opacity: .45; cursor: default; }
.spunta-box {
  width: 22px; height: 22px; flex: none;
  border: 1.5px solid var(--cintura-contorno); border-radius: 6px; background: var(--card);
  display: flex; align-items: center; justify-content: center;
  transition: background .12s, border-color .12s;
}
.spunta-box svg {
  width: 15px; height: 15px; fill: none; stroke: var(--accent-on); stroke-width: 2.6;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: 0; transform: scale(.6); transition: opacity .12s, transform .12s;
}
.spunta:not(.dis):hover .spunta-box { border-color: var(--accent); }
.spunta.on .spunta-box { background: var(--accent); border-color: var(--accent); }
.spunta.on .spunta-box svg { opacity: 1; transform: scale(1); }
.spunta-testo { font-size: .9rem; }

/* Interruttore: pillola 42×24, grigio spento / accento acceso, pomello bianco che scorre.
   Testo (titolo + descrizione) a sinistra, toggle a destra, tutta la riga cliccabile. */
.interruttore-riga {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .2rem 0; cursor: pointer; user-select: none;
}
.interruttore-riga.dis { opacity: .45; cursor: default; }
.interruttore-testo b { display: block; font-size: .92rem; font-weight: 600; }
.interruttore-testo span { display: block; font-size: .78rem; color: var(--muted); }
.swi {
  width: 42px; height: 24px; flex: none; border-radius: 20px;
  background: var(--border); position: relative; transition: background .15s;
}
.swi::after {
  content: ""; position: absolute; width: 18px; height: 18px; border-radius: 50%;
  background: #fff; top: 3px; left: 3px; box-shadow: 0 1px 2px rgba(0,0,0,.25);
  transition: left .15s;
}
.swi.on { background: var(--accent); }
.swi.on::after { left: 21px; }

/* ===== schede (tab) di pagina ===== */
.schede { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin-bottom: 1rem; }
.scheda {
  font-family: var(--sans); font-size: .9rem; color: var(--muted);
  background: transparent; border: none; border-bottom: 2px solid transparent;
  padding: .55rem 1rem; margin-bottom: -1px; cursor: pointer;
}
.scheda:hover { color: var(--text); }
.scheda.attiva { color: var(--accent); font-weight: 700; border-bottom-color: var(--accent); }
.scheda-badge {
  font-size: .68rem; background: var(--accent-tenue); color: var(--accent-text);
  border-radius: 20px; padding: 0 .45rem; margin-left: .4rem; font-weight: 600;
}

/* ===== Impostazioni ente: una colonna sola (25 ago) ========================= */
/* .imp-griglia e .imp-lato non esistono più: la colonna destra era un menù travestito da
   colonna (sei piastrelle e la card «Gestione»), e con quelle partite resta un form. Qui c'era
   anche una SECONDA definizione di .imp-griglia che vinceva su quella di Impostazioni utente
   (~riga 816, grid a due colonne con la sua misura): togliendola, quella pagina torna alla
   griglia che il suo commento descrive. La misura del form è esplicita — un modulo si legge in
   una larghezza sola, e senza tetto le righe di testo diventano illeggibili sui monitor larghi. */
/* Pila, non blocchi accostati: .carta non ha margine proprio (vedi la nota su .ev-sez), e in una
   colonna sola le sezioni finivano separate dalla sola ombra. Il gap è 1rem, lo stesso ritmo di
   .griglia, .imp-col e delle carte-sezione degli eventi: è LO standard dell'app per carte
   impilate, non un numero scelto qui. */
.imp-form { display: grid; gap: 1rem; align-content: start; max-width: 640px; }

/* Due righe di campi non sono un blocco solo. `.det-campi` non porta un margine suo (~riga 923) e
   ai `.campo` che contiene lo toglie (~riga 924, giusto: in riga stanno affiancati, non impilati);
   l'unico posto che gliene fornisce uno è `.det-forma` (~riga 964), e questa pagina non lo è. Il
   `gap` qui sopra non le raggiunge, perché le righe vivono DENTRO una <Carta> e non come figlie
   dirette della griglia: Comune/Provincia/Cap e Telefono/Email/Sito web si leggevano come un
   unico blocco di sei campi, mentre Nazione e Indirizzo sopra respiravano.

   `.9rem` e non `.75rem`: qui i vicini di una riga sono `.campo`, che stanno a `.9rem` (~riga
   1111), e la carta si legge con un ritmo solo. Il `.75rem` è il ritmo di `.det-forma`, non una
   costante di casa da ricopiare.

   `:not(:last-child)`: la riga che CHIUDE una carta non deve aprirle il fondo. <Carta> mette
   `@ChildContent` dentro `.carta` senza niente dopo, quindi `:last-child` vuol dire quello che
   sembra.

   Circoscritta a `.imp-form`, mai a `.det-campi` in generale: vedi la nota alla ~riga 929 — quel
   contenitore porta in giro per l'app decine di pesi scritti a mano, e un margine globale
   sposterebbe pagine che oggi stanno bene e che nessuno sta guardando. */
.imp-form .det-campi:not(:last-child) { margin-bottom: .9rem; }

/* Le due sezioni di comportamento (ex card «Gestione», 17 ago). La modalità di scadenza — che
   compare sotto l'interruttore acceso — rientra con un filetto, così si legge come sua sottopiega;
   il divisore stacca i due interruttori dentro la stessa carta. Il nome del prefisso resta quello
   della card da cui vengono.

   `.imp-gestione` (la carta) non c'è più: dava un margine proprio a una carta che ora sta in una
   pila con un gap suo, e i due margini si sommavano rompendo il ritmo. Le due regole qui sotto
   valgono da sole — non sono discendenti di quella. */
.imp-gestione-sub { margin: .55rem 0 .2rem; padding-left: .55rem; border-left: 2px solid var(--border); }
.imp-gestione-div { border-top: 1px solid var(--border); margin: .7rem 0; }

/* La riga di navigazione DENTRO una carta: icona, titolo, dettaglio, chevron. Eredita il posto
   delle vecchie .gestione-tile — stesse misure — ma senza fondo né bordo propri: la carta che la
   contiene è già la scatola, e un riquadro dentro un riquadro leggeva come un secondo livello che
   non c'è. Ne resta UNA sola in tutta la pagina, il cartello check-in. Il chevron è in accento
   come sull'app: dice che si va altrove, non che c'è un campo da compilare. */
.imp-nav {
  display: flex; align-items: center; gap: .75rem;
  color: var(--text); text-decoration: none; cursor: pointer;
}
.imp-nav:hover { text-decoration: none; }
.imp-nav:hover .imp-nav-corpo b { color: var(--accent-text); }
.imp-nav-ico {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-tenue); color: var(--accent-text);
}
.imp-nav-ico svg { width: 18px; height: 18px; }
.imp-nav-corpo { flex: 1; min-width: 0; }
.imp-nav-corpo b { display: block; font-size: .92rem; }
.imp-nav-corpo span { display: block; font-size: .78rem; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.imp-nav-chev { flex: 0 0 auto; color: var(--accent); font-size: 1.1rem; }

/* ===== Eventi (pilastro eventi) ============================================= */
/* Lista: righe-card cliccabili verso il dettaglio/gestione. */
.ev-lista { display: flex; flex-direction: column; gap: .6rem; }
.ev-riga { display: flex; align-items: center; gap: .9rem; padding: .75rem .85rem;
  border: 1px solid var(--border); border-radius: var(--raggio-s); background: var(--card);
  text-decoration: none; color: var(--text); cursor: pointer; }
.ev-riga:hover { background: var(--riga-hover); border-color: var(--accent); }
.ev-cover-mini { flex: 0 0 auto; width: 46px; height: 46px; border-radius: 8px;
  background: var(--accent-tenue); color: var(--accent-text);
  display: flex; align-items: center; justify-content: center; font-family: var(--jp); font-size: 1.2rem; }
.ev-riga-corpo { flex: 1; min-width: 0; }
.ev-riga-corpo b { display: block; }
.ev-riga-corpo span { display: block; font-size: .8rem; color: var(--muted); }

/* Pill di stato / consenso / ruolo. */
.ev-pill { font-size: .68rem; padding: .1rem .5rem; border-radius: 20px; font-weight: 600; white-space: nowrap; }
.ev-pill.org { background: var(--accent-tenue); color: var(--accent-text); }
.ev-pill.ok { background: var(--ok-bg); color: var(--ok-text); }
.ev-pill.wait { background: var(--warn-bg); color: var(--warn-text); }
.ev-pill.no { background: var(--err-bg); color: var(--err-text); }
.ev-pill.neutro { background: var(--page-tenue); color: var(--muted); }

/* Editor: testata di sezione numerata (dentro una .carta). */
.ev-sez-num { flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent); color: var(--accent-on); font-size: .75rem;
  display: inline-flex; align-items: center; justify-content: center; margin-right: .5rem; }

/* Riga ente (organizzazione) e riga sessione. */
.ev-rolo { display: flex; align-items: center; gap: .7rem; padding: .55rem 0; border-top: 1px dashed var(--border); }
.ev-rolo:first-of-type { border-top: none; }
.ev-logo { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 7px;
  background: var(--accent-tenue); color: var(--accent-text);
  display: flex; align-items: center; justify-content: center; font-family: var(--jp); }
/* Il logo vero dell'ente al posto del kanji (3 set); le iniziali quando manca. */
img.ev-logo { object-fit: cover; }
.ev-logo.ini { font-family: var(--sans); font-weight: 600; font-size: .7rem; letter-spacing: .02em; }
/* I loghi davanti a una riga di seminar in home (3 set): l'organizzatore e i partner, a scalare. */
.loghi-ev { display: flex; align-items: center; }
.logo-ev { width: 30px; height: 30px; border-radius: 8px; object-fit: cover; flex: 0 0 auto;
  border: 2px solid var(--card); background: var(--accent-tenue); color: var(--accent-text);
  display: inline-flex; align-items: center; justify-content: center; font-weight: 600; font-size: .68rem; }
.logo-ev + .logo-ev { margin-left: -9px; }
.ev-rolo-corpo { flex: 1; min-width: 0; }
.ev-rolo-corpo b { font-size: .9rem; }
.ev-rolo-corpo span { display: block; font-size: .74rem; color: var(--muted); }
.ev-sess { display: flex; align-items: center; gap: .7rem; padding: .5rem .6rem;
  border: 1px solid var(--border); border-radius: var(--raggio-s); margin-bottom: .5rem; background: var(--card); }
.ev-sess-ico { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px;
  background: var(--page-tenue); display: flex; align-items: center; justify-content: center; font-size: 1rem; }
.ev-sess-corpo { flex: 1; min-width: 0; }
.ev-sess-corpo b { font-size: .88rem; }
.ev-sess-corpo span { display: block; font-size: .74rem; color: var(--muted); }
.ev-addlink { margin-top: .5rem; font-size: .85rem; color: var(--accent); font-weight: 600;
  background: none; border: none; cursor: pointer; padding: .2rem 0; }

/* Wizard di creazione: indicatore di passo (WA-1). */
.ev-stepper { display: flex; align-items: center; gap: .35rem; margin: .4rem 0 .2rem; flex-wrap: wrap; }
.ev-step { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%; font-size: .8rem; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--page-tenue); color: var(--muted); border: 1px solid var(--border); }
.ev-step.attivo { background: var(--accent); color: var(--accent-on); border-color: var(--accent); }
.ev-step.fatto { background: var(--accent-tenue); color: var(--accent-text); border-color: var(--accent-tenue); }
.ev-step-linea { flex: 1; height: 2px; min-width: 6px; background: var(--border); }

/* Dettaglio: cover + blocchi + requisiti. */
.ev-cover { height: 130px; border-radius: var(--raggio) var(--raggio) 0 0; position: relative;
  background: linear-gradient(135deg, #2b2f3a, #3d4657 60%, #5a4636); display: flex; align-items: flex-end; }
.ev-cover .kv { position: absolute; inset: 0; opacity: .16; font-size: 110px; color: #fff;
  display: flex; align-items: center; justify-content: center; font-family: var(--jp); }
.ev-cover h1 { position: relative; color: #fff; margin: 0; padding: .8rem 1rem; font-size: 1.3rem; text-shadow: 0 1px 4px rgba(0,0,0,.4); }
.ev-blocco { padding: .9rem 0; border-top: 1px solid var(--border); }
.ev-blocco h4 { margin: 0 0 .5rem; font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.ev-req { display: flex; align-items: center; gap: .5rem; font-size: .88rem; padding: .2rem 0; }
.ev-req-mk { flex: 0 0 auto; width: 18px; height: 18px; border-radius: 50%; color: #fff;
  display: inline-flex; align-items: center; justify-content: center; font-size: .7rem; }
.ev-req-mk.si { background: var(--ok); } .ev-req-mk.no { background: var(--err); }
.ev-barrato { background: var(--warn-bg); border: 1px solid var(--warn); border-radius: var(--raggio-s);
  padding: .6rem .8rem; font-size: .85rem; color: var(--warn-text); }
.ev-indicazioni { display: inline-flex; align-items: center; gap: .3rem; font-size: .78rem; color: var(--accent);
  text-decoration: none; border: 1px solid var(--accent-tenue); border-radius: 20px; padding: .1rem .6rem; }

/* Check-in dashboard. */
.ck-hd { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.ck-stats { display: flex; gap: 1.2rem; font-size: .85rem; color: var(--muted); margin: .6rem 0; }
.ck-stats b { color: var(--text); }
.ck-riga { display: flex; align-items: center; gap: .8rem; padding: .6rem 0; border-top: 1px solid var(--border); }
.ck-av { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; background: var(--accent-tenue);
  color: var(--accent-text); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: .8rem; }
.ck-corpo { flex: 1; min-width: 0; }
.ck-corpo b { font-size: .9rem; }
.ck-corpo span { display: block; font-size: .76rem; color: var(--muted); }
.ck-stato { display: inline-flex; align-items: center; gap: .3rem; font-size: .82rem; font-weight: 600; }
.ck-stato.ok { color: var(--ok-text); } .ck-stato.warn { color: var(--warn-text); }
.ck-panel { margin-top: 1rem; border: 1px solid var(--warn); background: var(--warn-bg); border-radius: var(--raggio-s); padding: .7rem .9rem; }
.ck-panel h4 { margin: 0 0 .4rem; font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--warn-text); }
.ck-panel .drow { font-size: .82rem; color: var(--warn-text); padding: .15rem 0; }
.bottone.ammetti { background: var(--warn); border-color: var(--warn); color: #fff; }

/* ===== «Il mio percorso» — la linea del tempo (mockup budopass_percorso_timeline.html) =====
   Le posizioni le mette il componente in stile inline (px sulla larghezza vera); qui c'è solo la
   forma. Colori dal tema (--perc-* e l'accento), mai hex nel componente; il colore del pallino
   (--c) è invece un DATO del grado, passato inline. */
.ln { position: relative; margin: 8px 0 0; height: var(--h); }
/* Le posizioni calcolate arrivano come --x/--y/--w/--h dal componente (8). */
.ln > * { left: var(--x); }
.ln .annoT, .ln .gam, .ln .eti, .ln .pt, .ln .pill { top: var(--y); }
.ln i { width: var(--w); }
.ln .gam { height: var(--h); }
.ln.apribile { cursor: pointer; }
.ln i { position: absolute; top: var(--asse); transform: translateY(-50%); display: block; }
.ln i.rot  { background: var(--perc-track); border-radius: 3px; height: 4px; }
.ln i.pat  { background: var(--perc-pieno); border-radius: 3px; height: 4px; }
.ln i.ferm { background: repeating-linear-gradient(90deg, var(--perc-tratto) 0 2px, transparent 2px 6px); height: 2px; }
.ln .inizio, .ln .oggi { position: absolute; top: var(--asse); transform: translate(-50%,-50%); width: 3px; height: 13px; border-radius: 2px; }
.ln .inizio { background: var(--perc-gambo); }
.ln .oggi { background: var(--accent); }
.ln .oggi.chiusa { background: var(--perc-gambo); }
.ln .gam { position: absolute; width: 1.5px; background: var(--perc-gambo); transform: translateX(-50%); }
.ln .pt { position: absolute; transform: translate(-50%,-50%); width: 10px; height: 10px; border-radius: 50%;
  background: var(--c); box-shadow: 0 0 0 2px var(--card); border: 1px solid rgba(0,0,0,.18); cursor: pointer; }
.ln .pt.dich { background: var(--card); border: 2px solid var(--c); }
.ln .pt.neutro { background: var(--muted); }
.ln .pt.neutro.dich { background: var(--card); border-color: var(--muted); }
.ln .pt.ultimo { width: 15px; height: 15px; box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--accent-tenue); }
.ln .eti { position: absolute; transform: translate(-50%,-50%); font-size: 9.5px; font-weight: 600; color: var(--text); white-space: nowrap; }
.ln .eti em { font-style: normal; font-weight: 500; color: var(--muted); }
.ln .anno { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--border); }
.ln .annoT { position: absolute; font-size: 9.5px; color: var(--muted); transform: translateX(-50%); }
/* La pillola è un tooltip scuro fisso (non segue il tema): deve staccarsi dalla card, chiara o scura. */
.ln .pill { position: absolute; background: #2B2723; color: #F6F2E9; font-size: 10.5px; font-weight: 600;
  padding: 3px 8px; border-radius: 20px; white-space: nowrap; pointer-events: none; opacity: 0;
  transition: opacity .12s; z-index: 5; transform: translate(-50%,-50%); }
.ln .pill.on { opacity: 1; }

/* Blocco disciplina della card: token a sinistra del nome, niente più banda a tutta larghezza. */
.perc-blocco { margin-bottom: 14px; }
.perc-blocco:last-child { margin-bottom: 0; }
.perc-testa { display: flex; gap: .7rem; align-items: center; }
.perc-testa .segno { flex: 0 0 44px; }
.perc-testa .m { flex: 1; min-width: 0; }
.perc-testa .m b { display: block; font-size: .9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.perc-testa .m p { font-size: .74rem; color: var(--muted); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.perc-passo { font-size: .74rem; color: var(--muted); margin-top: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.perc-passo b { color: var(--text); }
.perc-divis { height: 1px; background: var(--page-tenue); margin: 13px 0; }

/* Vista ingrandita: barra con zoom + contenitore che scorre in orizzontale, con la sfumatura a
   destra a dire «c'è dell'altro». Lo zoom allarga il contenuto (Larghezza del componente), non lo
   scala: il testo resta netto. */
.perc-barra { display: flex; align-items: center; gap: .6rem; margin-bottom: .6rem; }
.perc-barra .zoom { margin-left: auto; display: flex; gap: .4rem; }
.perc-scroll { position: relative; overflow-x: auto; overflow-y: hidden; }
.perc-scroll::after { content: ''; position: absolute; right: 0; top: 0; bottom: 0; width: 30px; pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--card) 75%); }

@media (max-width: 820px) {

  /* Fuori dal flusso l'aside non riserva più il suo gutter: il contenuto va a tutta larghezza. */
  .contenuto { width: 100%; }

  /* --- la testata diventa la barra mobile: compatta, senza sfondare ------------------------ */

  /* I menù a tendina in alto (preferenze/utente) non devono uscire dallo schermo: bordi e cap. */
  .menu { max-width: calc(100vw - 1.6rem); }
  .menu-pref { right: .8rem; width: min(268px, calc(100vw - 1.6rem)); }

  /* --- il corpo pagina: margini più stretti, niente overflow orizzontale ------------------- */
  /* La spalla si stringe qui, e si stringe per TUTTI: la variabile è la stessa a cui si allineano
     barra e schede del guscio nuovo, quindi il numero resta uno. Per il rail non cambia niente —
     `--colonna-lato` vale 1rem, cioè il padding che questa regola aveva scritto a mano. */
  :root { --colonna-lato: 1rem; }
  .pagina { padding: var(--colonna-lato); }

  /* Titoli/sottotitoli lunghi vanno a capo invece di forzare la larghezza; file di bottoni a capo. */
  .sottotitolo, .ah-sub, .pagina-sub, .pagina-titolo, h1 { overflow-wrap: anywhere; }
  .toolbar, .det-azioni, .due-porte, .carta-testa { flex-wrap: wrap; }
  .toolbar .cerca { flex: 1 1 100%; max-width: none; }
  .filtro { margin-left: 0; }

  /* --- reti di sicurezza: le griglie a due colonne collassano a una ----------------------- */
  .det-griglia, .corso-due, .cru, .cru-kpi, .ah-cols, .st-grid2,
  .com-ed, .com-seg, .nz-ed, .griglia.due { grid-template-columns: 1fr; }

  /* --- le tabelle larghe non ancora convertite: scorrono in orizzontale invece di sfondare -
     (Chiusure, DettaglioCorso, GradiDaRatificare, Lezione, ScalaGradi, PreferenzeNotifiche…).
     Esclusa la tabella Soci, che qui sotto diventa un elenco di card. */
  .pagina table:not(.soci):not(.enti) { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }

  /* --- Soci: sotto il breakpoint la tabella lascia il posto all'elenco di `Riga` (2 set), che
     la pagina disegna accanto alla tabella; a decidere chi si vede sono .solo-largo/.solo-stretto,
     in fondo al foglio. La vecchia conversione «una riga = una card etichetta/valore» era una
     tabella girata, non la SocioCard dell'app, ed è uscita di qui. */

  /* --- Piattaforma › Enti: dieci colonne non stanno in un telefono, e messe a scorrere in
     orizzontale il confronto (che è tutto il punto della pagina) si perde comunque. Stessa
     conversione dei Soci: ogni riga diventa una card, l'etichetta della colonna la scrive
     `data-etichetta`. Il dettaglio è un <tr> a parte, quindi da impilato diventa la card
     subito sotto la sua — che è esattamente dove lo si cerca. */
  table.enti, table.enti tbody, table.enti tr, table.enti td { display: block; }
  table.enti thead { display: none; }
  table.enti tbody tr.riga {
    border: 1px solid var(--border); border-radius: var(--raggio);
    background: var(--card); box-shadow: var(--ombra);
    padding: .7rem .85rem; margin-bottom: .6rem;
  }
  table.enti tbody tr.riga:hover { background: var(--card); }
  table.enti td { border: none; padding: .18rem 0; }
  table.enti td:first-child { padding-bottom: .35rem; }
  table.enti td[data-etichetta] {
    display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
    font-size: .86rem;
  }
  table.enti td[data-etichetta]::before {
    content: attr(data-etichetta); color: var(--muted); font-weight: 500; flex: 0 0 auto;
  }
  /* La seconda riga muta e la barrina tornano in linea col numero: da impilati stanno a destra
     insieme al valore, non sotto di esso (che spezzerebbe la coppia etichetta/valore). */
  table.enti td[data-etichetta] > .sotto { display: inline; margin-left: .35rem; }
  /* Il dettaglio da impilato non ha più colonne da tenere: prende tutta la card. */
  table.enti tr.dett { margin: -.35rem 0 .6rem; }
  table.enti tr.dett > td { border-radius: var(--raggio); padding: .8rem .85rem; }
}

/* ============================================================================
   SUGGERIMENTI IN HOME (§«suggerimenti in home», 2 ago): la card «Per cominciare»
   del gestore (Home) e i due riquadri di spiegazione dell'allievo (AtletaHome).
   Riusano .carta.richiudibile + .chiudi-avviso; i colori vengono dai token del tema
   (accento, --ok, --page-tenue), non da una palette a parte, così seguono skin e
   chiaro/scuro come il resto della WebAdmin. Mobile-first: le griglie sono auto-fit e
   si impilano da sole sotto ~820px, e la rete di sicurezza dello strato mobile le
   collasserebbe comunque — nessuna media query dedicata qui.
   ============================================================================ */

/* --- gestore: «Per cominciare» ------------------------------------------- */
.avvio { margin-bottom: 1rem; }
.avvio-testa { display: flex; align-items: center; gap: .6rem; margin-bottom: .2rem; padding-right: 1.6rem; }
.avvio-sig {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 9px;
  background: var(--accent); color: var(--accent-on);
  display: flex; align-items: center; justify-content: center; font-size: 1rem;
}
.avvio-testa h2 { margin: 0; font-size: 1.05rem; }
.avvio-avz {
  margin-left: auto; font-size: .74rem; font-weight: 600; color: var(--muted);
  background: var(--page-tenue); border-radius: 20px; padding: .18rem .6rem; white-space: nowrap;
}
.avvio-intro { color: var(--muted); font-size: .9rem; line-height: 1.5; margin: .2rem 0 1rem; }

.avvio-passo { display: flex; gap: .7rem; align-items: flex-start; padding: .6rem .15rem; }
.avvio-passo + .avvio-passo { border-top: 1px solid var(--border); }
/* Il passo «di adesso» risalta con un fondo tenue d'accento (e allora niente riga sopra). */
.avvio-passo.ora { background: var(--accent-tenue); border-radius: 10px; border-top: none; padding: .7rem .6rem; }
.avvio-pallino {
  flex: 0 0 auto; width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: .78rem; font-weight: 700; margin-top: .1rem;
  background: var(--page-tenue); color: var(--muted); border: 1px solid var(--border);
}
.avvio-passo.fatto .avvio-pallino { background: var(--ok); color: #fff; border-color: var(--ok); }
.avvio-passo.ora .avvio-pallino { background: var(--accent); color: var(--accent-on); border-color: var(--accent); }
.avvio-corpo { flex: 1 1 auto; min-width: 0; }
.avvio-corpo b { font-size: .92rem; }
.avvio-passo.dopo .avvio-corpo b { color: var(--muted); }
.avvio-corpo p { margin: .15rem 0 0; font-size: .82rem; color: var(--muted); line-height: 1.45; }
.avvio-cta { display: inline-block; margin-top: .6rem; }
.avvio-stato { flex: 0 0 auto; font-size: .78rem; font-weight: 600; color: var(--ok-text); margin-top: .15rem; }

/* Il blocco soci: due strade alla pari, non un passo. Con soci già presenti si attenua —
   resta a spiegare, non a spingere (uso opzionale di HaSoci). */
.avvio-soci { margin-top: 1rem; background: var(--page-tenue); border-radius: 10px; padding: .8rem .9rem; }
.avvio-soci.attenua { opacity: .6; }
.avvio-soci-h { font-size: .85rem; color: var(--text); line-height: 1.45; margin-bottom: .5rem; }
.avvio-via { display: flex; gap: .6rem; align-items: flex-start; font-size: .84rem; color: var(--muted); line-height: 1.45; padding: .45rem 0; }
.avvio-via + .avvio-via { border-top: 1px solid var(--border); }
.avvio-tag {
  flex: 0 0 auto; font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  padding: .18rem .5rem; border-radius: 20px; background: var(--border); color: var(--muted);
  margin-top: .1rem; white-space: nowrap;
}
.avvio-tag.ok { background: var(--ok-bg); color: var(--ok-text); }
.avvio-soci-p { font-size: .8rem; color: var(--muted); line-height: 1.5; margin-top: .55rem; padding-top: .55rem; border-top: 1px solid var(--border); }

/* --- allievo: i due riquadri di spiegazione ------------------------------ */
.spiega { margin-bottom: 1.4rem; }
.spiega-testa { display: flex; align-items: center; gap: .6rem; margin-bottom: .2rem; padding-right: 1.6rem; }
/* Il sigillo «?»: dice che è una spiegazione, non un avviso — quieto, non d'accento. */
.spiega-sig {
  flex: 0 0 auto; width: 28px; height: 28px; border-radius: 8px;
  background: var(--page-tenue); color: var(--muted); border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center; font-weight: 700;
}
.spiega-testa h2 { margin: 0; font-size: 1.02rem; }
.spiega-intro { color: var(--muted); font-size: .9rem; line-height: 1.55; margin: .2rem 0 1rem; }

/* Il confronto «il mio budopass / una tessera»: due colonne che si impilano da sole. */
.spiega-vista { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: .7rem; }
.spiega-box { border: 1px solid var(--border); border-radius: 12px; padding: .8rem .85rem; background: var(--page-tenue); }
.spiega-box.mio { border-color: var(--accent); }
.spiega-box .vt { display: flex; align-items: center; gap: .5rem; font-weight: 700; font-size: .9rem; }
.spiega-box .vk {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 6px;
  background: var(--accent); color: var(--accent-on);
  display: flex; align-items: center; justify-content: center; font-size: .82rem;
}
.spiega-box .vs { font-size: .76rem; color: var(--muted); margin: .25rem 0 .5rem; }
.spiega-box ul { margin: 0; padding-left: 1.1rem; }
.spiega-box li { font-size: .82rem; color: var(--text); line-height: 1.55; }
.spiega-nota { font-size: .8rem; color: var(--muted); margin: .8rem 0 0; line-height: 1.5; }

/* La catena dichiarato → ratificato, con le pastiglie di stato. */
.spiega-catena { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-top: .2rem; }
.spiega-catena .frecc { color: var(--muted); font-weight: 700; }
.spiega-catena-nota { font-size: .78rem; color: var(--muted); }
.pastiglia { display: inline-block; font-size: .72rem; font-weight: 700; padding: .16rem .55rem; border-radius: 20px; }
.pastiglia.dic { background: var(--accent-tenue); color: var(--accent-text); }
.pastiglia.rat { background: var(--ok-bg); color: var(--ok-text); }
.spiega-azioni { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1rem; }

/* ===== scheda esame del grado (§«scheda esame sul web», 2 ago) =============
   Parità con MAUI SchedaEsamePage: diploma/copertina, blocco grado (token da SegnoGrado),
   dati esame, galleria privata, condivisione. Palette washi/hanko dalle variabili di tema
   (chiaro e scuro insieme). Mobile-first: colonna unica; la galleria passa da 4 a 3 colonne
   sotto il breakpoint mobile (~820px), coordinato con lo strato mobile della WebAdmin. */
.sg { max-width: 680px; }

/* copertina / diploma disegnato */
.sg-cop {
  position: relative; height: 180px; border-radius: 14px; overflow: hidden; margin-bottom: 1.1rem;
  border: 1px solid var(--border);
  background: linear-gradient(160deg, var(--accent-tenue), var(--page-tenue));
  display: flex; align-items: center; justify-content: center;
}
.sg-cop img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sg-cornice { position: absolute; inset: 12px; border: 2px solid var(--accent); opacity: .5; border-radius: 8px; }
.sg-dip { position: relative; text-align: center; }
.sg-dip .et { font-size: .68rem; letter-spacing: .22em; color: var(--accent-text); font-weight: 700; }
.sg-dip .k { font-family: var(--jp); font-size: 2.6rem; color: var(--accent); line-height: 1.15; margin-top: .1rem; }
.sg-dip .seal {
  margin: .25rem auto 0; width: 32px; height: 32px; border-radius: 50%;
  border: 2px solid var(--accent); color: var(--accent); font-family: var(--jp); font-size: 1rem;
  display: flex; align-items: center; justify-content: center;
}
.sg-cop-azioni { position: absolute; right: 12px; bottom: 12px; display: flex; gap: .4rem; }
.sg-cop-btn {
  width: 36px; height: 36px; border-radius: 50%; padding: 0; cursor: pointer;
  border: 2px solid var(--card); background: rgba(0,0,0,.5); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
}
.sg-cop-btn.accento { background: var(--accent); }
.sg-cop-btn svg { width: 18px; height: 18px; }
.sg-cop-btn:disabled { opacity: .5; cursor: default; }

.sg-corpo { }

/* blocco grado */
.sg-grado { display: grid; grid-template-columns: auto 1fr auto; gap: .9rem; align-items: start; }
.sg-token { flex: none; }
/* SegnoGrado disegna .token-svg senza vincolo di larghezza: qui lo cappo (fuori da .segno,
   la cui regola non si applica), come nell'app il token è 56px nella scheda. */
.sg-token .token-svg { width: 56px; height: auto; display: block; }
.sg-grado-t { min-width: 0; }
.sg-grado-t h2 { font-size: 1.25rem; margin: 0; letter-spacing: -.01em; }
.sg-sub { font-size: .82rem; color: var(--muted); margin: .18rem 0 0; line-height: 1.4; }
.sg-grado-t .badge { margin-top: .5rem; }
.sg-ente { display: flex; flex-direction: column; align-items: flex-end; gap: .3rem; }
.sg-logo {
  width: 42px; height: 42px; border-radius: 11px; overflow: hidden;
  background: var(--accent-tenue); color: var(--accent-text); font-weight: 600; font-size: .9rem;
  display: flex; align-items: center; justify-content: center;
}
.sg-logo img { width: 100%; height: 100%; object-fit: cover; }
.sg-vf { display: flex; align-items: center; gap: .22rem; font-size: .7rem; color: var(--muted); }
.sg-vf svg { width: 13px; height: 13px; color: var(--accent); }

/* dati esame */
.sg-dati { background: var(--page-tenue); border: 1px solid var(--border); border-radius: 12px; padding: 0 .9rem; margin-top: 1.1rem; }
.sg-dr { display: flex; justify-content: space-between; gap: .8rem; padding: .78rem 0; font-size: .9rem; }
.sg-dr + .sg-dr { border-top: 1px solid var(--border); }
.sg-dr .k { color: var(--muted); }
.sg-dr .v { font-weight: 600; text-align: right; color: var(--text); }
.sg-seal {
  display: inline-flex; width: 28px; height: 28px; border-radius: 50%;
  border: 1.5px solid var(--accent); color: var(--accent); font-family: var(--jp); font-size: .8rem;
  align-items: center; justify-content: center;
}
/* Il timbro DAVVERO apposto al grado, al posto del glifo (2 set): stessa impronta di 28px ma
   SENZA cornice né raggio — un hanko ha la sua forma, e un cerchio attorno sarebbe un secondo
   timbro che non esiste (RigaGrado.xaml sull'app). Per questo non riusa .sg-seal. */
.sg-seal-img { display: inline-block; width: 28px; height: 28px; object-fit: contain; vertical-align: middle; }

/* galleria privata */
.sg-galt { display: flex; align-items: center; justify-content: space-between; margin: 1.35rem .1rem .6rem; }
.sg-galt .l { font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.sg-galt .p { display: flex; align-items: center; gap: .3rem; font-size: .72rem; color: var(--muted); }
.sg-galt .p svg { width: 13px; height: 13px; }
.sg-gal { display: grid; grid-template-columns: repeat(4, 1fr); gap: .5rem; }
.sg-ph { position: relative; aspect-ratio: 1; border-radius: 10px; overflow: hidden; background: var(--page-tenue); border: 1px solid var(--border); }
.sg-ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sg-ph-x {
  position: absolute; top: .28rem; right: .28rem; width: 22px; height: 22px; border-radius: 50%;
  border: none; background: rgba(0,0,0,.55); color: #fff; padding: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.sg-ph-x svg { width: 13px; height: 13px; }
.sg-ph-x:disabled { opacity: .5; cursor: default; }
.sg-add {
  aspect-ratio: 1; border-radius: 10px; border: 1.5px dashed var(--border); background: var(--page-tenue);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .15rem;
  color: var(--muted); font-size: .7rem; cursor: pointer;
}
.sg-add .pl { display: inline-flex; }
.sg-add .pl svg { width: 20px; height: 20px; }

/* condivisione */
.sg-cond { margin-top: 1.35rem; }
.sg-bcond {
  display: inline-flex; align-items: center; justify-content: center; gap: .45rem; width: 100%;
  background: var(--accent); color: var(--accent-on); font-size: .95rem; font-weight: 600;
  padding: .8rem; border-radius: 11px; border: none; cursor: pointer;
}
.sg-bcond svg { width: 18px; height: 18px; }
.sg-bcond.quieto { background: var(--page-tenue); color: var(--text); border: 1px solid var(--border); }
.sg-bcond:disabled { opacity: .6; cursor: default; }
.sg-formati { display: flex; gap: .5rem; }
.sg-cond .cn { font-size: .72rem; color: var(--muted); text-align: center; margin: .55rem .5rem 0; line-height: 1.5; }

@media (max-width: 820px) {
  .sg { max-width: none; }
  .sg-cop { height: 150px; }
  .sg-dip .k { font-size: 2.2rem; }
  .sg-gal { grid-template-columns: repeat(3, 1fr); }
}

/* --- pagina privacy pubblica (/privacy) --------------------------------
   Documento statico a piena finestra (fuori dal guscio): una colonna di lettura centrata
   (~820px) su fondo pagina, la carta a contenerla. Il contenuto è HTML iniettato (MarkupString),
   quindi lo stile della CSS isolata non lo raggiungerebbe: le regole stanno qui, sotto .privacy-doc,
   così valgono comunque e restano confinate a questa pagina. Titoli/testo seguono i token del tema. */
.privacy-wrap { max-width: 820px; margin: 0 auto; padding: 2.5rem 1.25rem 3.5rem; }
.privacy-doc { line-height: 1.62; }
.privacy-doc h1 { font-size: 1.6rem; margin: 0 0 .35rem; }
.privacy-doc h2 { font-size: 1.15rem; margin: 1.7rem 0 .5rem; }
.privacy-doc h3 { font-size: 1rem; margin: 1.1rem 0 .35rem; }
.privacy-doc p { margin: .65rem 0; color: var(--text); }
.privacy-doc ul { margin: .65rem 0; padding-left: 1.35rem; }
.privacy-doc li { margin: .3rem 0; }
.privacy-doc em { color: var(--muted); font-style: italic; }

/* ===== Eventi — rework (creazione a sezioni + builder modulo + riepilogo + luoghi) =====
   Mockup: budopass_evento_creazione_misto / _registrazione_modulo_v2 / _builder_editor /
   _riepilogo / _luoghi_rubrica / _ente_sede_rubrica. Tutti i colori dai token del tema
   (adattano chiaro/scuro): mai hex crudi. */

/* --- tab row (Configurazione · Riepilogo · Registrazioni · Check-in) --- */
.ev-tabs { display: flex; gap: 1.4rem; border-bottom: 1px solid var(--border); margin: 0 0 1.25rem; flex-wrap: wrap; }
.ev-tabs a { padding: .6rem .1rem; color: var(--muted); font-size: .92rem; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.ev-tabs a:hover { color: var(--text); }
.ev-tabs a.on { color: var(--accent-text); font-weight: 700; border-bottom-color: var(--accent); }

/* --- barra navigatore (scroll-spy) fissa in alto --- */
.ev-nav { position: sticky; top: 0; z-index: 5; background: var(--card); border: 1px solid var(--border);
  border-radius: var(--raggio); padding: .7rem .85rem; box-shadow: 0 3px 10px rgba(35,32,28,.07); margin-bottom: 1.1rem; }
.ev-nav-list { display: flex; align-items: flex-start; gap: 0; }
.ev-nav-step { display: flex; flex-direction: column; align-items: center; flex: 1; position: relative; cursor: pointer; text-align: center; }
.ev-nav-step::before { content: ""; position: absolute; top: 14px; left: -50%; width: 100%; height: 2px; background: var(--border); }
.ev-nav-step:first-child::before { display: none; }
.ev-nav-step.done::before, .ev-nav-step.on::before { background: var(--ok); }
.ev-nav-dot { width: 28px; height: 28px; border-radius: 50%; background: var(--page-tenue); border: 1.5px solid var(--border);
  color: var(--muted); font-size: .78rem; font-weight: 700; display: flex; align-items: center; justify-content: center; z-index: 1; }
.ev-nav-step.on .ev-nav-dot { background: var(--accent); border-color: var(--accent); color: var(--accent-on); box-shadow: 0 0 0 4px var(--accent-tenue); }
.ev-nav-step.done .ev-nav-dot { background: var(--ok); border-color: var(--ok); color: #fff; }
.ev-nav-cap { font-size: .72rem; margin-top: .35rem; color: var(--muted); }
.ev-nav-step.on .ev-nav-cap { color: var(--accent-text); font-weight: 700; }
.ev-nav-step.done .ev-nav-cap { color: var(--text); }

/* --- carta di sezione con intestazione numerata --- */
.ev-sez { scroll-margin-top: 92px; }
/* Ritmo verticale fra le carte-sezione uguale allo standard app per .carta impilate (1rem, come
   .griglia / .imp-col): le carte sono sorelle dirette in pagina e .carta non ha margine proprio. */
.ev-sez + .ev-sez { margin-top: 1rem; }
.ev-sez.corrente { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tenue); }
.ev-sec-h { display: flex; align-items: baseline; gap: .6rem; margin: 0 0 .9rem; }
.ev-sec-n { width: 24px; height: 24px; flex: 0 0 24px; border-radius: 50%; background: var(--page-tenue);
  border: 1px solid var(--border); color: var(--muted); font-size: .72rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center; }
.ev-sec-h.done .ev-sec-n { background: var(--ok-bg); color: var(--ok-text); border-color: var(--ok); }
.ev-sec-h h2 { margin: 0; font-size: 1rem; }
.ev-sec-hint { color: var(--muted); font-size: .78rem; margin-left: auto; text-align: right; }
.ev-subhead { font-size: .8rem; color: var(--muted); margin: 1rem 0 .6rem; padding-top: .85rem; border-top: 1px solid var(--border); }

/* --- barra azioni fissa in basso --- */
.ev-actionbar { position: sticky; bottom: 0; z-index: 4; background: var(--card); border: 1px solid var(--border);
  border-radius: var(--raggio); box-shadow: 0 -2px 10px rgba(35,32,28,.07); padding: .7rem .9rem; margin-top: 1rem; }
.ev-actionbar-inner { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.ev-actionbar-msg { color: var(--muted); font-size: .8rem; }
.ev-actionbar .spazio { margin-left: auto; }

/* --- builder del modulo: card di un campo --- */
.ev-fld { display: flex; align-items: center; gap: .75rem; border: 1px solid var(--border); border-radius: 10px;
  padding: .65rem .7rem; margin-bottom: .55rem; background: var(--card); }
.ev-fld-ic { width: 34px; height: 34px; flex: 0 0 34px; border-radius: 8px; background: var(--page-tenue);
  display: flex; align-items: center; justify-content: center; font-size: .95rem; color: var(--muted); font-family: var(--jp); }
.ev-fld-bd { display: flex; flex-direction: column; min-width: 0; }
.ev-fld-bd b { font-weight: 600; font-size: .85rem; }
.ev-fld-bd span { color: var(--muted); font-size: .75rem; }
.ev-fld-rt { margin-left: auto; display: flex; align-items: center; gap: .6rem; }
.ev-fld.locked { background: var(--page-tenue); border-style: dashed; }
.ev-fld.locked .ev-fld-ic { background: var(--accent-tenue); color: var(--accent-text); }
.ev-badge { font-size: .68rem; font-weight: 700; padding: .1rem .5rem; border-radius: 20px; }
.ev-badge.ob { background: var(--warn-bg); color: var(--warn-text); }
.ev-badge.op { background: var(--page-tenue); color: var(--muted); }
.ev-badge.fx { background: var(--ok-bg); color: var(--ok-text); }
.ev-fld-x { color: var(--muted); cursor: pointer; font-size: 1rem; border: none; background: none; padding: 0 .2rem; }
.ev-fld-x:hover { color: var(--err); }
.ev-fld-edit { color: var(--accent-text); font-size: .78rem; font-weight: 600; cursor: pointer; border: none; background: none; }
.ev-addrow { display: flex; gap: .6rem; margin-top: .35rem; flex-wrap: wrap; }
.ev-add { flex: 1; min-width: 160px; border: 1px dashed var(--accent); color: var(--accent); background: transparent;
  border-radius: 10px; padding: .65rem; font: inherit; font-weight: 600; cursor: pointer; }
.ev-add:hover { background: var(--accent-tenue); }

/* --- editor type-first (aggiungi domanda / consenso) --- */
.ev-editor { border: 1px solid var(--accent); border-radius: 10px; padding: .9rem; margin: .4rem 0 .6rem; background: var(--card);
  box-shadow: 0 0 0 3px var(--accent-tenue); }
.ev-editor h4 { margin: 0 0 .1rem; font-size: .95rem; }
.ev-editor .ev-eh { color: var(--muted); font-size: .78rem; margin: 0 0 .8rem; }
.ev-types { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; margin-bottom: .2rem; }
.ev-type { display: flex; align-items: center; gap: .5rem; padding: .5rem .6rem; border: 1px solid var(--border);
  border-radius: 9px; background: var(--card); cursor: pointer; font-size: .82rem; }
.ev-type:hover { border-color: var(--accent); }
.ev-type.on { border-color: var(--accent); background: var(--accent-tenue); box-shadow: 0 0 0 1px var(--accent) inset; color: var(--accent-text); font-weight: 600; }
.ev-optrow { display: flex; align-items: center; gap: .5rem; margin-bottom: .4rem; }
.ev-optrow input { flex: 1; }
.ev-optrow .ev-op-btn { border: none; background: none; color: var(--muted); cursor: pointer; font-size: 1rem; padding: 0 .2rem; }
.ev-optrow .ev-op-btn:hover { color: var(--text); }
.ev-addopt { font-size: .82rem; color: var(--accent); font-weight: 600; cursor: pointer; border: none; background: none; padding: .1rem 0; }
.ev-prev { margin-top: .6rem; border: 1px dashed var(--border); border-radius: 10px; padding: .7rem .8rem; background: var(--page-tenue); }
.ev-prev-lab { font-size: .66rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin: 0 0 .5rem; font-weight: 700; }
.ev-prev-q { font-weight: 600; font-size: .85rem; margin-bottom: .45rem; }
.ev-prev-q .req { color: var(--accent); }
.ev-prev-cns { display: flex; align-items: flex-start; gap: .5rem; font-size: .84rem; }
.ev-prev-cns .box { width: 18px; height: 18px; flex: 0 0 18px; border: 1.5px solid var(--accent); border-radius: 5px;
  background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center; font-size: .7rem; }
.ev-editor-foot { display: flex; justify-content: flex-end; gap: .5rem; margin-top: .8rem; padding-top: .7rem; border-top: 1px solid var(--border); }
.ev-pdfpick { display: flex; align-items: center; gap: .6rem; padding: .5rem .6rem; border: 1px solid var(--border); border-radius: 9px; background: var(--card); font-size: .82rem; }
.ev-pdfpick .pi { width: 28px; height: 28px; flex: 0 0 28px; border-radius: 7px; background: var(--page-tenue); display: flex; align-items: center; justify-content: center; }

/* --- luoghi: rubrica picker + editor + mappa --- */
.ev-loc { display: flex; align-items: flex-start; gap: .7rem; border: 1px solid var(--border); border-radius: 10px;
  padding: .65rem .7rem; margin-bottom: .5rem; cursor: pointer; background: var(--card); width: 100%; text-align: left; font: inherit; color: inherit; }
.ev-loc.sel { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tenue); }
.ev-loc-radio { width: 20px; height: 20px; flex: 0 0 20px; border-radius: 50%; border: 2px solid var(--border); margin-top: 1px; position: relative; }
.ev-loc.sel .ev-loc-radio { border-color: var(--accent); }
.ev-loc.sel .ev-loc-radio::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--accent); }
.ev-loc-bd { display: flex; flex-direction: column; min-width: 0; }
.ev-loc-bd .nm { font-weight: 600; font-size: .88rem; display: flex; align-items: center; gap: .5rem; }
.ev-loc-bd .ad { color: var(--muted); font-size: .78rem; margin-top: 1px; }
.ev-loc-edit { margin-left: auto; color: var(--accent-text); font-size: .76rem; font-weight: 600; white-space: nowrap; }
.ev-paste { display: flex; gap: .5rem; }
.ev-paste input { flex: 1; }
.ev-map { position: relative; border-radius: 10px; overflow: hidden; border: 1px solid var(--border); background: var(--page-tenue);
  min-height: 150px; margin-top: .5rem; display: flex; align-items: center; justify-content: center; }
.ev-map img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ev-map-empty { color: var(--muted); font-size: .8rem; text-align: center; padding: 1rem; }
.ev-map-tag { position: absolute; left: .5rem; bottom: .45rem; background: var(--card); border: 1px solid var(--border);
  border-radius: 6px; font-size: .66rem; color: var(--muted); padding: .1rem .45rem; }
.ev-saverow { display: flex; align-items: center; gap: .6rem; margin: .8rem 0 .3rem; padding: .6rem .7rem;
  background: var(--page-tenue); border: 1px solid var(--border); border-radius: 9px; font-size: .82rem; }
.ev-saverow .spazio { margin-left: auto; }

/* --- riepilogo aggregato --- */
.ev-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: .7rem; margin-bottom: 1.1rem; }
.ev-tile { background: var(--card); border: 1px solid var(--border); border-radius: var(--raggio); padding: .8rem .9rem; }
.ev-tile .v { font-size: 1.5rem; font-weight: 700; }
.ev-tile .v small { font-size: .95rem; color: var(--muted); font-weight: 600; }
.ev-tile .l { font-size: .68rem; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); font-weight: 700; margin-top: .1rem; }
.ev-bar { display: grid; grid-template-columns: 190px 1fr 62px; align-items: center; gap: .7rem; margin: .55rem 0; }
.ev-bar-l { font-size: .84rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ev-bar-l small { color: var(--muted); }
.ev-bar-track { height: 22px; background: var(--page-tenue); border-radius: 6px; overflow: hidden; }
.ev-bar-fill { height: 100%; background: var(--accent); border-radius: 6px; width: var(--p); }
.ev-bar-val { text-align: right; font-weight: 700; font-size: .84rem; }
.ev-bar-val small { color: var(--muted); font-weight: 500; }
.ev-qblock { padding: .85rem 0; border-top: 1px solid var(--border); }
.ev-qblock:first-of-type { border-top: none; padding-top: .2rem; }
.ev-qh { display: flex; align-items: center; gap: .5rem; margin-bottom: .4rem; }
.ev-qh b { font-size: .9rem; }
.ev-qtype { font-size: .66rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
  background: var(--page-tenue); border: 1px solid var(--border); border-radius: 6px; padding: .05rem .4rem; }
.ev-numstat { display: flex; gap: 1.6rem; flex-wrap: wrap; margin-top: .3rem; }
.ev-numstat .ns { display: flex; flex-direction: column; }
.ev-numstat .ns b { font-size: 1.25rem; }
.ev-numstat .ns span { font-size: .7rem; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.ev-chips { display: flex; flex-wrap: wrap; gap: .45rem; margin-top: .5rem; }
.ev-chip { background: var(--page-tenue); border: 1px solid var(--border); border-radius: 20px; padding: .25rem .7rem; font-size: .78rem; }

/* --- registrazioni: elenco singoli + dettaglio laterale --- */
.ev-md { display: grid; grid-template-columns: 1fr 340px; gap: 1.1rem; align-items: start; }
.ev-md-detail { position: sticky; top: 1rem; }
.ev-md-vuoto { color: var(--muted); font-size: .85rem; padding: 1rem 0; }
.ev-md-row { display: flex; align-items: center; gap: .8rem; padding: .55rem 0; border-top: 1px solid var(--border);
  cursor: pointer; width: 100%; text-align: left; font: inherit; color: inherit; background: none; border-left: none; border-right: none; border-bottom: none; }
.ev-md-row.on { background: var(--accent-tenue); border-radius: 8px; padding-left: .5rem; padding-right: .5rem; }
.ev-kv { display: flex; justify-content: space-between; gap: .8rem; padding: .3rem 0; font-size: .84rem; }
.ev-kv span { color: var(--muted); }

@media (max-width: 820px) {
  .ev-md { grid-template-columns: 1fr; }
  .ev-md-detail { position: static; }
  .ev-tiles { grid-template-columns: repeat(2, 1fr); }
  .ev-bar { grid-template-columns: 120px 1fr 54px; }
  .ev-types { grid-template-columns: 1fr; }
  .ev-nav-cap { display: none; }
}


/* ==========================================================================
   STRATO DI MOVIMENTO E MATERIA
   --------------------------------------------------------------------------
   Il design system è lo stesso dell'app — stessa palette, stessi cinque accenti,
   stesso chiaro/scuro, stesse tre pelli — ma finora l'app si MUOVEVA e il web no:
   in 3.500 righe di questo foglio c'erano 19 `transition` e un solo @keyframes
   (il toast). Il risultato è che il WebAdmin si legge come una FOTOGRAFIA
   dell'app. Qui sotto sta il pezzo che mancava, tutto in un blocco: la grana
   della carta, l'entrata a cascata, l'elevazione all'hover, lo scheletro di
   caricamento e il rispetto del moto ridotto.

   Le durate e la curva stanno coi token, in cima (con --ombra/--ombra-alta e
   --scheletro): sono materiale, non comportamento, e vanno lette insieme agli
   altri valori. Qui c'è solo ciò che si muove.

   Fuori scopo di proposito — vogliono JavaScript, e sono un lavoro a parte: i
   numeri che salgono contando, la transizione fra pagine, il sigillo hanko che
   si imprime a salvataggio riuscito. Il token --t-lunga è già in cima e li
   aspetta; finché non arrivano, dorme.

   Riferimento reso e verificato: docs/budopass_webadmin_movimento.html — la
   scheda «I dieci gesti» documenta ogni gesto con la sua tempistica.
   ========================================================================== */

/* --- materia: la grana della carta -------------------------------------
   Non è un'animazione: è il washi che diventa carta. Un rumore FERMO all'1,8%,
   fisso al viewport (non scorre: la grana sta nella carta, non nel contenuto) e
   fuori dal flusso, così non costa un reflow a nessuno.
   Sta su html::before e NON su un z-index negativo: `body` ha un fondo suo
   (--page), e una pseudo a z-index:-1 finirebbe DIETRO quel fondo, cioè
   invisibile — è la stessa trappola che aveva la vecchia filigrana .guscio::after.
   A z-index:0 la grana passa quindi SOPRA il testo, ed è giusto così: è una
   texture di carta, la si sente e non la si vede. `pointer-events:none` perché
   non deve intercettare un solo clic. Resta comunque sotto tutto ciò che è
   posizionato più in alto — menù (30/50), scrim (40), modali (60), toast (1000)
   — quindi non vela mai un pannello aperto. */
html::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: .55;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.032'/%3E%3C/svg%3E");
}

/* --- entrata a cascata --------------------------------------------------
   La carta sale di 10px e prende corpo. Lo sfasamento è 55ms: sotto i 40 non si
   legge come cascata, sopra gli 80 la si aspetta.

   Si aggancia a ciò che ESISTE — i figli diretti di <main class="pagina"> — e
   non a una classe nuova nei .razor: nessuna pagina va toccata, e togliere lo
   strato è togliere questo blocco.

   ATTENZIONE, e vale per chiunque ci metta mano: in Blazor Server il DOM si
   RATTOPPA, non si ricostruisce. L'animazione parte quindi una volta sola, alla
   creazione VERA dell'elemento — battere sulla casella di ricerca non la fa
   ripartire, perché la riga o la card restano lo stesso nodo. Ma un blocco
   @if/@else che cambia ramo, o un @key diverso, SOSTITUISCE l'elemento e la
   rifà partire: è esattamente quello che si vuole quando i dati arrivano al
   posto del «Caricamento…», ed è quello che NON si vuole su un elemento che si
   ridisegna a ogni tasto o a ogni tick. Da qui le esclusioni. */
@keyframes entra-su {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* Le esclusioni stanno in un :not(:where(...)) e non in un :not(...) semplice
   per una ragione precisa: :not() prende la specificità del suo argomento, e
   quattro classi porterebbero il selettore a (0,5,0) — più delle regole di
   ritardo qui sotto, che a quel punto non varrebbero più nulla (la scorciatoia
   `animation` azzera animation-delay). :where() vale zero, così questa regola
   resta a (0,1,0) e i :nth-child a (0,2,0) la battono, come devono.

   Chi resta fuori, e perché:
   .modale-fondo  — è un overlay `fixed`, figlio diretto di .pagina in una
                    dozzina di pagine: la cascata gli farebbe entrare il velo
                    di sbieco e in ritardo. Dentro la modale non deve succedere
                    niente (la selezione è sui soli FIGLI di .pagina, quindi il
                    contenuto della modale non è mai toccato).
   .avviso-host   — il toast è già ancorato al viewport e ha la sua entrata
                    (avviso-su): due animazioni sullo stesso nodo litigano.
   .toolbar       — porta il campo di ricerca. Un campo che sfuma in entrata
                    sotto un cursore che sta già scrivendo è peggio di un campo
                    che sta lì e basta.
   .vuoto         — è il segnaposto di caricamento: viene sostituito dai dati
                    quasi subito, e farlo entrare significa due cascate di fila
                    per la stessa pagina. Lo stato d'attesa non è un ingresso. */
/* `backwards` e non `both` (§26 ago) — è una correzione, non un ritocco.

   `both` = `backwards` + `forwards`. Il `forwards` qui non serviva a niente: l'ultimo fotogramma
   di `entra-su` è `opacity: 1; transform: none`, cioè esattamente i valori che l'elemento ha già
   di suo. Ma teneva l'elemento «in animazione» per sempre, e un elemento che anima transform o
   opacity è un CONTESTO D'IMPILAMENTO: ogni carta ne diventava una, e uno z-index dentro una
   carta smetteva di valere fuori.

   Conseguenza vista sulla pagina Chiusure: il calendario di `CampoData` (`.cd-pop`, z-index 30),
   aperto nella carta del form, finiva DIETRO la carta della tabella qui sotto — perché quello
   z-index 30 era prigioniero della prima carta, e fra due carte-contesto vince chi viene dopo
   nel documento. Alzare lo z-index del popover non avrebbe risolto niente: il problema non era
   quanto fosse alto, era dentro quale scatola.

   Con `backwards` lo stato iniziale si applica lo stesso durante il ritardo (che è tutto ciò per
   cui `both` era stato messo: senza, le carte lampeggerebbero prima di entrare), l'ingresso è
   identico al pixel, e a fine animazione l'elemento torna un blocco qualunque. */
.pagina > *:not(:where(.modale-fondo, .avviso-host, .toolbar, .vuoto)) {
  animation: entra-su var(--t-media) var(--curva) backwards;
}

/* Dal quarto figlio in poi il ritardo NON cresce più: si fermano tutti a 165ms
   ed entrano insieme. Se continuasse, una pagina con otto blocchi finirebbe di
   comporsi dopo mezzo secondo; e se invece si lasciasse a 0 (nessuna regola),
   il quinto figlio arriverebbe PRIMA del quarto. */
.pagina > *:nth-child(1)   { animation-delay: 0ms; }
.pagina > *:nth-child(2)   { animation-delay: 55ms; }
.pagina > *:nth-child(3)   { animation-delay: 110ms; }
.pagina > *:nth-child(n+4) { animation-delay: 165ms; }

/* --- elevazione all'hover ----------------------------------------------
   Un pixel, non tre: la carta si STACCA dal foglio, non salta. Il bordo che vira
   all'accento c'era già sulle tessere del cruscotto — qui diventa il gesto
   condiviso, con l'ombra alta a fare il distacco e la pressione che riappoggia.

   Regola d'uso, e non è un dettaglio: .sollevabile va solo su ciò che è DAVVERO
   cliccabile. Una carta che si alza e non porta da nessuna parte è una bugia. */
.sollevabile,
.cru-kpi a.carta {
  transition: transform var(--t-corta) var(--curva),
              box-shadow var(--t-corta) var(--curva),
              border-color var(--t-corta) var(--curva),
              background var(--t-corta) var(--curva);
}
.sollevabile:hover,
.cru-kpi a.carta:hover {
  transform: translateY(-1px);
  box-shadow: var(--ombra-alta);
  border-color: var(--accent);
  background: var(--accent-tenue);
}
.sollevabile:active,
.cru-kpi a.carta:active {
  transform: translateY(0);
  box-shadow: var(--ombra);
}

/* La riga di lista NON si solleva: non è un foglio. Scorre di poco verso il ›,
   che le va incontro. Sono le due liste del cruscotto: le faccende da fare
   (ognuna è un <a>) e le lezioni di stasera (una riga con l'azione dentro: lì
   il fondo dice «sei su questa», non «cliccami»). */
.faccenda,
.lezione-oggi {
  border-radius: var(--raggio-s);
  transition: background var(--t-corta) var(--curva),
              padding-left var(--t-corta) var(--curva);
}
.faccenda:hover,
.lezione-oggi:hover {
  background: var(--riga-hover);
  padding-left: .45rem;
}
.faccenda .vai, .lezione-oggi .vai { transition: transform var(--t-corta) var(--curva); }
.faccenda:hover .vai, .lezione-oggi:hover .vai { transform: translateX(3px); }

/* --- scheletro di caricamento ------------------------------------------
   Al posto di «Caricamento…» centrato: la FORMA della pagina già lì, in washi,
   percorsa da una luce. Il gestore vede la struttura prima dei dati, e la pagina
   non salta quando arrivano.
   Questo blocco mette solo l'attrezzo: NESSUNA pagina è convertita qui. Chi
   vorrà adottarlo sostituirà il proprio <div class="vuoto">@Testi.Caricamento</div>
   con le barre — .scheletro.t per un titolo, .scheletro.r per una riga — e la
   larghezza a mano, che è ciò che le fa sembrare testo e non un blocco pieno. */
.scheletro {
  background: var(--scheletro);
  border-radius: 6px;
  position: relative;
  overflow: hidden;
}
.scheletro.r { height: 11px; }   /* riga */
.scheletro.t { height: 19px; }   /* titolo */
@keyframes luce { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.scheletro::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, var(--scheletro-luce), transparent);
  animation: luce 1150ms linear infinite;
}

/* --- moto ridotto: non è facoltativo -----------------------------------
   Chi ha chiesto al sistema di calmarsi vede la pagina di oggi, ferma. Senza
   questo blocco tutto quanto sta qui sopra non è raffinatezza, è un fastidio.

   È l'UNICO punto del foglio in cui il selettore universale e !important sono
   la cosa giusta: deve valere su ogni regola, comprese quelle che verranno
   dopo, e non c'è un elenco di eccezioni da mantenere.

   I due `*-delay` non stanno nel frammento canonico che gira in rete, ma qui
   servono: la cascata ha un fill-mode `both`, quindi senza azzerare il ritardo
   l'elemento resterebbe a opacità 0 per i suoi 165ms e poi COMPARIREBBE di
   colpo — cioè proprio lo sfarfallio che si voleva togliere. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    transition-delay: 0s !important;
  }
}

/* --- la copertina della scheda esame offerta come prova (§26 ago) ----------------------
   Sta dentro «Foto a riprova», sopra gli allegati, e compare SOLO se c'è almeno una
   copertina vera da offrire: un contenitore vuoto che annuncia di essere vuoto è
   esattamente il riquadro «aggiungi foto» da cui nasce l'equivoco.

   Tono d'accento tenue e non di avviso: è un aiuto, non un problema da sistemare. */
.cop-blocco {
  background: var(--accent-tenue); border: 1px solid var(--border);
  border-radius: var(--raggio-s); padding: .8rem .85rem; margin-bottom: .8rem;
}
/* UNA riga per tutto il blocco (§27 ago): il grassetto sta sulla sola frase d'apertura, che
   arriva come <strong> dai marcatori `**` della stringa. Il resto è tenue — è un'offerta, non
   un avvertimento, ed era proprio il tono che tre testi in fila davano per sbaglio.
   Sono cadute con loro `.cop-aiuto` e `.cop-nota`: i due testi non esistono più. */
.cop-testa { font-size: .8rem; color: var(--muted); line-height: 1.45; margin: 0 0 .7rem; }
.cop-testa strong { color: var(--text); font-weight: 600; }
.cop-strip { display: flex; gap: .8rem; flex-wrap: wrap; }
.cop-foto { width: 6.5rem; }
/* La miniatura in formato documento (più alta che larga): un diploma sta in piedi. Il bordo
   d'accento è ciò che dice «questa parte», e si vede prima dell'etichetta sotto. */
.cop-mini {
  width: 100%; height: 4.6rem; object-fit: cover; display: block;
  border-radius: var(--raggio-s); border: 2px solid var(--border); background: var(--page-tenue);
}
/* Niente più stato «scelta» sulla miniatura: una copertina scelta LASCIA la striscia e scende
   fra gli allegati, quindi qui c'è solo ciò che si può ancora usare (§27 ago). */
/* Di quale grado è la copertina: è la riga che rende visibili all'atleta le tre porte. */
.cop-da { font-size: .72rem; color: var(--muted); margin: .25rem 0 .3rem; line-height: 1.3; }
.cop-usa {
  width: 100%; font-size: .74rem; padding: .25rem .3rem; border-radius: var(--raggio-s);
  border: 1px solid var(--border); background: var(--card); color: var(--text); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: .25rem;
}
.cop-usa:hover:not(:disabled) { border-color: var(--accent); }
.cop-usa:disabled { opacity: .45; cursor: not-allowed; }
.cop-usa svg { width: 1em; height: 1em; flex: none; }


/* Il motivo per cui una riga trovata NON è unibile (§27 ago): sotto il nome, accanto al
   pulsante spento. Colore d'errore e non `--muted`, perché non è un dettaglio anagrafico in
   più — è la ragione per cui il bottone lì di fianco non si preme. La riga resta però una
   persona trovata: nessun barrato, nessuna opacità sull'intera `.ric-cand`. Un elenco che
   cancella a metà le righe che nega è di nuovo un modo di dire «non c'è». */
.ric-cand-motivo { display: block; color: var(--err-text); font-size: .78rem; margin-top: .2rem; }

/* ===== lo sweep delle emoji (28 ago) =======================================
   Le icone che hanno preso il posto di 📍 📌 🗑 📄 escono a 18px FISSI, mentre l'emoji che
   sostituiscono cresceva col testo attorno: dentro una pastiglia da .72rem erano enormi, e
   appoggiate alla linea di base invece che centrate. Qui si rimettono in scala sul testo (em)
   e si allineano.

   Le regole stanno sui contenitori specifici e MAI su `.etichetta` o `.bottone`: quelle sono
   classi di tutta l'app, e una riga scritta lì si sarebbe portata dietro ogni icona già esistente
   in pagine che nessuno ha guardato. Dove serviva un aggancio si è aggiunta una classe in più
   nel markup (`con-icona`, `ev-coord`), che è esplicito e circoscritto. */

/* Pastiglie e distintivi: icona + testo su una riga sola. */
.nz-chip.pin, .nz-pinl, .pin-badge, .con-icona { display: inline-flex; align-items: center; gap: .32rem; }
.nz-chip.pin svg, .nz-pinl svg, .pin-badge svg, .con-icona svg,
.ev-indicazioni svg, .ev-type svg { width: 1.15em; height: 1.15em; flex: none; }

/* In flusso di testo (la fascia del «non idoneo», il paragrafo di coordinate, il riquadro
   che dice che la mappa non c'è) l'icona resta INLINE: si scala e scende sotto la linea di
   base, senza trasformare il paragrafo in una riga flex — lì dentro c'è anche un <br>. */
.ev-barrato svg, .ev-map-empty svg, .ev-coord svg { width: 1.1em; height: 1.1em; vertical-align: -.2em; }

/* Icona sola dentro un bottoncino quadrato: centrata, non appoggiata alla base. */
.nz-ib, .ev-fld-x { display: inline-flex; align-items: center; justify-content: center; }
.nz-ib svg, .ev-fld-x svg { width: 16px; height: 16px; }


/* ============================================================================
   PIATTAFORMA › ENTI (§28 ago) — l'avanzamento di ogni ente, a conteggi.
   Mockup: docs/mockup/mockup_piattaforma_enti.html.

   Tutto è annidato sotto `.ep` di proposito, e non per vezzo: due dei nomi che il
   mockup usa esistono GIÀ nel foglio con un altro mestiere — `.avvio` è la card
   «Per cominciare» della Home del gestore, `.chip` è la pastiglia-filtro con bordo
   e accento. Scritte a livello globale se le sarebbero portate via entrambe, in
   pagine che nessuno ha guardato. Sotto `.ep` i nomi del mockup restano quelli, e
   non toccano niente fuori da questa pagina.

   Il mockup, essendo autonomo, inchioda i colori del tema chiaro: qui NO. Ogni
   colore viene dalle variabili, così le skin e il tema scuro reggono da soli.
   ============================================================================ */

/* --- la striscia di riepilogo: i cinque scalari della risposta, in fila ------------------- */
.ep .sommario {
  display: flex; gap: 1.6rem; flex-wrap: wrap; margin: 0 0 1rem; padding: .85rem 1.2rem;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--raggio);
}
.ep .sommario .it { display: flex; flex-direction: column; line-height: 1.15; }
.ep .sommario .it b { font-size: 1.35rem; font-weight: 600; letter-spacing: -.01em; }
.ep .sommario .it span { font-size: .78rem; color: var(--muted); }

/* --- la cella «ente»: iniziali + nome (con la pastiglia) + comune · tipo · data ----------- */
.ep .cell-ente { display: flex; align-items: center; gap: .6rem; min-width: 210px; }
.ep .ente-ini {
  flex: 0 0 32px; width: 32px; height: 32px; border-radius: var(--raggio-s);
  background: var(--page-tenue); color: var(--muted); border: 1px solid var(--border);
  display: grid; place-items: center; font-size: .78rem; font-weight: 600;
}
/* `min-width: 0` è ciò che permette al nome di troncare invece di allargare la colonna:
   senza, un flex item si rifiuta di scendere sotto la larghezza del suo contenuto. */
.ep .ente-cn { min-width: 0; display: flex; flex-direction: column; line-height: 1.2; }
.ep .ente-nome { font-weight: 500; }
.ep .ente-meta { font-size: .78rem; color: var(--muted); }
/* La pastiglia verificato/non verificato è il `.badge` di casa, solo rimpicciolito per stare
   in coda a un nome invece che in fondo a una card. */
.ep .ente-nome .badge { font-size: .66rem; padding: .06rem .42rem; margin: 0 0 0 .35rem; vertical-align: .05em; }

/* --- il semaforo a sei passi -------------------------------------------------------------
   L'ordine è FISSO (logo · copertina · primo socio · primo corso · primo maestro · prima
   presenza) perché è la POSIZIONE del pallino a dire quale passo manca; il `title` su ognuno
   lo scrive per chi non ha imparato l'ordine a memoria. */
.ep .avvio { display: flex; align-items: center; gap: .45rem; white-space: nowrap; }
.ep .pallini { display: inline-flex; gap: 3px; }
.ep .pallini i {
  width: 9px; height: 9px; border-radius: 50%; display: block;
  border: 1.4px solid var(--border); background: transparent;
}
.ep .pallini i.on { background: var(--ok); border-color: var(--ok); }
.ep .avvio .q { font-size: .8rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.ep .avvio.pieno .q { color: var(--ok-text); font-weight: 600; }

/* --- le celle numeriche e la loro seconda riga -------------------------------------------- */
.ep table.enti { width: 100%; border-collapse: collapse; }
.ep table.enti td { vertical-align: middle; }
.ep table.enti td.num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.ep .sotto { display: block; font-size: .78rem; color: var(--muted); }
.ep .sotto.rosso { color: var(--err-text); }
.ep .ambra { color: var(--warn-text); }
/* Gli stessi due toni di stato della pagina, ma sulla CELLA e non sulla sua seconda riga:
   le colonne «Ultimo atto umano» e «Domanda più vecchia» non hanno un `.sotto` su cui
   appoggiarli. Nessun colore nuovo: ambra = silenzio oltre il mese, rosso = non è mai
   successo niente, oppure qualcuno aspetta risposta da più di trenta giorni. */
.ep table.enti td.rosso { color: var(--err-text); }
.ep .barrina { margin-right: .4rem; }
.ep table.enti tbody tr.ep-riga { cursor: pointer; }
.ep table.enti tbody tr.ep-riga.aperta { background: var(--riga-hover); }

/* --- la riga di dettaglio ---------------------------------------------------------------
   Un secondo <tr> e non una modale: il punto della pagina è il CONFRONTO, e una modale
   nasconde proprio i vicini con cui si confronta.

   `minmax(0, 1fr)` e non `1fr`: la cella in colspan partecipa al calcolo delle larghezze
   della tabella, e una colonna di griglia che si rifiuta di scendere sotto il proprio
   contenuto trascinerebbe con sé le otto colonne di sopra. Con lo zero come minimo il
   dettaglio si adatta alla tabella, non il contrario. */
.ep tr.dett > td {
  background: var(--page-tenue); padding: 1rem 1.1rem 1.15rem; border-bottom: 1px solid var(--border);
}
.ep .dett-griglia { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1rem; }
@media (max-width: 960px) { .ep .dett-griglia { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.ep .blocco {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--raggio-s); padding: .75rem .85rem;
}
.ep .blocco h4 {
  margin: 0 0 .5rem; font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); font-weight: 600;
}
.ep .voce {
  display: flex; align-items: baseline; justify-content: space-between; gap: .6rem;
  padding: .16rem 0; font-size: .86rem;
}
.ep .voce span { color: var(--muted); }
.ep .voce b { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Le note diagnostiche: sono il motivo per cui il dettaglio esiste. Tre toni, e il tono NON è
   l'unico segnale — la frase dice sempre cosa non va, così regge anche a colori spenti. */
.ep .nota {
  margin-top: .7rem; font-size: .82rem; display: flex; gap: .45rem; align-items: flex-start;
  padding: .5rem .6rem; border-radius: var(--raggio-s);
  background: var(--warn-bg); color: var(--warn-text);
}
.ep .nota.grave { background: var(--err-bg); color: var(--err-text); }
.ep .nota.bene { background: var(--ok-bg); color: var(--ok-text); }
.ep .dett-piede { margin-top: .75rem; font-size: .79rem; color: var(--muted); }

/* --- la legenda sotto la tabella --------------------------------------------------------- */
.ep .legenda { margin: .9rem .1rem 0; font-size: .8rem; color: var(--muted); line-height: 1.5; }
.ep .legenda b { color: var(--text); font-weight: 600; }

/* ============================================================================
   STATISTICHE › UTENTI (§31 ago) — l'imbuto dall'iscrizione al tatami e i
   quattro stati, a soli conteggi. Mockup: docs/mockup/mockup_piattaforma_utenti.html.

   Tutto annidato sotto `.upf` per la stessa ragione di `.ep` qui sotto: i nomi
   del mockup (`.stato`, `.grad`, `.rig`, `.una`, `.nota`, `.sez`) sono corti e
   generici, e scritti a livello globale si porterebbero via pagine che nessuno
   ha guardato. Sotto `.upf` restano quelli del mockup e non toccano niente fuori.

   Il mockup, essendo autonomo, inchioda i colori del tema chiaro: qui NO. Ogni
   colore viene dalle variabili, così le skin e il tema scuro reggono da soli.
   ============================================================================ */

/* --- testata: il ritorno alla madre + titolo + il segmentato del periodo ------------------ */
.upf .dietro {
  font-size: .82rem; color: var(--muted); text-decoration: none;
  display: inline-block; margin-bottom: .5rem;
}
.upf .dietro:hover { color: var(--accent-text); }
.upf .testa { display: flex; align-items: flex-start; gap: 1rem; flex-wrap: wrap; margin-bottom: .2rem; }
.upf .testa .spazio { flex: 1; }
.upf .pagina-sub { max-width: 66ch; }

/* --- i titoletti di sezione --------------------------------------------------------------- */
.upf .sez {
  margin: 1.5rem 0 .55rem; font-size: .74rem; text-transform: uppercase;
  letter-spacing: .07em; color: var(--muted); font-weight: 600;
}

/* --- l'imbuto: etichetta + barra + caduta -------------------------------------------------- */
.upf .imbuto { display: flex; flex-direction: column; gap: .1rem; }
.upf .grad {
  display: grid; grid-template-columns: 15rem 1fr 8.5rem; gap: .9rem;
  align-items: center; padding: .42rem 0;
}
@media (max-width: 820px) {
  .upf .grad { grid-template-columns: 11rem 1fr; }
  .upf .grad .caduta { grid-column: 2; text-align: left; }
}
.upf .grad .et { font-size: .88rem; }
.upf .grad .et i { display: block; font-style: normal; font-size: .76rem; color: var(--muted); }
.upf .grad .bar {
  height: 26px; background: var(--page-tenue); border-radius: var(--raggio-s);
  position: relative; overflow: hidden;
}
.upf .grad .bar i {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: var(--accent); opacity: .88; border-radius: var(--raggio-s);
}
/* Il valore sta DENTRO la barra finché ci sta: sotto una certa quota esce a destra,
   in colore tenue, sennò diventa bianco su washi e non si legge più. */
.upf .grad .bar u {
  position: absolute; left: .6rem; top: 0; bottom: 0; display: flex; align-items: center;
  text-decoration: none; font-size: .82rem; font-weight: 600;
  color: var(--accent-on, #fff); font-variant-numeric: tabular-nums;
}
.upf .grad .bar u.fuori { left: auto; right: .6rem; color: var(--muted); }
.upf .grad .caduta {
  font-size: .8rem; color: var(--muted); text-align: right;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.upf .grad .caduta b { color: var(--err-text); font-weight: 600; }
/* La caduta PEGGIORE si calcola, non si inchioda al primo gradino: qui è solo il vestito. */
.upf .grad.peggiore .caduta b {
  background: var(--err-bg); border-radius: 20px; padding: .06rem .42rem;
}

/* --- le legende: righe di testo, con i grassetti che non vanno a capo storti ---------------- */
.upf .legenda {
  margin: .9rem .1rem 0; font-size: .8rem; color: var(--muted);
  line-height: 1.5; max-width: 78ch;
}
.upf .legenda b { color: var(--text); font-weight: 600; }
/* Le frasi stanno in <span> distinti e vanno in blocco, una per riga. */
.upf .legenda span { display: block; }

/* --- i quattro stati ----------------------------------------------------------------------- */
.upf .stati { display: grid; grid-template-columns: repeat(4, 1fr); gap: .9rem; }
@media (max-width: 900px) { .upf .stati { grid-template-columns: repeat(2, 1fr); } }
.upf .stato {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--raggio);
  padding: .9rem 1rem;
}
/* Mai il colore da solo: il pallino sta SEMPRE accanto alla sua etichetta. */
.upf .stato .cap { display: flex; align-items: center; gap: .4rem; font-size: .78rem; color: var(--muted); }
.upf .stato .dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 9px; }
.upf .stato .dot.ok { background: var(--ok); }
.upf .stato .dot.warn { background: var(--warn); }
.upf .stato .dot.err { background: var(--err); }
.upf .stato .dot.neu { background: var(--neutro, #C9C2B4); }
.upf .stato .v {
  font-size: 1.75rem; font-weight: 600; letter-spacing: -.02em; line-height: 1.25;
  font-variant-numeric: tabular-nums;
}
.upf .stato .sub { font-size: .79rem; color: var(--muted); margin-top: .15rem; }
.upf .stato .voce {
  display: flex; justify-content: space-between; gap: .6rem; font-size: .8rem;
  padding: .14rem 0; border-top: 1px dashed var(--border); margin-top: .35rem;
}
.upf .stato .voce:first-of-type { margin-top: .55rem; }
.upf .stato .voce span { color: var(--muted); }
.upf .stato .voce b { font-weight: 600; font-variant-numeric: tabular-nums; }
.upf .stato .allarme {
  margin-top: .55rem; font-size: .79rem; padding: .35rem .5rem;
  border-radius: var(--raggio-s); background: var(--err-bg); color: var(--err-text);
}
.upf .stato .allarme b { font-weight: 600; }

/* --- «su cosa lavorano»: il numero grosso accanto alla scomposizione ----------------------- */
.upf .ort {
  margin-top: .9rem; background: var(--card); border: 1px solid var(--border);
  border-radius: var(--raggio); padding: 1rem 1.2rem;
  display: grid; grid-template-columns: 12rem 1fr; gap: 1.4rem; align-items: start;
}
@media (max-width: 820px) { .upf .ort { grid-template-columns: 1fr; } }
.upf .ort .n {
  font-size: 1.75rem; font-weight: 600; letter-spacing: -.02em; line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.upf .ort .n span { display: block; font-size: .78rem; font-weight: 400; color: var(--muted); letter-spacing: 0; }

/* La nota d'ambiguità. Il testo sta in UN solo <span> di proposito: dentro un flex, un <b> in
   mezzo alla frase diventa una colonna a sé e la nota si spezza in blocchi frastagliati —
   visto davvero al primo render del mockup. Il `min-width:0` è l'altra metà della cura. */
.upf .nota {
  font-size: .82rem; display: flex; gap: .45rem; align-items: flex-start;
  padding: .55rem .65rem; border-radius: var(--raggio-s);
  background: var(--warn-bg); color: var(--warn-text); margin-top: .5rem;
}
.upf .nota > .tx { flex: 1; min-width: 0; }

/* --- le distribuzioni: quattro cartine, ognuna con la SUA scala ---------------------------- */
.upf .griglia2 { display: grid; grid-template-columns: 1fr 1fr; gap: .9rem; }
@media (max-width: 820px) { .upf .griglia2 { grid-template-columns: 1fr; } }
.upf .ct { display: flex; flex-direction: column; line-height: 1.25; margin-bottom: .75rem; }
.upf .ct b { font-size: .92rem; font-weight: 600; }
.upf .ct span { font-size: .78rem; color: var(--muted); }
.upf .rig {
  display: grid; grid-template-columns: 9rem 1fr 3.2rem; gap: .7rem;
  align-items: center; padding: .2rem 0; font-size: .85rem;
}
.upf .rig .bb {
  height: 16px; background: var(--page-tenue); border-radius: 5px;
  position: relative; overflow: hidden;
}
.upf .rig .bb i {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: var(--accent); opacity: .85; border-radius: 5px;
}
/* Tenue = il secchiello che non è un risultato ma il suo contorno («nessuna app», «mai
   arrivati»): sta nella stessa scala, ma non si legge come una vittoria. */
.upf .rig .bb i.tenue { opacity: .35; }
.upf .rig .q { text-align: right; font-variant-numeric: tabular-nums; color: var(--muted); }

/* --- i tre scalari in fondo ---------------------------------------------------------------- */
.upf .una {
  margin-top: .9rem; background: var(--card); border: 1px solid var(--border);
  border-radius: var(--raggio); padding: 1rem 1.2rem;
  display: flex; gap: 2.2rem; flex-wrap: wrap; align-items: baseline;
}
.upf .una .it { display: flex; flex-direction: column; line-height: 1.2; }
.upf .una .it b {
  font-size: 1.35rem; font-weight: 600; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}
.upf .una .it span { font-size: .78rem; color: var(--muted); }

/* ============================================================================
   GUSCIO A SCHEDE — «il web prende la forma dell'app» (deciso 2 set)
   Schema: docs/mockup/budopass_web_come_app.html

   Tutto sotto una radice sola, `.shell-app`, perché i due gusci convivono: senza quel prefisso
   le due navigazioni si contenderebbero gli stessi selettori (.barra-rail, .nav, .barra-laterale) e
   il confronto misurerebbe l'interferenza invece dei due impianti. Da qui in giù nessuna regola
   esce dalla radice, e spegnere l'interruttore riporta il rail identico a com'era.

   I colori NON sono quelli del mockup, che dipinge la barra di un grigio scuro fisso: sull'app
   la barra è `SfondoBarra`, cioè la SUPERFICIE ALZATA (la stessa cosa che sul web è
   `--card-alta`), e diventa accento pieno solo con la skin Sumi. Copiare il grigio del mockup
   avrebbe dato una barra che non segue né tema né skin — cioè l'unico pezzo di WebAdmin sordo
   alle preferenze che quella stessa barra regola.
   ============================================================================ */

.shell-app { display: flex; flex-direction: column; min-height: 100vh; position: relative; }

/* --- la barra: ☰ · emblema+nome+▾ · campana · cursori (l'ordine di BarraApp) --------------
   `sticky` è anche l'àncora dei due menù che scendono da qui (un valore posizionato), e crea
   sempre un contesto d'impilamento: 45 la tiene sopra il .menu-backdrop (40) e sotto i .menu
   (50), che è la stessa taratura per cui il rail non si faceva rubare i clic dallo switcher. */
.shell-app .sa-barra {
  position: sticky; top: 0; z-index: 45;
  padding: .5rem 0;
  background: var(--card-alta);
  border-bottom: 1px solid var(--border);
}

/* La colonna DENTRO le due strisce (deciso 2 set, variante A del mockup
   `budopass_barra_schede_allineamento.html`). Su schermo largo la fila delle schede partiva dal
   bordo della finestra mentre il contenuto era una colonna centrata: fra «Soci» in alto e «Soci»
   nel titolo passavano cinquecento pixel di niente, e la sottolineatura della scheda attiva stava
   sopra nessuna pagina.

   ⚠️ A spostarsi è solo il CONTENUTO: fondo e filo delle strisce restano da bordo a bordo, perché
   sono la cornice del guscio — una barra che finisce a 1180px sembrerebbe una card che galleggia. */
.shell-app .sa-colonna {
  width: 100%; max-width: var(--colonna); margin-inline: auto;
  display: flex; align-items: center; gap: .5rem;
  /* Àncora dei due menù che scendono dalla barra: si aprono sotto i comandi, che ora stanno
     dentro la colonna e non più al bordo della finestra. */
  position: relative;
}

/* Le spalle rientrano della propria intercapedine, e non è una limatura: sulla verticale della
   colonna deve cadere il SEGNO, non la scatola che gli sta attorno. Il ☰ e i cursori sono tondi
   da 36 con un glifo da 19 al centro; col loro BOX sulla colonna, il segno cadrebbe 8,5px più
   dentro del titolo di pagina — cioè si vedrebbe. I due numeri sono quelli veri del comando, non
   una taratura a occhio: cambiando la tonda, l'allineamento si aggiusta da sé. */
.shell-app .sa-barra .sa-colonna {
  --tondo: 36px;
  --tondo-segno: 19px;
  padding-inline: calc(var(--colonna-lato) - (var(--tondo) - var(--tondo-segno)) / 2);
}

/* Le tonde dei comandi: ☰ a sinistra e i cursori a destra. La campana è CampanaNotifiche, che
   porta la sua .ico-btn — qui si allinea la misura, non si ridisegna il componente. */
.shell-app .sa-tondo,
.shell-app .sa-barra .ico-btn {
  width: 36px; height: 36px; flex: 0 0 auto; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; border-radius: 999px;
  background: transparent; color: var(--text); cursor: pointer;
}
.shell-app .sa-tondo:hover,
.shell-app .sa-barra .ico-btn:hover { background: var(--riga-hover); }
.shell-app .sa-tondo svg, .shell-app .sa-barra .ico-btn svg { width: 19px; height: 19px; }

/* Il blocco emblema + nome + sottotitolo + ▾: UN solo bersaglio, largo, come sull'app — non il
   solo emblema. `flex: 1` lo fa arrivare fino ai comandi di destra, `min-width: 0` lascia che i
   due testi si tronchino invece di spingere fuori la campana. */
.shell-app .sa-ctx {
  display: flex; align-items: center; gap: .55rem; flex: 1; min-width: 0;
  padding: .25rem .4rem; border: none; border-radius: var(--raggio-s);
  background: transparent; color: var(--text); font-family: var(--sans); text-align: left;
}
.shell-app .sa-ctx-btn { cursor: pointer; }
.shell-app .sa-ctx-btn:hover { background: var(--riga-hover); }

.shell-app .sa-emblema {
  position: relative; flex: 0 0 auto; width: 34px; height: 34px; border-radius: 10px;
  overflow: hidden; background: var(--accent-tenue); color: var(--accent-text);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: .8rem; font-family: var(--jp);
}
.shell-app .sa-emblema img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.shell-app .sa-nome { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.shell-app .sa-nome b { font-weight: 600; font-size: .95rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.shell-app .sa-nome span { font-size: .75rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.shell-app .sa-chev { flex: 0 0 auto; color: var(--muted); font-size: .7rem; padding-left: .2rem; }

/* I due menù scendono dalla COLONNA (ne sono figli): il bordo del menù cade sulla verticale della
   colonna, come i comandi che lo aprono. `top` è esplicito perché il 100% qui è l'altezza del
   contenuto, non della striscia: senza, il menù salirebbe sopra il filo inferiore della barra. */
.shell-app .sa-menu-profilo,
.shell-app .sa-menu-pref { top: calc(100% + .5rem); max-width: calc(100vw - 1.2rem); }
.shell-app .sa-menu-profilo { left: 0; width: 292px; }
.shell-app .sa-menu-pref { right: 0; width: 268px; }

/* --- le quattro schede ---------------------------------------------------------------------
   In ALTO e non in basso: è l'unica differenza voluta rispetto all'app (2 set). Scorrono in
   orizzontale sugli schermi stretti invece di andare a capo: quattro schede su due righe non
   sono più una fila, e la fila è il punto. */
.shell-app .sa-schede {
  background: var(--card-alta); border-bottom: 1px solid var(--border);
}

/* Lo scorrimento orizzontale sta sulla COLONNA e non sulla striscia: così la regione che scorre e
   la colonna a cui ci si allinea sono la stessa scatola, e il nastro comincia e finisce esatto
   sulle due verticali. Con lo scorrimento sulla striscia e le spalle sulla scatola interna, un
   nastro scorso lascia una fascia vuota a un capo e sborda dalla cornice all'altro.
   (Su schermo largo non scorre mai: quattro schede non riempiono la colonna.)

   La spalla di sinistra rientra della propria spalla della scheda, per la stessa ragione delle
   tonde qui sopra: a cadere sulla verticale dev'essere l'ETICHETTA della prima scheda, che è la
   parola che l'occhio confronta col titolo. Rientro come PADDING e non come margine negativo:
   dentro un contenitore che scorre, un margine negativo porterebbe la prima scheda fuori dalla
   scatola scorrevole, dove viene tagliata e non la si raggiunge più. */
.shell-app .sa-schede .sa-colonna {
  --sa-tab-lato: .8rem;
  gap: .1rem; align-items: stretch;
  padding-inline-start: calc(var(--colonna-lato) - var(--sa-tab-lato));
  padding-inline-end: var(--colonna-lato);
  overflow-x: auto; scrollbar-width: none;
}
.shell-app .sa-schede .sa-colonna::-webkit-scrollbar { display: none; }

.shell-app .sa-tab {
  display: inline-flex; align-items: center; gap: .35rem; white-space: nowrap;
  padding: .65rem var(--sa-tab-lato); font-size: .88rem; color: var(--muted);
  border-bottom: 2px solid transparent; text-decoration: none;
}
.shell-app .sa-tab:hover { color: var(--text); text-decoration: none; }
.shell-app .sa-tab.on { color: var(--accent-text); font-weight: 600; border-bottom-color: var(--accent); }
.shell-app .sa-tab .conta {
  background: var(--accent); color: var(--accent-on); border-radius: 8px;
  min-width: 17px; height: 17px; padding: 0 .28rem; font-size: .66rem; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}

/* La pagina resta `.pagina` (stessi margini e stessa animazione d'ingresso del rail): senza il
   rail si centra invece di restare incollata a sinistra — ed è la colonna su cui si mettono anche
   la barra e le schede qui sopra. */
.shell-app .pagina { margin: 0 auto; }

/* --- il cassetto ---------------------------------------------------------------------------
   Fuori dallo schermo di suo, dentro con la classe: fisso, quindi non allunga la pagina e non
   scorre col contenuto. Sopra c'è la PERSONA e la veste in cui sta lavorando — nessun dojo, che
   è precisamente la riga per cui questo guscio esiste. */
.shell-app .sa-velo { position: fixed; inset: 0; z-index: 55; background: rgba(20, 17, 14, .45); }

.shell-app .sa-cassetto {
  position: fixed; top: 0; left: 0; bottom: 0; z-index: 60;
  width: 292px; max-width: 86vw;
  display: flex; flex-direction: column;
  background: var(--card); border-right: 1px solid var(--border);
  transform: translateX(-100%); transition: transform .22s var(--curva);
  box-shadow: 6px 0 24px rgba(0, 0, 0, .28);
}
.shell-app .sa-cassetto.aperto { transform: translateX(0); }

.shell-app .sa-banda { background: var(--accent); color: var(--accent-on); padding: .8rem .85rem 1rem; }
.shell-app .sa-banda-riga { display: flex; align-items: flex-start; }
.shell-app img.sa-avatar { object-fit: cover; }
.shell-app .sa-avatar {
  width: 40px; height: 40px; border-radius: 999px;
  background: rgba(255, 255, 255, .2); color: var(--accent-on);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: .82rem;
}
.shell-app .sa-x {
  margin-left: auto; border: none; background: transparent; cursor: pointer;
  color: var(--accent-on); opacity: .85; font-size: 1rem; line-height: 1; padding: .3rem;
}
.shell-app .sa-banda-nome {
  margin-top: .55rem; font-weight: 600; font-size: .95rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.shell-app .sa-banda-sotto { font-size: .78rem; opacity: .8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.shell-app .sa-voci { flex: 1; overflow-y: auto; padding: .45rem .5rem; }
.shell-app .sa-voce {
  display: flex; align-items: flex-start; gap: .6rem;
  padding: .5rem .55rem; border-radius: var(--raggio-s);
  color: var(--text); text-decoration: none;
}
.shell-app .sa-voce:hover { background: var(--riga-hover); text-decoration: none; }
.shell-app .sa-voce .ic { flex: 0 0 18px; color: var(--muted); display: inline-flex; padding-top: .1rem; }
.shell-app .sa-voce .ic svg { width: 17px; height: 17px; }
.shell-app .sa-voce .tx { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.shell-app .sa-voce .tx .t { font-size: .88rem; font-weight: 500; }
/* La descrizione va a capo (niente troncatura), come nel cassetto dell'app: una riga lunga si
   legge tutta, ed è il motivo per cui icona e chevron stanno in alto e non al centro. */
.shell-app .sa-voce .tx .m { font-size: .73rem; color: var(--muted); }
.shell-app .sa-voce .ch { flex: 0 0 auto; color: var(--muted); font-size: 1rem; line-height: 1.2; }
.shell-app .sa-voce .n {
  flex: 0 0 auto; background: var(--accent); color: var(--accent-on); border-radius: 8px;
  min-width: 17px; height: 17px; padding: 0 .28rem; font-size: .66rem; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center; margin-top: .1rem;
}

.shell-app .sa-piede { border-top: 1px solid var(--border); padding: .3rem .5rem .5rem; }
.shell-app .sa-versione {
  display: flex; align-items: center; padding: .5rem .55rem; border-radius: var(--raggio-s);
  color: var(--muted); font-size: .78rem; text-decoration: none;
}
.shell-app .sa-versione:hover { background: var(--riga-hover); text-decoration: none; }
.shell-app .sa-versione .ch { margin-left: auto; color: var(--accent); }
/* Nella demo la versione è solo un numero (6 set): niente storico «Novità», niente chevron. */
.shell-app .sa-versione.ferma { cursor: default; }
.shell-app .sa-versione .bollino-demo { position: static; margin-right: .5rem; }
.shell-app .sa-versione.ferma:hover { background: transparent; }
.shell-app .sa-account { display: flex; align-items: center; gap: .4rem; padding: .2rem .55rem .1rem; }
.shell-app .sa-account .em {
  flex: 1; min-width: 0; font-size: .76rem; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.shell-app .sa-esci {
  flex: 0 0 auto; border: none; background: transparent; cursor: pointer;
  color: var(--accent-text); display: inline-flex; padding: .35rem; border-radius: var(--raggio-s);
}
.shell-app .sa-esci:hover { background: var(--riga-hover); }
.shell-app .sa-esci svg { width: 17px; height: 17px; }

/* Sumi lava barra e schede d'accento pieno, come fa già col rail e con la testata — e come fa
   l'app, dove `SfondoBarra` passa al pieno d'accento. Senza questo, il testo scuro di default e
   i comandi sparirebbero sul fondo colorato. La scheda attiva non può essere l'accento (è già il
   fondo): la distingue il testo pieno contro quello spento, esattamente come `TabAttiva`. */
html[data-skin="sumi"] .shell-app .sa-barra,
html[data-skin="sumi"] .shell-app .sa-schede {
  background: var(--accent); border-bottom-color: var(--accent-banda);
}
html[data-skin="sumi"] .shell-app .sa-tondo,
html[data-skin="sumi"] .shell-app .sa-barra .ico-btn,
html[data-skin="sumi"] .shell-app .sa-ctx,
html[data-skin="sumi"] .shell-app .sa-nome b,
html[data-skin="sumi"] .shell-app .sa-chev { color: var(--accent-on); }
html[data-skin="sumi"] .shell-app .sa-nome span { color: var(--accent-on); opacity: .8; }
html[data-skin="sumi"] .shell-app .sa-emblema { background: rgba(255, 255, 255, .18); color: var(--accent-on); }
html[data-skin="sumi"] .shell-app .sa-tondo:hover,
html[data-skin="sumi"] .shell-app .sa-barra .ico-btn:hover,
html[data-skin="sumi"] .shell-app .sa-ctx-btn:hover { background: rgba(255, 255, 255, .18); }
html[data-skin="sumi"] .shell-app .sa-tab { color: var(--accent-on); opacity: .72; }
html[data-skin="sumi"] .shell-app .sa-tab.on { color: var(--accent-on); opacity: 1; border-bottom-color: var(--accent-on); }
html[data-skin="sumi"] .shell-app .sa-tab .conta { background: rgba(255, 255, 255, .22); color: var(--accent-on); }
/* La banda del cassetto è già accento pieno: su Sumi resta tale, ma il filo che la stacca dal
   corpo va all'accento-banda come tutti gli altri fili di questa skin. */
html[data-skin="sumi"] .shell-app .sa-banda { border-bottom: 1px solid var(--accent-banda); }

@media (max-width: 640px) {
  /* Sotto il breakpoint la colonna coincide con la finestra: cambia la sola spalla, in un posto
     solo, e con lei rientrano pagina, barra e schede insieme. Scoped a `.shell-app` perché il rail
     qui non c'entra: la sua spalla resta quella del suo strato mobile. */
  .shell-app { --colonna-lato: .9rem; }
  .shell-app .pagina { padding-block: 1rem; }
  .shell-app .sa-barra { padding-block: .45rem; }
  .shell-app .sa-barra .sa-colonna { gap: .3rem; }
  /* Il sottotitolo del profilo esce per primo: su un telefono la riga deve dire CHI, e il ruolo
     o la disciplina rubano la larghezza al nome, che è l'informazione. */
  .shell-app .sa-nome span { display: none; }
}


/* ==========================================================================
   I PEZZI CONDIVISI — «il web parla la lingua dell'app» (2 set)
   --------------------------------------------------------------------------
   Quattro componenti, gemelli di quelli della MAUI e con gli stessi nomi:
   Sezione (SectionHeader + Skin.xaml), Riga (RigaVoce / SocioCard), Campo
   (CampoTesto / CampoScelta / CampoTestoMemo), Foglio (FoglioBottom). Le misure
   sono quelle di Stili.xaml, passate dai token --t-* in cima al foglio.

   Perché esistono: il guscio a schede è già quello dell'app, le pagine dentro no.
   Misurato il 2 set: il titolo di sezione stava DENTRO la carta a 9,5px sbiadito
   (sull'app è sopra, a 12px spaziati); le liste erano tabelle o card
   etichetta/valore; i moduli input nudi; le azioni bottoni stampati su ogni riga.
   Tutto ciò che qui è colore viene dai token: nessun pezzo è sordo a tema,
   accento o skin — e la Sezione è proprio il punto in cui lo skin torna a fare
   qualcosa sul web (Obi = banda piena, come sull'app).
   ========================================================================== */

/* --- Sezione: l'intestazione FUORI dalla carta ------------------------------------------- */
.sezione {
  display: flex; align-items: center; gap: .6rem;
  margin: 18px 0 8px; min-height: 22px;
}
/* La prima sezione di una pagina o di una colonna non ha bisogno di respirare sopra. */
.sezione:first-child { margin-top: 4px; }
.sezione-titolo {
  font-size: var(--t-sezione); font-weight: 600; letter-spacing: .13em;
  text-transform: uppercase; color: var(--muted); line-height: 1.3;
}
/* Lo stato accanto al titolo («TESSERA · Scaduta»): non un'azione, quindi non a destra (§26 ago). */
.sezione-pastiglia { display: inline-flex; }
.sezione-pastiglia:empty { display: none; }
.sezione-pastiglia .badge { margin: 0; }
/* L'azione: un comando prende l'accento («Vedi tutti ›», «Stagione 2026/27 ›»); una sola
   etichetta (un periodo che non si tocca) resta tenue — AzioneCliccabile, come sull'app. */
.sezione-azione { font-size: 13.5px; color: var(--muted); white-space: nowrap; }
.sezione-azione.cliccabile,
.sezione-azione.cliccabile a,
.sezione-azione.cliccabile button { color: var(--accent-text); font-weight: 500; text-decoration: none; }
.sezione-azione.cliccabile a:hover { text-decoration: none; opacity: .85; }
/* Il blocco che tiene insieme intestazione e carta (Carta.razor): per griglie e colonne flex è
   un figlio solo, come lo era la carta da sola. Dentro, la sezione non ha margine sopra — lo
   spazio fra un blocco e l'altro è del contenitore, com'era per le carte. */
.sezione-blocco { min-width: 0; }
.sezione-blocco > .sezione { margin-top: 0; }
/* Un titolo di carta scritto a mano (<h2>) non ha bisogno dello style="margin-top:0" che
   ventidue pagine ripetono: lo azzera la carta. */
.carta > h2:first-child { margin-top: 0; }

/* Obi — la banda piena dell'app (SezioneObi in Skin.xaml): l'accento è il fondo, tutto ciò che
   ci sta sopra prende il colore su-accento — ripetere l'accento sull'azione la renderebbe
   invisibile. Ma e Sumi restano etichetta nuda: la banda è di Obi soltanto (§3.1, 24 lug). */
html[data-skin="obi"] .sezione {
  background: var(--accent); color: var(--accent-on);
  padding: 8px 16px; border-radius: 10px; margin-bottom: 10px;
}
html[data-skin="obi"] .sezione-titolo,
html[data-skin="obi"] .sezione-azione,
html[data-skin="obi"] .sezione-azione.cliccabile,
html[data-skin="obi"] .sezione-azione.cliccabile a,
html[data-skin="obi"] .sezione-azione.cliccabile button { color: var(--accent-on); }
html[data-skin="obi"] .sezione-azione { opacity: .92; }

/* --- Riga: la riga di ogni elenco ---------------------------------------------------------- */
.carta.piena { padding: 0; overflow: hidden; }
.riga {
  display: flex; align-items: center; gap: .75rem;
  padding: 12px 16px; color: var(--text); text-decoration: none;
}
.riga + .riga { border-top: 1px solid var(--border); }
.riga-av {
  flex: 0 0 36px; width: 36px; height: 36px; border-radius: 10px; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-tenue); color: var(--accent-text);
  font-weight: 600; font-size: .82rem; font-family: var(--jp);
}
.riga-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Un segno grafico (SegnoGrado) porta il suo colore: la casella si fa trasparente. */
.riga-av .rp-segno { display: block; line-height: 0; }
.riga-av:has(.rp-segno) { background: transparent; }
.riga-av .token-svg { width: 36px; height: auto; display: block; }
.riga-corpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.riga-titolo { font-size: var(--t-valore); font-weight: 600; line-height: 1.25; }
.riga-meta { font-size: var(--t-meta); color: var(--muted); line-height: 1.3; }
.riga-coda {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: flex-end;
  gap: .35rem; flex-wrap: wrap; text-align: right; font-size: .86rem; max-width: 46%;
}
.riga-coda .badge { margin: 0; }
/* Il valore di RigaPersona in coda (5 set, Fudo: «controlla questi margini, soprattutto su
   mobile»): era un solo span `flex: 0 0 auto`, che non si stringeva mai — con due pastiglie e
   «13 registrati» superava il 46 % della riga e, allineato a destra, sbordava a SINISTRA sopra il
   titolo. Ora è un flex che va a capo dentro la coda: le pastiglie e il conteggio si dispongono su
   più righe quando lo spazio manca, con un'aria fissa fra loro. */
.riga-coda .rp-valore {
  display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center;
  gap: .3rem .4rem; flex: 0 1 auto; min-width: 0; margin-left: 0;
}
/* Su telefono la coda è sempre in COLONNA, un elemento per riga (5 set, Fudo: «come mai qua non
   è andato a capo?»): «Pubblicato · 7 registrati» ci stava in una riga e non aveva motivo di
   spezzarsi, ma così le code avevano larghezze diverse e i titoli si stringevano in modo
   disuguale da una riga all'altra. In colonna la coda è stretta quanto la pastiglia più larga,
   uguale per tutte le righe, e al titolo resta lo stesso spazio ovunque. */
@media (max-width: 560px) {
  .riga-coda .rp-valore { flex-direction: column; align-items: flex-end; gap: .25rem; }
}
.riga-vai { flex: 0 0 auto; color: var(--muted); font-size: 1.15rem; line-height: 1; }
.riga.cliccabile { cursor: pointer; transition: background var(--t-corta) ease; }
.riga.cliccabile:hover { background: var(--riga-hover); text-decoration: none; color: var(--text); }
.riga.cliccabile:hover .riga-vai { color: var(--accent-text); }
.riga.cliccabile:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* La riga la cui scheda è aperta a fianco (master-detail degli indici, prompt a parte). */
.riga.selezionata, .riga.selezionata:hover { background: var(--accent-tenue); }
.riga.cessato .riga-titolo { color: var(--muted); font-weight: 500; }

/* --- Campo: i campi «filled A» (§3.1, rivisto 26 lug) ------------------------------------- */
/* L'etichetta SOPRA il campo, testo normale e tenue — mai nel bordo, che faceva la «toppa». */
.campo-et { display: block; font-size: .86rem; color: var(--muted); margin-bottom: .35rem; font-weight: 500; }
/* L'asterisco del campo richiesto, nell'accento e in grassetto (5 set sera, Fudo: «evidenzia i campi
   richiesti»): prima era sottile e si perdeva accanto all'etichetta tenue. */
.campo-obbl { color: var(--accent-text); font-weight: 700; font-size: 1.1em; margin-left: .2rem; }
/* La scatola: superficie propria (carta sul chiaro, alzata sullo scuro — SuperficieCampo
   dell'app), bordo tenue, raggio 10. L'input dentro è nudo: bordo, fondo e anello li porta la
   scatola, così testo, tendina e memo hanno la stessa veste. `background-color` e non
   `background`: il select globale tiene il chevron come background-image, e la scorciatoia
   lo cancellerebbe (è la trappola del 26 ago). */
.campo-box {
  display: flex; align-items: stretch;
  background: var(--card); border: 1px solid var(--border); border-radius: 10px;
  transition: border-color var(--t-corta) ease, box-shadow var(--t-corta) ease;
}
.campo-box input, .campo-box select, .campo-box textarea {
  flex: 1; width: 100%; min-width: 0; margin: 0;
  border: 0; border-radius: 10px; background-color: transparent;
  padding: .62rem .8rem; font: inherit; font-size: .95rem; color: var(--text);
  outline: none; box-shadow: none;
}
.campo-box textarea { resize: vertical; line-height: 1.45; }
.campo-box select { padding-right: 2.1rem; }
.campo-box input::placeholder, .campo-box textarea::placeholder { color: var(--muted); opacity: .8; }
.campo-box input:disabled, .campo-box select:disabled, .campo-box textarea:disabled { background-color: transparent; }
.campo-box:hover { border-color: var(--muted); }
/* Focus: bordo ed etichetta in accento, come CampoTesto.xaml. */
.campo:focus-within .campo-box { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tenue); }
.campo:focus-within .campo-et { color: var(--accent-text); }
/* Errore: vira il campo, e la riga sotto lo spiega (inline, mai un dialogo). */
.campo.err .campo-box { border-color: var(--err); background: var(--err-bg); }
.campo.err .campo-et { color: var(--err-text); }
/* Disabilitato: il look sbiadito SOLO qui, dove è vero. */
.campo.dis .campo-box { background: var(--page-tenue); border-color: var(--border); }
.campo.dis .campo-box:hover { border-color: var(--border); }
.campo.dis .campo-et { opacity: .7; }
.campo.dis .campo-box input, .campo.dis .campo-box select, .campo.dis .campo-box textarea { color: var(--muted); cursor: not-allowed; }
.campo-aiuto { font-size: .8rem; color: var(--muted); margin-top: .4rem; line-height: 1.4; }
/* CampoData sta in fila con gli altri: stesso raggio, stessa altezza. */
.campo-data { border-radius: 10px; min-height: 2.6rem; }
/* I bottoni in fondo a un modulo, a destra. */
.fila-destra { display: flex; justify-content: flex-end; gap: .6rem; flex-wrap: wrap; margin-top: .4rem; }

/* --- Foglio: il foglio dell'app, da destra (e dal basso sotto gli 820px) ------------------ */
.foglio-velo {
  position: fixed; inset: 0; z-index: 70; background: rgba(20, 17, 14, .45);
  animation: foglio-velo var(--t-media) ease-out;
}
@keyframes foglio-velo { from { opacity: 0; } to { opacity: 1; } }
.foglio { display: flex; flex-direction: column; outline: none; }
.foglio.sovrapposto {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 71;
  width: 480px; max-width: 92vw;
  background: var(--card-alta); border-left: 1px solid var(--border);
  box-shadow: -8px 0 30px rgba(0, 0, 0, .22);
  animation: foglio-entra var(--t-lunga) var(--curva);
}
@keyframes foglio-entra { from { transform: translateX(56px); opacity: 0; } to { transform: none; opacity: 1; } }
/* Affiancato: la colonna destra di uno split. Il CSS c'è, chi lo aggancia è il prompt degli indici. */
.foglio.affiancato {
  position: sticky; top: 1rem; max-height: calc(100vh - 2rem);
  background: var(--card); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--ombra);
}
.foglio-testa {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: 1rem 1.1rem .8rem; border-bottom: 1px solid var(--border);
}
.foglio-occhiello {
  flex-basis: 100%; font-size: var(--t-sezione); letter-spacing: .13em;
  text-transform: uppercase; color: var(--muted); font-weight: 600;
}
.foglio-titolo { margin: 0; font-size: var(--t-titolo); font-weight: 600; flex: 1; min-width: 0; }
.foglio-x {
  flex: 0 0 auto; margin-left: auto; width: 32px; height: 32px; border: 0; border-radius: 999px;
  background: transparent; color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.foglio-x:hover { background: var(--riga-hover); color: var(--text); }
.foglio-x svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; }
.foglio-corpo { flex: 1; overflow-y: auto; padding: 1rem 1.1rem; }
.foglio-piede {
  display: flex; gap: .6rem; justify-content: flex-end; flex-wrap: wrap;
  padding: .8rem 1.1rem; border-top: 1px solid var(--border); background: var(--card-alta);
}
@media (max-width: 820px) {
  /* Il bottom sheet dell'app: tutta la larghezza, sale dal basso, angoli alti arrotondati. */
  .foglio.sovrapposto {
    top: auto; left: 0; right: 0; bottom: 0; width: 100%; max-width: none; max-height: 92vh;
    border-left: 0; border-top: 1px solid var(--border); border-radius: 18px 18px 0 0;
    box-shadow: 0 -8px 30px rgba(0, 0, 0, .22);
    animation-name: foglio-sale;
  }
  @keyframes foglio-sale { from { transform: translateY(56px); opacity: 0; } to { transform: none; opacity: 1; } }
}
@media (prefers-reduced-motion: reduce) { .foglio, .foglio-velo { animation: none; } }

/* --- Il guscio a schede: due ritocchi misurati contro BarraApp (2 set) -------------------- */
/* La pastiglia col chevron del commutatore (30×30, raggio 9, fondo adattivo): il «▾» da 0,7rem
   a schermo era un puntino accanto al nome. */
.shell-app .sa-chev {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 9px; padding: 0; margin-left: .25rem;
  background: rgba(0, 0, 0, .08); color: var(--text);
  display: inline-flex; align-items: center; justify-content: center; font-size: 0;
}
.shell-app .sa-chev svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
html[data-theme="dark"] .shell-app .sa-chev { background: rgba(255, 255, 255, .15); }
@media (prefers-color-scheme: dark) {
  html[data-theme="system"] .shell-app .sa-chev,
  html:not([data-theme]) .shell-app .sa-chev { background: rgba(255, 255, 255, .15); }
}
html[data-skin="sumi"] .shell-app .sa-chev { background: rgba(255, 255, 255, .22); color: var(--accent-on); }
/* L'icona davanti all'etichetta della scheda, come la TabBar dell'app. */
.shell-app .sa-tab .ic { display: inline-flex; flex: 0 0 auto; }
.shell-app .sa-tab .ic svg { width: 17px; height: 17px; }

/* --- Soci: elenco di Riga sotto il breakpoint, tabella sopra ----------------------------- */
/* Dai 1100px in su (5/5) l'elenco può aprire la scheda a fianco: sotto, la riga naviga. */
@media (max-width: 1099.98px) { .solo-largo { display: none; } }
@media (min-width: 1100px) { .solo-stretto { display: none; } }
.lista-conteggio { margin-top: .75rem; }

/* --- valori calcolati che entrano dal markup come proprietà personalizzate ---------------- */
.barra-freq > i { width: var(--p, 0%); }
.barrina i { width: var(--p, 0%); }

/* --- Impostazioni utente › Profilo (pagina di prova dei Campo) ---------------------------- */
.imp-profilo { display: flex; gap: 1rem; align-items: flex-start; flex-wrap: wrap; }
.imp-profilo-avatar {
  flex: 0 0 auto; width: 64px; height: 64px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-tenue); color: var(--accent-text); font-weight: 700; font-size: 1.3rem;
}
/* La foto del profilo (3 set): l'immagine nel tondo al posto delle iniziali, e sotto le due
   azioni piccole (scegli / elimina) — link, non bottoni: sono di contorno alla foto. */
img.imp-profilo-avatar { object-fit: cover; }
.imp-profilo-foto { display: flex; flex-direction: column; align-items: center; gap: .4rem; }
.imp-profilo-tondo { position: relative; display: inline-block; line-height: 0; }
.imp-profilo-tondo .edit-logo { width: 26px; height: 26px; right: -4px; bottom: -4px; border-width: 2px; }
.imp-profilo-tondo .edit-logo svg { width: 12px; height: 12px; }
.imp-foto-azione { background: none; border: 0; padding: 0; color: var(--muted); font: inherit;
  font-size: .78rem; cursor: pointer; text-decoration: none; text-align: center; }
.imp-foto-azione:hover { color: var(--text); }
.imp-foto-azione.dis, .imp-foto-azione:disabled { opacity: .5; cursor: default; }
.imp-profilo-corpo { flex: 1; min-width: 240px; }
.imp-profilo-email { margin-top: .4rem; }


/* --- le plance (3/4): ciò che i pezzi non coprivano ancora ------------------------------- */
/* La ✕ di una carta richiudibile, nello slot azione della Sezione: un bottone nudo, tondo. */
.sez-x {
  border: 0; background: transparent; color: var(--muted); cursor: pointer; padding: 0;
  width: 26px; height: 26px; border-radius: 999px; font-size: .95rem; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}
.sez-x:hover { background: var(--riga-hover); color: var(--text); }
html[data-skin="obi"] .sez-x { color: var(--accent-on); }
html[data-skin="obi"] .sez-x:hover { background: rgba(255, 255, 255, .18); }
/* L'azione può portare due cose (un conteggio e la ✕): stanno in fila. */
.sezione-azione { display: inline-flex; align-items: center; gap: .5rem; }
/* Una carta di solo testo: i paragrafi si toccano senza lo style="margin:0" di ogni riga. */
.carta-testo p { margin: 0 0 .4rem; }
.carta-testo p:last-child { margin-bottom: 0; }
/* I bottoni in fondo a una carta di testo. */
.azioni-carta { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1rem; }
/* Lo stato vuoto dentro una carta che ha già un'intestazione: meno aria di quello di pagina. */
.vuoto.corto { padding: 1.5rem 1rem; }
/* Carte in pila, una sotto l'altra: lo spazio lo mette il contenitore, non un margine per carta. */
.pila { display: flex; flex-direction: column; gap: 1rem; }
.timbro-img { width: 36px; height: 36px; object-fit: contain; flex: 0 0 auto; }
.mb-lenti { margin-top: 1rem; flex-wrap: wrap; }
/* Una riga-avviso (certificato scaduto / in scadenza): la casella davanti prende il tono. */
.riga.err .riga-av { background: var(--err-bg); color: var(--err-text); }
.riga.warn .riga-av { background: var(--warn-bg); color: var(--warn-text); }
.riga-av svg { width: 18px; height: 18px; }

/* La lezione in home, come CardLezioneHome sull'app: blocco data in accento, pillola con
   data · ora, nome, luogo; sotto un filo, «Ci sarai?» a due bottoni pieni — non un chip. */
.ah-lezione { display: flex; flex-direction: column; gap: .7rem; align-items: stretch; }
.ah-lezione-testa { display: flex; gap: .9rem; align-items: flex-start; }
.data-blocco {
  flex: 0 0 auto; width: 58px; height: 58px; border-radius: 12px;
  background: var(--accent); color: var(--accent-on); font-weight: 700;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.data-blocco b { font-size: 1.4rem; line-height: 1; }
.data-blocco span { font-size: .66rem; letter-spacing: .08em; text-transform: uppercase; margin-top: 2px; }
.pillola {
  display: inline-block; background: var(--accent-tenue); color: var(--accent-text);
  border-radius: 999px; font-size: .8rem; padding: .1rem .6rem; font-weight: 600; margin-bottom: .25rem;
}
.ah-lezione .titolo { font-size: var(--t-valore); font-weight: 600; }
.ah-lezione .meta { color: var(--muted); font-size: var(--t-meta); }
.ah-rsvp-fila { border-top: 1px solid var(--border); padding-top: .7rem; }
.ah-rsvp-dom { color: var(--muted); font-size: .88rem; margin-bottom: .5rem; }
.ah-rsvp-fila .fila { display: flex; gap: .6rem; }
.ah-rsvp-fila .fila .bottone { flex: 1; text-align: center; }
.ah-tessera .data { opacity: .7; }
.ah-coda { margin-top: 1rem; }
/* Il percorso ingrandito: la larghezza dello zoom arriva come proprietà personalizzata. */
.perc-tela { width: var(--w, 100%); }


/* --- le schede (4/4): ciò che i pezzi non coprivano ancora ------------------------------- */
/* Il link «← Torna a…» in cima a una scheda. */
.torna { margin: 0 0 1rem; }
/* Un <input type=file> dietro un'etichetta-bottone. */
.nascosto { display: none; }
/* La nota tenue sotto i dati di una carta. */
.nota-sotto { margin-top: .6rem; }
/* Un testo che arriva già composto a righe (le conferme di `Conferme`). */
.pre-righe { white-space: pre-line; }
/* Una pastiglia accanto a un testo. */
.badge.accanto { margin-left: .4rem; vertical-align: middle; }
.riga-titolo .badge { margin-left: .4rem; vertical-align: middle; }
/* Le azioni in fondo a una pagina (annulla/elimina la lezione). */
.azioni-pagina { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; margin-top: 1.5rem; }
/* Un elenco di righe DENTRO una carta che ha altro sopra (la striscia della settimana): un
   riquadro col bordo, le righe corrono da bordo a bordo come in una carta piena. */
.lista-righe { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; margin-top: .6rem; }
/* Una riga spenta (iscrizione scaduta). */
.riga.spenta .riga-titolo, .riga.spenta .riga-meta { color: var(--muted); }
/* Le barrette di frequenza leggono la larghezza dalla proprietà personalizzata. */
.corso-bar > i, .isc-bar > i { width: var(--p, 0%); }
.riga .corso-bar { display: block; margin-top: .4rem; max-width: 240px; }
/* Scheda ente: la sezione «Dove». */
/* Richiesta di affiliazione: la riga del candidato e la testata. */
.ric-cand .ric-av.grande { width: 2.35rem; height: 2.35rem; font-size: .85rem; }
.ric-id .etichetta { margin-top: .3rem; }
.nz-ent-testa { margin-bottom: .5rem; }
/* Il timbro nel foglio di un grado o di un'iscrizione: la stessa impronta del glifo. */
.foglio .timbro-img { width: 40px; height: 40px; }


/* --- gli indici (5/5): la colonna stretta, l'ordine a pastiglie, la scheda accanto all'elenco -- */
.colonna-stretta { max-width: 640px; }
/* La fila dell'ordine respira sopra e SOTTO: appiccicata alla carta sembrava la sua intestazione (Fudo, 3 set). */
.filtro.ordina { margin: .4rem 0 .9rem; }
/* Soci sopra i 1100px: l'elenco a sinistra e, quando una riga è aperta, la sua scheda a destra —
   la scheda intera di /soci/{id} dentro il Foglio affiancato, che scorre per conto suo. Senza una
   riga aperta l'elenco prende tutta la colonna. */
.soci-split { display: grid; grid-template-columns: 400px minmax(0, 1fr); gap: 1.25rem; align-items: start; }
.soci-split.solo-lista { grid-template-columns: minmax(0, 1fr); }
.soci-split .foglio.affiancato { max-height: calc(100vh - 2rem); }
.foglio.affiancato .foglio-corpo { padding: .25rem 1.1rem 1.1rem; }
.foglio.affiancato .det-griglia { grid-template-columns: 1fr; }
.foglio.affiancato .det-intestazione h1 { font-size: 1.25rem; }
.foglio.affiancato .pagina-titolo, .foglio.affiancato h1 { font-size: 1.25rem; }
/* Chiusure: la nota sotto l'impatto. */
.impatto-nota { margin: .35rem 0 .6rem; }
/* Le mie affiliazioni: l'identità dell'ente e le preferenze in fondo alla carta. */
/* Le mie ratifiche: il bottone-etichetta della foto e «Ritira» in fondo alla riga. */
.azioni-richiesta .bottone { margin: 0; cursor: pointer; }
.azioni-richiesta .ritira { margin-left: auto; }
.azioni-carta.fine { justify-content: flex-end; align-items: center; }
.azioni-carta .spiega-ratifica { flex: 1; min-width: 14rem; }
/* Tutte le notifiche: la carta piena tiene un filo d'aria attorno alle righe della campana. */
.carta.piena.camp-carta { padding: .35rem; }
/* Un grado dichiarato: la riga porta l'esito e le azioni sotto la voce. */
.riga-dichiarato .riga-corpo { gap: .3rem; }
.riga-dichiarato .azioni-voce { margin-top: .3rem; }
/* Lo split dei soci è `display: grid` con la stessa specificità di .solo-largo, e sta più in basso
   nel foglio: sotto i 1100px vincerebbe lui. Qui la regola che lo spegne pesa di più. */
@media (max-width: 1099.98px) { .soci-split.solo-largo { display: none; } }


/* --- Maestri, Notizie, Cerca ente (6) --------------------------------------------------------- */
/* L'ultimo campo di una carta non lascia aria sotto di sé: nessuna pagina deve scriverlo. */
.carta > .campo:last-child { margin-bottom: 0; }
.cerca-filtro { margin-bottom: 1rem; }
.testa-corpo { flex: 1; min-width: 0; }
/* La coda di una riga con più cose in fila (pastiglie + timbro). */
.coda-fila { display: inline-flex; align-items: center; justify-content: flex-end; gap: .4rem; }
/* Il timbro predefinito del maestro in coda alla riga: l'immagine vera, o il 印 tenue «non impostato». */
.timbro-box {
  width: 40px; height: 40px; flex: 0 0 auto; border-radius: 8px; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-tenue); color: var(--accent-text); font-family: var(--jp); font-size: 1.2rem;
}
.timbro-box img { width: 100%; height: 100%; object-fit: contain; }
.timbro-box.vuoto { background: transparent; color: var(--muted); opacity: .3; }
/* I timbri dentro il foglio del maestro. */
.timbri { margin-top: 1rem; }
.timbri .sezione:first-child { margin-top: .5rem; }
.sezione-azione a.spento { opacity: .45; pointer-events: none; }
.tdef {
  display: inline-flex; align-items: center; gap: .35rem; font-size: .8rem; color: var(--muted);
  border: 0; background: transparent; padding: 0; cursor: default; font: inherit; font-size: .8rem;
}
button.tdef { cursor: pointer; }
button.tdef:hover { color: var(--text); }
.tdef .radio { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--border); display: inline-block; }
.tdef .radio.on { border-color: var(--accent); box-shadow: inset 0 0 0 3px var(--accent); }
.timbro-nuovo { margin-top: .8rem; padding: .9rem; border: 1px solid var(--border); border-radius: 10px; background: var(--page-tenue); }
.timbro-nuovo .risalto { margin-bottom: .5rem; }
.timbro-nuovo-corpo { display: flex; gap: .9rem; align-items: flex-start; }
.timbro-nuovo-campi { flex: 1; min-width: 0; }
.timbro-carica {
  width: 56px; height: 56px; flex: 0 0 auto; border-radius: 8px; overflow: hidden; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px dashed var(--border); color: var(--muted); font-family: var(--jp); font-size: 1.6rem;
}
.timbro-carica.piena { border-style: solid; background: var(--accent-tenue); color: var(--accent-text); }
.timbro-carica img { width: 100%; height: 100%; object-fit: contain; }
/* Il titolo di una notizia, più grande dentro la scatola del campo. */
.campo.nz-big .campo-box input { font-size: 1.15rem; font-weight: 600; }


/* --- i moduli (7) ------------------------------------------------------------------------- */
/* L'etichetta di un gruppo di spunte, e la riga d'aiuto subito sotto un'etichetta. */
.gruppo-spunte { margin-top: .6rem; }
.campo-aiuto.sotto-etichetta { margin: .1rem 0 .6rem; }
/* Il piede di un modulo: il conteggio a sinistra, i bottoni a destra. */
.piede-modulo { display: flex; align-items: center; gap: .75rem; justify-content: space-between; flex-wrap: wrap; margin-top: .6rem; }
/* L'anteprima del segno che si sta per conferire. */
.anteprima-segno { display: flex; align-items: center; gap: .6rem; margin: -.4rem 0 .9rem; }
.anteprima-segno .segno { width: 52px; }
/* Preferenze notifiche: le due colonne degli interruttori, sopra l'elenco e in coda a ogni riga. */
.pref-colonne { display: flex; align-items: center; gap: .35rem; padding: 0 16px .4rem; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.pref-col { width: 64px; flex: 0 0 64px; display: inline-flex; justify-content: center; text-align: center; }
.riga-coda .pref-col { justify-content: center; }
/* Impostazioni ente: il badge del logo, la riga «incolla e trova», la conferma dentro la lista. */
.mod-badge-logo { margin-top: .45rem; }
.ev-subhead.prima { border-top: none; padding-top: 0; margin-top: .2rem; }
.ev-paste .campo-box { flex: 1; }
.lista-righe .avviso.dentro-lista { margin: 0; border-radius: 0; }


/* --- la coda delle ratifiche, la bacheca e gli ultimi componenti (8) ------------------------ */
.chips.sopra { margin-bottom: 1rem; }
.seg.sopra { margin-bottom: .9rem; }
.vuoto .bottone.sotto { margin-top: 1rem; }
.carica-altri { display: flex; justify-content: center; margin: 1rem 0 .3rem; }
/* La testa di una richiesta (coda e storico): nome, disciplina, la data all'estrema destra. */
.testa-richiesta { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; }
.testa-richiesta .nome { font-size: var(--t-valore); }
.testa-richiesta .data { margin-left: auto; }
.carta .etichetta.messaggio { margin: .4rem 0 0; }
.etichetta.sotto { margin-top: .4rem; }
.allegati.sotto { margin-top: .4rem; }
.chip-fila { margin-top: .5rem; }
.carta.decisa { margin-bottom: .7rem; }
.richiesta-coda .lista-righe.voci { margin-top: .6rem; border-top: 1px solid var(--border); }
/* Il selettore del timbro: chip con la miniatura (o il glifo 印) e l'etichetta. */
.campo.ultimo { margin-bottom: 0; }
.timbri-scelta { display: flex; gap: .5rem; flex-wrap: wrap; }
.timbro-chip {
  display: flex; align-items: center; gap: .5rem; border: 1px solid var(--border); border-radius: 10px;
  padding: .4rem .6rem; cursor: pointer; background: var(--card); color: var(--text); font: inherit;
}
.timbro-chip.on { border-color: var(--accent); background: var(--accent-tenue); }
.timbro-chip:disabled { cursor: default; opacity: .6; }
.timbro-chip b { font-size: .85rem; font-weight: 600; }
.timbro-mini { width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; font-family: var(--jp); color: var(--accent-text); }
.timbro-mini img { width: 100%; height: 100%; object-fit: contain; }


/* --- eventi, check-in e media (9) ----------------------------------------------------------- */
/* Spaziature con un nome, al posto dei margini scritti in tasca. */
.spazio-sopra-s { margin-top: .3rem; }
.spazio-sopra-m { margin-top: .6rem; }
.spazio-sopra-l { margin-top: .8rem; }
.spazio-sopra-xl { margin-top: 1rem; }
.spazio-sotto { margin-bottom: 1rem; }
.senza-sopra { margin-top: 0; }
.avviso.solo-sopra { margin: .7rem 0 0; }
.avviso .nota { margin: .3rem 0 0; }
.avviso.sinistra { text-align: left; }
.campo.stretto { margin-bottom: .4rem; }
.campo.spunta-sotto { margin: .5rem 0 0; }
.bottone.largo { width: 100%; }
.bottone.carica, .ev-fld-edit.carica, .ev-addlink.carica { cursor: pointer; }
.bottone.quieto.pericolo { border-color: var(--warn); color: var(--warn-text); }
.risalto.titolo-s { font-size: 1.1rem; }
.risalto.titolo-m { font-size: 1.2rem; }
.risalto.titolo-l { font-size: 1.3rem; }
.carta.centrata { text-align: center; }
.seg.filtri { margin: .5rem 0; }
/* La testata dell'evento: sigillo, titolo, stato in coda. */
.ev-topbar { display: flex; align-items: center; gap: .7rem; margin-bottom: .75rem; }
.ev-topbar h1 { margin: 0; font-size: 1.25rem; }
.ev-topbar-coda { margin-left: auto; display: flex; align-items: center; gap: .6rem; }
.ev-sigillo { width: 36px; height: 36px; flex: 0 0 36px; border-radius: 9px; background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center; font-family: var(--jp); font-size: 1.25rem; }
.ev-intro-fila { display: flex; align-items: center; gap: .75rem; margin-bottom: 1rem; flex-wrap: wrap; }
.ev-h3 { margin: 0 0 .2rem; font-size: .95rem; }
.ev-corpo .ev-h3 { margin: .4rem 0; }
.etichetta.ev-nota { margin: 0 0 .8rem; }
.etichetta.ev-nota-s { margin: .2rem 0 .4rem; }
/* Le righe compatte di campi: relatori, sessioni, il walk-in. */
.ev-riga-modulo { display: flex; gap: .5rem; flex-wrap: wrap; align-items: flex-end; margin-bottom: .5rem; }
.ev-riga-modulo .campo { flex: 1; min-width: 120px; margin: 0; }
.ev-riga-modulo .campo.largo { flex: 2; min-width: 160px; }
.ev-riga-modulo .bottone { margin-bottom: 2px; }
.ev-sessione { border: 1px solid var(--border); border-radius: 8px; padding: .6rem; margin-bottom: .5rem; }
.ev-sessione .ev-riga-modulo:last-child { margin-bottom: 0; }
/* L'anteprima del modulo, il picker degli enti, l'attestato. */
.ev-prev-in { max-width: 260px; }
.ev-prev-num { width: 90px; }
.ev-picker { border-top: 1px solid var(--border); margin-top: .75rem; padding-top: .75rem; }
.ev-picker-risultati { max-height: 240px; overflow: auto; margin-bottom: .5rem; }
.ev-rolo.scelta { cursor: pointer; }
.ev-rolo-check { width: auto; margin-right: .5rem; }
.ev-locandina-img { max-width: 220px; max-height: 120px; border-radius: 8px; display: block; margin-bottom: .4rem; }
.ev-doc { display: flex; align-items: center; gap: .5rem; padding: .3rem 0; }
/* Il rotolo leggero del percorso (4 set, Percorso.razor): hero nell'inchiostro, selettore del
   verso, righe a tre colonne — anno, cintura, corpo. La cintura è la colonna di ogni riga, divisa
   in due metà (--sopra / --sotto) col pallino a cavallo: cambia colore sul pallino senza misurare.
   I colori arrivano come proprietà personalizzate: una tappa ha il colore del suo livello. */
.rl2 { max-width: 560px; }
.rl2-hero { position: relative; overflow: hidden; background: #2A2723; color: #fff; border-radius: 18px; padding: 16px 16px 14px; }
.rl2-hero-kj { position: absolute; right: -6px; top: -18px; font-family: var(--jp); font-size: 120px; line-height: 1; font-weight: 700; color: rgba(255,255,255,.07); pointer-events: none; }
.rl2-hero-top { display: flex; gap: 12px; align-items: center; position: relative; }
.rl2-hero-tok { flex: 0 0 auto; width: 54px; height: 54px; display: grid; place-items: center; }
.rl2-hero-tok .token-svg { width: 54px; height: 54px; }
.rl2-hero-g { font-size: 19px; font-weight: 600; }
.rl2-hero-m { font-size: 12px; color: #C9C2B3; margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rl2-stats { display: flex; gap: 6px; margin-top: 14px; position: relative; }
.rl2-stats div { flex: 1; background: rgba(255,255,255,.08); border-radius: 10px; padding: 8px 8px 7px; min-width: 0; }
.rl2-stats b { display: block; font-size: 17px; font-weight: 600; font-variant-numeric: tabular-nums; }
.rl2-stats span { font-size: 10.5px; color: #C9C2B3; letter-spacing: .03em; text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
.rl2-ordine { display: flex; gap: 4px; margin: 12px 0 0; background: var(--page-tenue); border-radius: 11px; padding: 3px; }
.rl2-ordine button { flex: 1; border: 0; background: none; font: inherit; font-size: 12.5px; padding: 6px 0; border-radius: 9px; color: var(--muted); cursor: pointer; }
.rl2-ordine button.on { background: var(--card); color: var(--text); font-weight: 600; box-shadow: 0 1px 2px rgba(0,0,0,.08); }
.rl2-rotolo { margin-top: 16px; }
.rl2-riga { display: grid; grid-template-columns: 34px 26px 1fr; column-gap: 6px; position: relative; }
.rl2-anno { font-size: 10.5px; color: var(--muted); text-align: right; padding-top: 9px; font-variant-numeric: tabular-nums; position: relative; }
/* la lineetta dell'inizio stagione, allineata alla barra delle presenze in fondo alla riga */
.rl2-riga.tacca-alto .rl2-anno:after, .rl2-riga.tacca-basso .rl2-anno:after { content: ""; position: absolute; right: 0; bottom: 8px; width: 22px; height: 2px; border-radius: 1px; background: var(--muted); }
.rl2-cint { position: relative; display: block; }
.rl2-cint:before, .rl2-cint:after { content: ""; position: absolute; left: 7px; width: 12px; }
.rl2-cint:before { top: 0; height: 50%; background: var(--sopra); }
.rl2-cint:after { top: 50%; height: 50%; background: var(--sotto); }
.rl2-riga.prima .rl2-cint:before { border-radius: 6px 6px 0 0; }
.rl2-nodo { position: absolute; left: 3px; top: 8px; width: 20px; height: 20px; border-radius: 50%; background: var(--nodo); border: 3px solid var(--page); box-shadow: 0 1px 4px rgba(0,0,0,.18); z-index: 1; }
/* il punto di un seminar a cavallo del bordo DESTRO della cintura: metà dentro, metà fuori */
.rl2-punto { position: absolute; left: 13px; top: 12px; width: 12px; height: 12px; border-radius: 50%; background: var(--blu); border: 2px solid var(--page); box-shadow: 0 1px 3px rgba(0,0,0,.2); z-index: 1; }
.rl2-corpo { padding: 7px 0 7px 6px; min-height: 40px; }
.rl2-riga + .rl2-riga .rl2-corpo { border-top: 1px solid rgba(35,32,28,.06); }
.rl2-staz { display: block; position: relative; color: inherit; text-decoration: none; padding-right: 38px; }
.rl2-staz.leggera { padding-right: 0; }
.rl2-r1 { display: flex; align-items: baseline; gap: 8px; }
.rl2-r1 b { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rl2-staz.leggera .rl2-r1 b { font-weight: 500; }
.rl2-data { margin-left: auto; font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.rl2-chi, .rl2-t { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rl2-chi { font-size: 11.5px; color: var(--muted); margin-top: 1px; }
.rl2-timbro { position: absolute; right: 0; top: 2px; width: 30px; height: 30px; object-fit: contain; }
.rl2-stag { font-size: 11.5px; color: var(--muted); }
.rl2-stag b { color: var(--text); font-weight: 600; }
.rl2-pct { margin-left: auto; font-weight: 600; color: var(--ok); }
.rl2-stag.media .rl2-pct { color: var(--arancio); }
.rl2-stag.scarsa .rl2-pct { color: var(--err); }
.rl2-barra { display: block; height: 5px; margin-top: 4px; }
.rl2-barra i { display: block; height: 100%; width: var(--w); border-radius: 3px; background: var(--ok); opacity: .65; }
.rl2-stag.media .rl2-barra i { background: var(--arancio); }
.rl2-stag.scarsa .rl2-barra i { background: var(--err); }
.rl2-sem { position: relative; padding-right: 60px; display: block; color: inherit; text-decoration: none; }
/* Il seminar attestato è un link (5 set): chevron in coda, i timbri si spostano di un passo. */
.rl2-sem.rl2-link { cursor: pointer; padding-right: 80px; }
.rl2-sem.rl2-link:hover .rl2-t { color: var(--accent-text); }
.rl2-sem .rl2-chev { position: absolute; right: 2px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 18px; line-height: 1; }
.rl2-sem.rl2-link .rl2-timbri { right: 20px; }
.rl2-t { font-size: 12.5px; font-weight: 500; }
.rl2-timbri { position: absolute; right: 0; top: 4px; display: flex; }
.rl2-timbri img { width: 28px; height: 28px; object-fit: contain; }
.rl2-timbri img + img { margin-left: -6px; }
.rl2-cta { display: block; text-align: center; margin-top: 14px; }

/* «Leggi (PDF)» di un consenso o di un documento (3 set): un link, nel tono d'accento. */
.ev-allegato { background: none; border: 0; padding: 0; color: var(--accent-text); font: inherit;
  font-size: .8rem; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.ev-annulla { margin-top: 1rem; border: 1px solid var(--border); border-radius: var(--raggio); padding: .75rem .9rem; display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
/* La scheda dell'evento lato praticante e l'attestato. */
.carta.ev-scheda { padding: 0; overflow: hidden; }
.ev-meta { padding: .6rem 1rem; }
.ev-corpo { padding: 0 1rem 1rem; }
.ev-blocco.azioni { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.ev-logo.timbro { font-size: 1.1rem; }
.ev-det-nome { margin: 0 0 .1rem; font-size: 1rem; }
.etichetta.ev-det-sub { margin-bottom: .6rem; }
/* Il check-in dal cartello (pagina anonima). */
.ck-web { max-width: 420px; margin: 2rem auto; padding: 0 1rem; }
.ck-web-testa { text-align: center; margin-bottom: 1.5rem; }
.ck-web-testa h1 { margin: 0; font-size: 1.3rem; }
.ck-web-logo { width: 76px; height: 76px; border-radius: 22px; object-fit: cover; margin: 0 auto .75rem; display: block; }
.ck-web-logo.iniziale { background: var(--accent-tenue); color: var(--accent-text); display: grid; place-items: center; font-size: 2rem; font-weight: 700; }
.ck-web-codice { text-align: center; font-family: monospace; font-size: 1.4rem; letter-spacing: .15em; text-transform: uppercase; }
.ck-web-lezione { margin-bottom: .5rem; text-align: left; }
.ck-web-ok { color: var(--ok); display: flex; justify-content: center; }
.ck-web-ok svg { width: 44px; height: 44px; }
/* Il cartello del check-in lato gestore. */
.ck-admin { display: flex; gap: 1.5rem; align-items: flex-start; flex-wrap: wrap; }
.ck-admin-corpo { flex: 1; min-width: 12rem; }
.ck-admin-codice { font-family: monospace; font-size: 1.8rem; letter-spacing: .15em; }
.ck-admin-url { font-family: monospace; word-break: break-all; }
.ck-admin-qr { text-align: center; flex: 0 0 auto; }
.ck-admin-qr-box { width: 170px; height: 170px; }
.ck-admin-lingua { margin: .35rem 0 .9rem; }
/* La coda dei media: elenco e dettaglio affiancati. */
.media-split { display: flex; gap: 1rem; flex-wrap: wrap; align-items: flex-start; }
.media-lista { flex: 1; min-width: 280px; }
.media-dettaglio { flex: 1.4; min-width: 300px; }
.carta.media-voce { cursor: pointer; margin-bottom: .5rem; }
.media-voce-fila { display: flex; gap: .6rem; align-items: center; }
.media-voce-corpo { flex: 1; min-width: 0; }
.media-anteprima { padding: 1rem; border-radius: 8px; text-align: center; margin-top: .3rem; }
.media-anteprima img { max-width: 100%; max-height: 320px; }
.media-requisiti { margin: .3rem 0 0; padding-left: 1.2rem; }
.media-rifiuto { margin-top: .6rem; border-top: 1px solid var(--border); padding-top: .6rem; }


/* --- piattaforma, accesso, e la baseline a zero (10) ---------------------------------------- */
.in-arrivo h2 { margin-top: 0; }
.in-arrivo .sottotitolo { margin-bottom: 0; }
/* Il pallino dell'accento nel menù delle preferenze: il colore arriva come --c. */
.accento-punti button { background: var(--c); color: var(--c); }
.iniziali.piccole { width: 28px; height: 28px; flex: 0 0 28px; font-size: .72rem; }
.com-dlg h3 { margin-top: 0; }
.com-dlg .avviso { margin: .6rem 0; }
.etichetta.citazione { font-style: italic; }
/* Le azioni di un dialogo: due bottoni che si dividono la larghezza. */
.azioni-dialogo { display: flex; gap: .6rem; margin-top: 1rem; }
.azioni-dialogo .bottone { flex: 1; }
.acc-testo { color: var(--text); line-height: 1.55; margin: .4rem 0 1.2rem; }
a.bottone.largo { display: block; text-align: center; text-decoration: none; }
.chips-badge { display: flex; gap: .4rem; flex-wrap: wrap; }
.testo.preformattato { white-space: pre-wrap; margin: 0; }
.modale .preformattato { white-space: pre-line; }
.modale .titolo-modale { margin: 0 0 .6rem; font-size: 1.05rem; }
.allegati.in-alto { align-items: flex-start; }
.spazio-sotto-l { margin-bottom: .8rem; }
.upf .grad .bar i { width: var(--p); }
.upf .rig .bb i { width: var(--p); }


/* =========================================================================================
   LA SECONDA MANO (11): il movimento è uno, e sta qui — non nelle pagine.
   Tre tempi (--t-corta il tocco, --t-media un ridisegno, --t-lunga un foglio), una curva.
   Tutto ciò che si clicca risponde allo stesso modo: la RIGA si tinge e la freccia avanza, la
   CARTA si stacca di due pixel col bordo d'accento, il BOTTONE si preme. Ciò che è un dato
   resta fermo: un numero che si alza e non porta da nessuna parte è una bugia.
   ========================================================================================= */

/* La testata del guscio: barra + schede, ferme insieme. La barra non è più sticky da sola. */
.shell-app .sa-testa { position: sticky; top: 0; z-index: 45; }
.shell-app .sa-barra { position: relative; z-index: auto; }

/* Le righe che si cliccano. */
.riga.cliccabile, .riga-persona.linkabile, .corso-and.linkabile, .faccenda, .ev-md-row, .sa-voce,
.dp-lz:not(.statica), .lvoce, .ctx, .com-ente-riga, .ev-loc, .sg-riga, .corsi-opt {
  transition: background var(--t-corta) var(--curva), color var(--t-corta) var(--curva),
              border-color var(--t-corta) var(--curva);
}
.riga.cliccabile:hover, .riga-persona.linkabile:hover, .corso-and.linkabile:hover, .faccenda:hover,
.ev-md-row:hover, .sa-voce:hover, .dp-lz:not(.statica):hover, .com-ente-riga:hover, .sg-riga:hover {
  background: var(--accent-tenue);
}
.riga-vai, .rp-vai, .faccenda .vai, .sa-voce .ch, .dp-vai, .gestione-chev, .sa-versione .ch {
  transition: transform 180ms var(--curva), color var(--t-corta) var(--curva);
}
.riga.cliccabile:hover .riga-vai, .riga-persona.linkabile:hover .rp-vai, .corso-and.linkabile:hover .rp-vai,
.faccenda:hover .vai, .sa-voce:hover .ch, .dp-lz:hover .dp-vai, .sa-versione:hover .ch {
  transform: translateX(4px); color: var(--accent-text);
}
.riga.cliccabile:hover .riga-titolo, .riga-persona.linkabile:hover .rp-nome, .faccenda:hover .corpo b,
.corso-and.linkabile:hover .corpo b { color: var(--accent-text); }

/* Le carte che si cliccano. */
a.carta, .carta.cliccabile, .cru-kpi a.carta, .ev-riga, .nz-fc.clic, .carta.media-voce, .tessera-link,
.sollevabile, .dop-lato, .oc-scelta, .aff-carta.apribile, .avvio-cta, .cerca-ente-card, .ente-card {
  transition: transform var(--t-corta) var(--curva), box-shadow var(--t-corta) var(--curva),
              border-color var(--t-corta) var(--curva), background var(--t-corta) var(--curva);
}
a.carta:hover, .carta.cliccabile:hover, .cru-kpi a.carta:hover, .ev-riga:hover, .nz-fc.clic:hover,
.carta.media-voce:hover, .tessera-link:hover, .sollevabile:hover, .dop-lato:hover, .oc-scelta:hover,
a.carta:active, .carta.cliccabile:active, .cru-kpi a.carta:active, .ev-riga:active, .nz-fc.clic:active,
.carta.media-voce:active, .tessera-link:active, .sollevabile:active, .dop-lato:active, .oc-scelta:active {
  transform: translateY(0); box-shadow: var(--ombra);
}

/* I bottoni si premono. */
.bottone { transition: transform var(--t-corta) var(--curva), filter var(--t-corta), background var(--t-corta),
                       border-color var(--t-corta), box-shadow var(--t-corta); }
.bottone:not(:disabled):active { transform: translateY(1px); }

/* Le schede della testata: l'attiva scivola, non scatta. */
.shell-app .sa-tab { transition: color var(--t-corta) var(--curva), border-color var(--t-corta) var(--curva), background var(--t-corta) var(--curva); }

/* Le righe di una carta piena entrano a scalare, dopo lo scheletro: sei tempi, poi insieme. */
.carta.piena > .riga, .lista-righe > .riga { animation: entra-su var(--t-media) var(--curva) backwards; }
.carta.piena > .riga:nth-child(1), .lista-righe > .riga:nth-child(1) { animation-delay: 0ms; }
.carta.piena > .riga:nth-child(2), .lista-righe > .riga:nth-child(2) { animation-delay: 30ms; }
.carta.piena > .riga:nth-child(3), .lista-righe > .riga:nth-child(3) { animation-delay: 60ms; }
.carta.piena > .riga:nth-child(4), .lista-righe > .riga:nth-child(4) { animation-delay: 90ms; }
.carta.piena > .riga:nth-child(5), .lista-righe > .riga:nth-child(5) { animation-delay: 120ms; }
.carta.piena > .riga:nth-child(n+6), .lista-righe > .riga:nth-child(n+6) { animation-delay: 150ms; }

/* Lo scheletro: la forma delle righe che stanno per arrivare. */
.scheletro { display: flex; flex-direction: column; }
.scheletro.in-carta { background: var(--card); border: 1px solid var(--border); border-radius: var(--raggio); box-shadow: var(--ombra); }
.sk-riga { display: flex; align-items: center; gap: .8rem; padding: .8rem 1rem; }
.sk-riga + .sk-riga { border-top: 1px solid var(--border); }
.sk-av { flex: 0 0 36px; width: 36px; height: 36px; border-radius: 50%; }
.sk-testo { flex: 1; display: flex; flex-direction: column; gap: .45rem; }
.sk-testo i { display: block; height: 11px; border-radius: 6px; }
.sk-l1 { width: 42%; } .sk-l2 { width: 68%; }
.sk-av, .sk-testo i {
  background: linear-gradient(90deg, var(--accent-tenue) 25%, var(--border) 50%, var(--accent-tenue) 75%);
  background-size: 200% 100%;
  animation: sk-luccica 1.2s linear infinite;
}
@keyframes sk-luccica { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* I numeri e gli anelli che arrivano (11): l'anello legge --v (0..100) e la transizione lo riempie. */
@property --v { syntax: "<number>"; inherits: false; initial-value: 0; }
.anello-vivo { transition: --v 1s var(--curva); }

/* Con «riduci movimento» resta tutto, senza animazione. */
@media (prefers-reduced-motion: reduce) {
  .carta.piena > .riga, .lista-righe > .riga, .sk-av, .sk-testo i { animation: none; }
  a.carta:hover, .carta.cliccabile:hover, .cru-kpi a.carta:hover, .ev-riga:hover, .nz-fc.clic:hover,
  .carta.media-voce:hover, .tessera-link:hover, .sollevabile:hover, .dop-lato:hover, .oc-scelta:hover,
  .riga.cliccabile:hover .riga-vai, .riga-persona.linkabile:hover .rp-vai, .faccenda:hover .vai,
  .sa-voce:hover .ch, .dp-lz:hover .dp-vai, .bottone:not(:disabled):active { transform: none; }
  .anello-vivo { transition: none; }
}

/* La COPPIA (Fudo, 3 set: «Dal e Al sulla stessa riga, a cosa serve tutto sto spazio?»): due o tre
   campi brevi e legati — un intervallo di date, ora d'inizio e di fine, CAP e provincia — stanno
   su una riga sopra i 700 px e si impilano sotto. «Un campo per riga» resta la regola per i campi
   lunghi; una coppia di date non lo è. */
.campi-coppia { display: grid; grid-template-columns: 1fr 1fr; gap: 0 .8rem; }
.campi-coppia.terna { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 700px) { .campi-coppia, .campi-coppia.terna { grid-template-columns: 1fr; } }
/* Dentro una riga compatta (relatori, sessioni) la coppia prende il posto dei suoi campi. */
.ev-riga-modulo > .campi-coppia { flex: 2 1 260px; }

/* Il RITMO fra le carte (Fudo, 3 set: «qua manca margine»): due carte in fila, o una carta dopo una
   sezione, respirano di un rem — senza che ogni pagina debba avvolgerle in una .pila. Vale per i
   figli diretti della pagina e delle colonne. `.ah-cols` (5 set, Fudo: «sistema questo margine»):
   le due colonne della home dell'allievo entrano nella lista, sennò l'avviso che le precede —
   ratifica respinta, domanda d'apertura — poggiava su «Prossima lezione» senza un filo d'aria. */
main.pagina > :is(.carta, .sezione-blocco, .avviso, .lista-righe, .scheletro, .striscia, .testata, .reg-miss, .det-griglia, .cru, .pila, .reg-actions, .toolbar, .ev-tabs, .ev-md, .ah-cols)
  + :is(.carta, .sezione-blocco, .avviso, .lista-righe, .scheletro, .striscia, .testata, .reg-miss, .det-griglia, .cru, .pila, .reg-actions, .ev-md, .ah-cols),
.det-col > :is(.carta, .sezione-blocco) + :is(.carta, .sezione-blocco),
.col > :is(.carta, .sezione-blocco) + :is(.carta, .sezione-blocco) { margin-top: 1rem; }
/* La barra strumenti a DUE righe: ricerca e primaria sopra, i filtri sotto a tutta larghezza. */
.toolbar.righe { display: grid; grid-template-columns: 1fr auto; gap: .6rem .8rem; align-items: center; }
.toolbar.righe .cerca { grid-column: 1; grid-row: 1; max-width: none; }
.toolbar.righe > .bottone { grid-column: 2; grid-row: 1; }
.toolbar.righe .filtro { grid-column: 1 / -1; grid-row: 2; margin-left: 0; }

/* Il titolo di pagina non poggia mai sulla prima carta (Fudo, 3 set): dove non c'è un sottotitolo a
   fare da cuscino, ci pensa questa regola. */
main.pagina > h1 + :is(.carta, .sezione-blocco, .lista-righe, .scheletro, .toolbar, .chips, .seg) { margin-top: .9rem; }


/* =========================================================================================
   LA SECONDA MANO (12): la testata è l'oggetto, la striscia è lo stato, il percorso è una linea.
   ========================================================================================= */
.testata {
  display: block; /* un blocco, e la riga dentro prende tutta la larghezza. La barra del rail, che si chiamava così ed è un flex, ora è .barra-rail: due cose diverse non portano lo stesso nome */
  margin-bottom: 1rem;
  position: relative; overflow: hidden; background: var(--card); border: 1px solid var(--border);
  border-radius: var(--raggio); box-shadow: var(--ombra); padding: 1.1rem 1.25rem;
}
.testata-filigrana {
  position: absolute; right: 1.2rem; top: -1.4rem; font-family: var(--jp); font-size: 9.5rem; line-height: 1;
  color: var(--accent); opacity: .06; pointer-events: none; user-select: none;
}
.testata-riga { position: relative; display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap; }
.testata-av { flex: 0 0 auto; }
.testata-av .det-foto { width: 64px; height: 64px; }
.testata-glifo {
  display: grid; place-items: center; width: 64px; height: 64px; border-radius: 18px;
  background: var(--accent-tenue); color: var(--accent-text); font-family: var(--jp); font-size: 1.9rem;
}
.testata-chi { flex: 1 1 260px; min-width: 0; }
.testata-titolo { margin: 0; font-size: var(--t-pagina); line-height: 1.15; }
.testata-sotto { margin-top: .3rem; display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; color: var(--muted); font-size: var(--t-valore); }
.testata-sotto .sep { opacity: .6; }
.testata-sotto .capitalizza { text-transform: capitalize; }
.testata-segno .token-svg { width: 40px; height: auto; display: block; }
.testata-codice { font-family: ui-monospace, Menlo, Consolas, monospace; letter-spacing: .12em; background: var(--accent-tenue); color: var(--text); padding: 0 .4rem; border-radius: 5px; }
.testata-pastiglie { margin-top: .45rem; display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; }
.testata-azioni { flex: 0 0 auto; margin-left: auto; display: flex; gap: .5rem; flex-wrap: wrap; align-self: flex-start; }
.testata-corpo { position: relative; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--border); }
@media (max-width: 700px) { .testata-azioni { margin-left: 0; width: 100%; } }

/* La striscia: da due a quattro celle, un pallino a colore, il fatto, l'unica azione. */
.striscia {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  margin-bottom: 1rem;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--raggio); box-shadow: var(--ombra);
  overflow: hidden; margin-top: 1rem;
}
.cella { display: flex; align-items: center; gap: .8rem; padding: .85rem 1rem; min-width: 0; position: relative; }
.cella + .cella { border-left: 1px solid var(--border); }
.cella-testo { display: flex; flex-direction: column; gap: .15rem; min-width: 0; flex: 1; }
.cella-et { font-size: var(--t-etichetta); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); font-weight: 600; display: flex; align-items: center; gap: .4rem; }
.cella-et::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--muted); flex: 0 0 auto; }
.cella.ok .cella-et::before { background: var(--ok); }
.cella.warn .cella-et::before { background: var(--warn); }
.cella.err .cella-et::before { background: var(--err); }
.cella-val { font-size: 1.15rem; font-weight: 600; line-height: 1.2; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.cella-val b { font-weight: 600; }
.cella-nota { font-size: var(--t-meta); color: var(--muted); }
.cella-azione { font-size: var(--t-meta); font-weight: 600; color: var(--accent-text); background: none; border: 0; padding: 0; cursor: pointer; text-align: left; font-family: inherit; margin-top: .15rem; text-decoration: none; }
.cella-azione:hover { text-decoration: underline; }
.cella-azione.muta { color: var(--muted); cursor: default; }
.cella-azione:disabled { color: var(--muted); cursor: default; }
.cella-anello {
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; position: relative;
  background: conic-gradient(var(--ok) calc(var(--v, 0) * 1%), var(--accent-tenue) 0);
}
.cella.warn .cella-anello { background: conic-gradient(var(--warn) calc(var(--v, 0) * 1%), var(--accent-tenue) 0); }
.cella.err .cella-anello { background: conic-gradient(var(--err) calc(var(--v, 0) * 1%), var(--accent-tenue) 0); }
.cella-anello::after { content: ""; position: absolute; inset: 5px; border-radius: 50%; background: var(--card); }
.cella-anello i { position: relative; z-index: 1; font-style: normal; font-size: .72rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.cru-striscia { margin-bottom: 1rem; }
@media (max-width: 700px) { .cella + .cella { border-left: 0; border-top: 1px solid var(--border); } }

/* Il percorso come linea: una tappa per grado, la cintura al posto dell'icona, il filo che scende. */
.carta.percorso { padding: .6rem .9rem; }
.percorso-linea { display: flex; flex-direction: column; }
.tappa {
  display: grid; grid-template-columns: 18px auto 1fr auto auto; align-items: center; gap: .8rem;
  padding: .7rem .4rem; border: 0; background: none; text-align: left; font: inherit; color: inherit;
  cursor: pointer; border-radius: 10px; position: relative;
  transition: background var(--t-corta) var(--curva);
}
.tappa:hover { background: var(--accent-tenue); }
.tappa:hover .riga-vai { transform: translateX(4px); color: var(--accent-text); }
.tappa:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.tappa-punto { width: 10px; height: 10px; border-radius: 50%; background: var(--accent); justify-self: center; position: relative; }
.tappa-punto::after { content: ""; position: absolute; left: 4px; top: 12px; width: 2px; height: 46px; background: var(--border); }
.tappa:last-child .tappa-punto::after { display: none; }
.tappa-segno .token-svg { width: 40px; height: auto; display: block; }
.tappa-corpo { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tappa-titolo { font-weight: 600; font-size: var(--t-valore); display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.tappa-titolo .badge { margin: 0; }
.tappa-meta { font-size: var(--t-meta); color: var(--muted); }

/* La griglia dei dati freddi (tessera, recapiti, certificato): etichetta sopra, valore sotto. */
.dati-griglia { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: .8rem 1.2rem; }
.dati-griglia .etichetta { margin-bottom: .1rem; }
.dati-griglia + .det-azioni { border-top: 1px solid var(--border); margin-top: .9rem; padding-top: .8rem; }
.mono-testo { font-family: ui-monospace, Menlo, Consolas, monospace; font-weight: 500; overflow-wrap: anywhere; }

/* Il foglio del grado: la cintura grande e la riga dello stato. */
.grado-testa { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.grado-segno .token-svg { width: 64px; height: auto; display: block; }
.stato-riga { flex: 1; display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; border: 1px solid var(--border); border-radius: 10px; padding: .55rem .8rem; font-size: var(--t-meta); background: var(--accent-tenue); }
.stato-riga.ok { background: var(--ok-bg); border-color: var(--ok); }
.stato-riga.ok b { color: var(--ok-text); }
.stato-riga.attesa { background: var(--warn-bg); border-color: var(--warn); }
.stato-riga.attesa b { color: var(--warn-text); }
.stato-riga .timbro-img { margin-left: auto; width: 30px; height: 30px; }
.foglio-piede .a-sinistra { margin-right: auto; }
/* Un foglio largo per i moduli lunghi (assegna grado). */
.foglio.sovrapposto.largo { width: 600px; }
/* Sotto gli 820px anche il foglio largo è il bottom sheet a tutta larghezza (3 set, sera, visto a
   700px: restava a 600px appoggiato a sinistra). */
@media (max-width: 820px) { .foglio.sovrapposto.largo { width: 100%; } }

/* Nel pannello accanto all'elenco la striscia ha due colonne: quattro celle in 420 px si spezzano male. */
.foglio.affiancato .striscia { grid-template-columns: 1fr 1fr; }
.foglio.affiancato .cella:nth-child(odd) { border-left: 0; }
.foglio.affiancato .cella:nth-child(n+3) { border-top: 1px solid var(--border); }
.foglio.affiancato .testata-azioni { margin-left: 0; width: 100%; }

.det-pila > .testata, .det-pila > .striscia, .pila > .testata, .pila > .striscia { margin-bottom: 0; }
.det-pila > .striscia { margin-top: 0; }


/* =========================================================================================
   LA SECONDA MANO (13): l'agenda, l'ordine a menù, le carte di servizio.
   ========================================================================================= */
/* L'agenda: il mese a sinistra, la giornata a destra. */
.cal-agenda { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(300px, 1fr); gap: 1rem; align-items: start; }
.cal-mese.carta { padding: .6rem .6rem .8rem; }
.cal-mese .cal-gh { background: transparent; border-bottom: 0; gap: 0; }
.cal-mese .cal-gh div { background: transparent; opacity: 1; padding: .4rem .5rem .6rem; text-align: center; }
.cal-mese .cal-gb { background: transparent; gap: 2px; grid-auto-rows: minmax(84px, auto); }
.cal-mese .cal-cell { border-radius: 12px; padding: .35rem .35rem .45rem; border-top: 1px solid var(--border); background: transparent; }
.cal-mese .cal-cell:nth-child(-n+7) { border-top: 0; }
.cal-mese .cal-cell:hover { background: var(--accent-tenue); }
.cal-mese .cal-cell.fuori { background: transparent; opacity: .45; }
.cal-mese .cal-cell.fuori:hover { background: var(--accent-tenue); }
.cal-mese .cal-cell.oggi { background: transparent; }
.cal-mese .cal-daynum { display: flex; justify-content: flex-start; margin-bottom: .25rem; }
.cal-mese .cal-daynum > span {
  display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  font-size: .78rem; font-weight: 600; color: var(--muted);
  transition: background var(--t-corta) var(--curva), color var(--t-corta) var(--curva);
}
.cal-mese .cal-cell.oggi .cal-daynum > span { background: var(--accent); color: var(--accent-on); }
.cal-mese .cal-cell.sel { box-shadow: inset 0 0 0 2px var(--accent); background: var(--accent-tenue); }
.cal-mese .cal-cell.sel .cal-daynum > span { color: var(--accent-text); }
.cal-mese .cal-cell.oggi.sel .cal-daynum > span { color: var(--accent-on); }
.cal-mese .cal-ev { border-radius: 6px; padding: .12rem .4rem; font-size: .68rem; margin-top: 2px; }
.cal-mese .cal-cell.chiusa { background: repeating-linear-gradient(45deg, transparent 0 6px, var(--cal-fuori, var(--page-tenue)) 6px 8px); }
.cal-mese .cal-leg { padding: .8rem .4rem 0; }
.cal-giorno { display: flex; flex-direction: column; gap: 1rem; position: sticky; top: 1rem; }
/* Sotto la testata ferma del guscio a schede parte più in basso; nel rail (produzione) non c'è testata. */
.shell-app .cal-giorno { top: calc(var(--sa-testa-h) + 1rem); }
.cal-giorno .dp-bar { flex-direction: column; align-items: stretch; gap: .8rem; margin: 0; }
.cal-giorno .dp-when { min-width: 0; }
.cal-giorno .dp-when .occhiello { font-size: var(--t-sezione); }
.cal-giorno .dp-when h3 { font-size: var(--t-titolo); }
.cal-giorno .dp-lessons { flex: none; flex-direction: column; align-items: stretch; gap: .5rem; }
.cal-giorno .dp-lz { width: 100%; }
.cal-giorno .dp-corpo b, .cal-giorno .dp-corpo .meta { white-space: normal; }
.cal-giorno-chip { display: flex; flex-direction: column; align-items: center; line-height: 1; }
.cal-giorno-chip b { font-size: 1rem; font-weight: 700; }
.cal-giorno-chip small { font-size: .62rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
@media (max-width: 1000px) { .cal-agenda { grid-template-columns: 1fr; } .cal-giorno { position: static; } }

/* L'ordine a menù, in coda ai filtri. */
.ordina-menu { position: relative; margin-left: auto; }
.ordina-btn {
  display: inline-flex; align-items: center; gap: .4rem; border: 1px solid var(--border); background: var(--card);
  color: var(--text); border-radius: 999px; padding: .3rem .8rem .3rem .6rem; font: inherit; font-size: .82rem; font-weight: 600; cursor: pointer;
  transition: border-color var(--t-corta), background var(--t-corta);
}
.ordina-btn:hover { border-color: var(--accent); background: var(--accent-tenue); }
.ordina-ico svg { width: 15px; height: 15px; display: block; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; }
.menu.menu-ordine { position: absolute; right: 0; top: calc(100% + .4rem); z-index: 50; min-width: 200px; }

/* Il pallino delle scelte dell'RSVP nel foglio. */
.foglio .scelte { display: flex; flex-direction: column; gap: .5rem; }

/* --- Il pannello di destra sotto la testata ferma (3 set, sera) ---------------------------------
   Due difetti con una radice sola, la testata sticky del guscio (barra + schede, z 45):
   1. il pannello affiancato stava a `top: 1rem` e, scorrendo, finiva SOTTO la testata: la sua
      cima — nome, striscia — sparivano. Ora `top` conta l'altezza della testata, misurata da
      tema.js in --sa-testa-h (100px di ripiego, che è quanto misura a schermo largo);
   2. `position: sticky` crea sempre un contesto d'impilamento: un foglio o una conferma aperti
      DENTRO il pannello (grado, assegna grado, rinnovi) restavano confinati sotto la testata, e la
      loro testa — titolo e ✕ — non si vedeva. Finché ospita un velo, il pannello sale sopra la
      testata: il velo la copre come fa per i fogli aperti da qualunque altra pagina. */
:root { --sa-testa-h: 100px; }
.shell-app .foglio.affiancato {
  top: calc(var(--sa-testa-h) + 1rem); max-height: calc(100vh - var(--sa-testa-h) - 2rem);
}
.foglio.affiancato:has(.foglio-velo, .modale-fondo) { z-index: 72; }

/* Impostazioni ente su due colonne (3 set, sera): sinistra «come si presenta» (copertina, identità,
   contatti, Salva), destra «come si comporta» (sede, traccia, a rischio, risposte, statistiche).
   La copertina resta 16:9 nella sua colonna — a tutta pagina sarebbe un manifesto. */
.imp-griglia { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem; align-items: start; }
.imp-griglia > .imp-col { display: grid; gap: 1rem; align-content: start; min-width: 0; }
.imp-griglia .imp-testata, .imp-griglia .scheda-ente { max-width: none; margin-bottom: 0; }
.imp-griglia .det-campi:not(:last-child) { margin-bottom: .9rem; }
@media (max-width: 999.98px) { .imp-griglia { grid-template-columns: 1fr; } }

/* La striscia sotto i 900px (3 set, sera, visto a 700px): quattro celle in auto-fit finivano 3+1,
   con la quarta sola su una riga e i divisori a caso. Due per riga, come nel pannello affiancato. */
@media (max-width: 899.98px) {
  .striscia { grid-template-columns: 1fr 1fr; }
  .cella + .cella { border-left: 0; }
  .cella:nth-child(even) { border-left: 1px solid var(--border); }
  .cella:nth-child(n+3) { border-top: 1px solid var(--border); }
}

/* --- Check-in in due carte (3 set, sera) --------------------------------------------------- */
.carta.ck-hero { display: flex; gap: 1.75rem; align-items: center; flex-wrap: wrap; }
.ck-qr { flex: 0 0 auto; width: 190px; height: 190px; }
.ck-qr svg { width: 100%; height: 100%; display: block; }
.ck-dati { flex: 1; min-width: 16rem; display: grid; gap: 1rem; }
.ck-voce { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
.ck-voce-testo { display: grid; gap: .2rem; min-width: 0; flex: 1; }
.ck-admin-codice { font-size: 2.2rem; line-height: 1.1; }
.ck-piede { padding-top: .25rem; }
.ck-cartello-fila { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin-top: .4rem; }

/* Il messaggio di chi chiede una ratifica, come citazione. */
.richiesta-coda .citazione {
  margin: .6rem 0 0; padding: .55rem .9rem; border-left: 3px solid var(--accent);
  background: var(--page-tenue); border-radius: 0 10px 10px 0; color: var(--text);
}

/* Una barra strumenti col solo «Nuovo»: lo spazio elastico lo manda a destra (3 set). */
.toolbar-spazio { flex: 1; }

/* Le due cose appiccicate delle pagine evento partono sotto la testata del guscio (3 set): il
   navigatore delle sezioni e il pannello di dettaglio delle registrazioni. */
.shell-app .ev-nav { top: calc(var(--sa-testa-h) + .5rem); }
.shell-app .ev-md-detail { top: calc(var(--sa-testa-h) + 1rem); }
.ev-md:has(.ev-md-detail[hidden]) { grid-template-columns: 1fr; }

/* Il giro dell'allievo (15): la copertina dell'ente in vetrina è un banner a tutta larghezza, non la
   card 16:9 delle impostazioni (che resta com'è, con logo e nome dentro). */
.scheda-ente.scheda-banner { max-width: none; }
.scheda-banner .scheda-cover { aspect-ratio: auto; height: 220px; }
/* La riga con la × di archivio in coda: il bottone non allarga la riga. */
.riga-coda .nz-ib { flex: 0 0 auto; }
/* Il kanji dentro una pastiglia respira dal nome («合 Aikido»). */
.badge .kanji { margin-right: .3em; }

/* --- SceltaGrado (3 set): il campo col segno del livello scelto, e le righe del foglio ------- */
.scelta-grado {
  width: 100%; min-height: 2.6rem; display: flex; align-items: center; gap: .7rem;
  padding: .35rem .8rem; border: 1px solid var(--border); border-radius: 10px;
  background: var(--card); color: var(--text); font: inherit; text-align: left; cursor: pointer;
  transition: border-color var(--t-corta) var(--curva), background var(--t-corta) var(--curva);
}
.scelta-grado:hover { border-color: var(--accent); }
.scelta-grado:disabled { opacity: .6; cursor: default; }
.scelta-grado.vuota .scelta-grado-nome { color: var(--muted); }
.scelta-grado-segno { flex: 0 0 auto; display: inline-flex; }
.scelta-grado-segno .token-svg { width: 30px; height: auto; display: block; }
.scelta-grado-nome { flex: 1; min-width: 0; font-weight: 500; }
.scelta-grado-chev { color: var(--muted); font-size: 1.1rem; line-height: 1; }
/* Un livello già conferito: si vede, non si sceglie. */
.riga.spenta { opacity: .45; }

/* --- TessereTipoEnte (3 set): il tipo dell'ente in due tessere che si spiegano da sé ------- */
.tipo-tessere { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; }
.tipo-tessera { display: grid; gap: .25rem; padding: .7rem .8rem; border: 1px solid var(--border); border-radius: 12px; background: var(--card-alta); }
.tipo-tessera.scelta { border-color: var(--accent); background: var(--accent-tenue); box-shadow: inset 0 0 0 1px var(--accent); }
.tipo-tessera.spenta { opacity: .5; }
.tipo-kanji { font-family: var(--jp); font-size: 1.15rem; line-height: 1; color: var(--accent-text); }
/* Le chiavi «dojo»/«organizzazione» nascono per stare dentro una frase: qui sono un titolo. */
.tipo-nome { font-weight: 600; font-size: .92rem; text-transform: capitalize; }
.tipo-tessera.scelta .tipo-nome::after { content: " ✓"; color: var(--accent-text); }
.tipo-spiega { font-size: .8rem; color: var(--muted); line-height: 1.4; }
.tipo-nota { margin-top: .25rem; }
@media (max-width: 560px) { .tipo-tessere { grid-template-columns: 1fr; } }

/* ===== conferma email (3 set) — la striscia col codice, sulle due home e nelle preferenze ===== */
.conferma-email { display: flex; flex-direction: column; gap: .6rem; }
.conferma-email .ce-testo { display: flex; flex-direction: column; gap: .15rem; line-height: 1.45; }
/* Il campo e i due bottoni sulla stessa linea: `.campo` porta un margine sotto per stare in un
   modulo, qui è in una riga e il margine lo spingeva più in alto dei bottoni. */
.conferma-email .ce-riga { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.conferma-email .ce-campo { flex: 0 1 11rem; margin-bottom: 0; }
.conferma-email .ce-esito { font-size: .85rem; }

/* ===== i timbri sulla riga del seminar (3 set): uno accanto all'altro, come il timbro sul grado ===== */
.timbri-riga { display: inline-flex; gap: .15rem; align-items: center; }

/* --- la demo (docs/Budopass_Demo.md, 4 set): il bottone sull'accesso, il catalogo (/demo), la
   fascia in cima al guscio. Il catalogo ricalca docs/mockups/demo_accesso.html: chip del paese e
   delle persone (col volto), voci con logo + due righe + interruttore, l'avviso, «Entra». --- */
.auth-oppure { display: flex; align-items: center; gap: .6rem; color: var(--muted); font-size: .78rem; margin: .9rem 0; }
.auth-oppure::before, .auth-oppure::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.auth-demo .bottone { width: 100%; }
.auth-demo-spiega { font-size: .78rem; color: var(--muted); text-align: center; margin: .5rem 0 0; line-height: 1.45; }
/* Il catalogo (seconda pagina) sta centrato in verticale come l'accesso quando ci sta (6 set, Fudo:
   «centriamo anche questo»), e parte dall'alto e scorre quando è più alto della finestra: il margine
   automatico centra finché c'è aria, e si azzera quando non ce n'è — così la testa non finisce mai
   sopra il bordo. */
.auth.demo.scegli .auth-formside { align-items: flex-start; overflow-y: auto; }
.auth.demo.scegli .auth-form { margin: auto 0; }
.auth.demo .auth-form { max-width: 480px; }
.auth.demo .auth-form > .bottone { width: 100%; }
.dm-chips { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 1rem; }
/* Dentro .auth --accent-text e' il bianco del bottone pieno: il chip acceso, su fondo tenue, vuole
   il rosso scuro del sito (come nel mockup), sennò il testo sparisce. */
.auth .chip.on { color: #8C2A20; font-weight: 600; }
.chip.persona { padding: .25rem .8rem .25rem .25rem; }
.chip.persona img { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; display: block; }
.dm-sez { margin: 0 0 .9rem; }
.dm-sez h3 { font-size: .7rem; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin: 0 0 .5rem; font-weight: 600; }
.dm-voce { display: flex; align-items: center; gap: .75rem; padding: .6rem .75rem; border: 1px solid var(--border); border-radius: 12px; background: var(--card); margin-bottom: .5rem; }
.dm-voce .iniziali { width: 36px; height: 36px; flex: 0 0 36px; border-radius: 9px; font-size: .8rem; }
.dm-voce .tx { flex: 1; min-width: 0; }
.dm-voce .tx b { display: block; font-size: .9rem; font-weight: 600; color: var(--text); }
.dm-voce .tx span { display: block; font-size: .76rem; color: var(--muted); margin-top: .1rem; }
.dm-sw { width: 40px; height: 22px; border-radius: 999px; background: var(--border); position: relative; flex: 0 0 40px; border: 0; padding: 0; cursor: pointer; }
.dm-sw::after { content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; transition: left .15s; }
.dm-sw.on { background: var(--accent); }
.dm-sw.on::after { left: 21px; }
.dm-avviso { background: var(--page-tenue); border-radius: 10px; padding: .6rem .75rem; font-size: .78rem; color: var(--text); line-height: 1.45; margin: .25rem 0 .9rem; }
.dm-avviso b { font-weight: 600; }
/* La fascia della demo (6 set): fra la barra e le schede, coi colori dell'app — il tenue dell'accento
   come fondo, il testo nell'accento, «Esci» pieno — ma la struttura di sempre: una riga sola, titolo e
   nota di seguito (la nota si tronca), i tocchi e «Esci» a destra. */
.shell-app .sa-demo { background: var(--accent-tenue); border-bottom: 1px solid var(--border); padding: .35rem 1rem; font-size: .8rem; color: var(--accent-text); }
.shell-app .sa-demo b { font-weight: 700; white-space: nowrap; }
.shell-app .sa-demo .sp { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: .9; }
.shell-app .sa-demo-esci { border: 1px solid var(--accent); background: var(--accent); color: var(--accent-on); border-radius: 999px; padding: .2rem .7rem; font: inherit; font-weight: 600; cursor: pointer; }

/* --- il marchio col LOGO non ha piastrella (5 set): un logo con l'esterno trasparente — un tondo,
   un triangolo — sta sul fondo della pagina, come farebbe su carta. La tinta accento resta a chi
   mostra le INIZIALI. Ogni tondo/quadrato che può ospitare un <img> passa di qui. --- */
.iniziali:has(img), .menu .mk:has(img), .shell-app .sa-emblema:has(img),
html[data-skin="sumi"] .shell-app .sa-emblema:has(img), .nz-ent .mk:has(img), .ah-tessera .mk:has(img) {
  background: transparent;
}

/* --- la fascia della demo: i tre tocchi (5 set) — solo icone, 30×30, il pollice scelto pieno --- */
.shell-app .sa-demo-ico {
  width: 30px; height: 30px; flex: none; border: 0; border-radius: 8px; padding: 0;
  background: transparent; color: var(--accent-text); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.shell-app .sa-demo-ico svg { width: 18px; height: 18px; }
.shell-app .sa-demo-ico:hover { background: rgba(255, 255, 255, .35); }
.shell-app .sa-demo-ico.on { background: var(--accent); color: var(--accent-on); }
.shell-app .sa-demo-nota { font-size: .74rem; white-space: nowrap; opacity: .85; }

/* --- le statistiche della demo (admin/statistiche): una tabellina per gruppo --- */
.st-demo-tab { width: 100%; border-collapse: collapse; font-size: .82rem; font-variant-numeric: tabular-nums; }
.st-demo-tab th, .st-demo-tab td { padding: .3rem .4rem; text-align: right; border-bottom: 1px solid var(--border); }
.st-demo-tab th:first-child, .st-demo-tab td:first-child { text-align: left; }
.st-demo-tab th { font-weight: 600; color: var(--muted); font-size: .72rem; letter-spacing: .04em; text-transform: uppercase; }
.st-demo-tab tr:last-child td { border-bottom: 0; }

/* --- il seminar concluso (5 set): galleria in testa, spunte sulle sessioni frequentate --- */
.ev-gal .sg-ph { border: 1px solid var(--border); padding: 0; cursor: pointer; }
.ev-gal .sg-ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ev-gal-vis { position: absolute; left: 6px; bottom: 6px; display: inline-flex; align-items: center; gap: .25rem; font-size: .66rem; font-weight: 600; padding: .15rem .45rem; border-radius: 999px; background: rgba(35,32,28,.72); color: #fff; }
.ev-gal-vis svg { width: 11px; height: 11px; }
.ev-sess.frequentata b { color: var(--accent-text); }
.ev-sess-ok { margin-left: auto; align-self: center; color: var(--ok); font-weight: 700; }
.sg-galt .p .ev-pill { margin-left: .4rem; }

/* --- il catalogo a spunte della demo (5 set): la riga dell'ente, sotto le due spunte --- */
.dm-ente { display: block; }
.dm-ente .dm-testa { display: flex; align-items: center; gap: .75rem; }
.dm-spunte { display: flex; flex-wrap: wrap; gap: .5rem; margin: .6rem 0 0 calc(36px + .75rem); }
.dm-chk { display: inline-flex; align-items: center; gap: .45rem; border: 1px solid var(--border); border-radius: 10px; padding: .35rem .7rem .35rem .5rem; font: inherit; font-size: .8rem; background: var(--card); color: var(--text); cursor: pointer; }
.dm-chk i { width: 18px; height: 18px; border-radius: 5px; border: 1.5px solid var(--border); display: inline-flex; align-items: center; justify-content: center; font-size: .7rem; font-style: normal; font-weight: 700; color: #fff; }
.dm-chk small { color: var(--muted); font-size: .74rem; }
.dm-chk.on { border-color: var(--accent); background: var(--accent-tenue); color: var(--accent-text); font-weight: 600; }
.auth .dm-chk.on { color: #8C2A20; }
.dm-chk.on i { background: var(--accent); border-color: var(--accent); }

/* «Mostra tutti ›» accanto alla porta della carta (5 set): un bottone che sembra il link accanto. */
.azione-testo { background: none; border: 0; padding: 0; margin-right: .9rem; font: inherit; color: var(--accent-text); font-weight: 600; cursor: pointer; }

/* --- l'ambito di disciplina (5 set): le linguette sopra l'elenco soci e la scheda, le pastiglie in riga --- */
.dm-chips.ambito { margin: 0 0 .75rem; }
.pastiglie { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .25rem; }
.pastiglia { font-size: .7rem; font-weight: 600; padding: .1rem .5rem; border-radius: 999px; background: var(--accent-tenue); color: var(--accent-text); }

/* La barra della frequenza nell'elenco soci (5 set): verde, ambra sotto i due terzi, rossa sotto un terzo. */
.soci-barra { max-width: 220px; }
.soci-barra.media i { background: var(--warn); }
.soci-barra.scarsa i { background: var(--err); }
/* Elenco soci (5 set): davanti la persona, e il segno del grado piccolo in testa alla riga del grado,
   come ritratto e token affiancati nella SocioCard dell'app. */
.soci-meta { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.soci-meta .rp-segno { display: block; line-height: 0; flex: 0 0 auto; }
.soci-meta .token-svg { width: 22px; height: auto; display: block; }
.soci-meta > span:last-child { min-width: 0; }
/* Il menù dei profili (5 set): il marchio di una GESTIONE porta un bollino con l'ingranaggio
   sull'angolo in alto a destra. Il marchio non taglia più (overflow), l'immagine resta tonda
   coi suoi angoli. */
.menu .mk { position: relative; overflow: visible; }
.menu .mk-badge {
  position: absolute; top: -5px; right: -5px; width: 15px; height: 15px; border-radius: 50%;
  background: var(--card); border: 1px solid var(--border); color: var(--accent-text);
  display: flex; align-items: center; justify-content: center; font-style: normal; line-height: 0;
}
.menu .mk-badge svg { width: 9px; height: 9px; }
/* Il tondo del cassetto su un ente (5 set): piastrella bianca col logo (o l'iniziale), angoli come
   il marchio in barra, e il bollino della gestione sull'angolo. */
.shell-app .sa-avatar.sa-ente {
  position: relative; border-radius: 10px; background: #fff; color: var(--accent);
  font-family: var(--jp); overflow: visible;
}
.shell-app .sa-ente img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block; }
.shell-app .sa-ente .mk-badge {
  position: absolute; top: -5px; right: -5px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--card); border: 1px solid var(--border); color: var(--accent-text);
  display: flex; align-items: center; justify-content: center; font-style: normal; line-height: 0;
}
.shell-app .sa-ente .mk-badge svg { width: 9px; height: 9px; }
/* Il bollino della gestione anche sul marchio in barra (5 set): il marchio non taglia più, così il
   bollino sporge dall'angolo; l'immagine tiene i suoi angoli. */
.shell-app .sa-emblema { overflow: visible; }
.shell-app .sa-emblema img { border-radius: inherit; }
.shell-app .sa-emblema .mk-badge {
  position: absolute; top: -5px; right: -5px; width: 15px; height: 15px; border-radius: 50%;
  background: var(--card); border: 1px solid var(--border); color: var(--accent-text);
  display: flex; align-items: center; justify-content: center; font-style: normal; line-height: 0; z-index: 1;
}
.shell-app .sa-emblema .mk-badge svg { width: 9px; height: 9px; }
/* Le carte d'AVVISO della home (5 set): lo sfondo nel colore di stato, come `Avviso(...)` sull'app —
   attesa (ambra) per ciò che preme, ok (verde) per una buona notizia, errore per il certificato
   scaduto. Gli stati non seguono l'accento (§7). */
.carta.avviso-attesa { background: var(--warn-bg); border-color: var(--warn); }
.carta.avviso-attesa .etichetta, .carta.avviso-attesa .carta-testo { color: var(--warn-text); }
.carta.avviso-ok { background: var(--ok-bg); border-color: var(--ok); }
.carta.avviso-ok .etichetta, .carta.avviso-ok .carta-testo { color: var(--ok-text); }
.carta.avviso-errore { background: var(--err-bg); border-color: var(--err); }
.carta.avviso-attesa .riga + .riga, .carta.avviso-errore .riga + .riga { border-top-color: transparent; }
/* Il bottone della demo sull'accesso (5 set): il bordo nell'accento come «Prova con dati
   dimostrativi» nell'app, e il bollino «Demo» sull'angolo in alto a destra in un colore SUO —
   il viola di --demo, che non è l'accento, non è un verde/ambra/rosso di stato e non è il blu
   del calendario: la demo si riconosce a colpo d'occhio e non si confonde con uno stato. */
/* Il testo nell'accento «pieno» (--accent), non in --accent-text: nella palette fissa dell'accesso
   --accent-text è il bianco DA METTERE SULL'accento, e il bottone sarebbe uscito bianco su bianco. */
.bottone.demo { background: transparent; color: var(--accent); border-color: var(--accent); position: relative; overflow: visible; }
.bottone.demo:hover { background: var(--accent-tenue); filter: none; box-shadow: none; }
.bollino-demo {
  position: absolute; top: -.55rem; right: -.4rem;
  background: var(--demo); color: var(--demo-on);
  font-size: .6rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; line-height: 1.3;
  padding: .18rem .5rem; border-radius: 999px; box-shadow: 0 2px 5px rgba(0, 0, 0, .18);
}
/* Le pastiglie delle discipline nella card dell'ente (5 set sera, una card per ente): la disciplina
   con cui c'è già un rapporto prende il tono del suo stato — verde affiliato, ambra in attesa,
   rosso sospeso/scaduto — e lo dice in coda («· Sei affiliato»). Le altre restano neutre. */
.tag.ok { background: var(--ok-bg); color: var(--ok-text); border-color: var(--ok); }
.tag.attesa { background: var(--warn-bg); color: var(--warn-text); border-color: var(--warn); }
.tag.errore { background: var(--err-bg); color: var(--err-text); border-color: var(--err); }
.tag .tag-stato { font-weight: 600; }
/* «Le mie affiliazioni» a card per ente (5 set sera, come l'app): testa con logo, nome-link e stato;
   una riga per disciplina — pastiglia, numero budopass, stato — e i due interruttori in fondo. La
   riga evidenziata è quella che la notifica di esito indica (?ev=). */
.aff-ente .testa-carta .badge { margin-left: auto; flex: 0 0 auto; }
.aff-nome { color: inherit; text-decoration: none; }
.aff-nome:hover { color: var(--accent-text); text-decoration: none; }
.aff-discipline { display: flex; flex-direction: column; gap: .4rem; margin-top: .8rem; }
.aff-disc {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: .45rem .6rem; border: 1px solid var(--border); border-radius: var(--raggio-s);
}
.aff-disc .tag { flex: 0 0 auto; }
.aff-disc .aff-meta { flex: 1; min-width: 0; }
.aff-disc .badge { margin: 0; flex: 0 0 auto; }
.aff-disc.evidenziata, .aff-rifiuto.evidenziata { background: var(--accent-tenue); border-color: var(--accent); }
.aff-rifiuto { margin-top: .6rem; padding: .6rem; border: 1px solid var(--err); background: var(--err-bg); border-radius: var(--raggio-s); }
.aff-rifiuto .aff-disc { border: 0; padding: 0; }
.aff-rifiuto .risalto { margin: .4rem 0 0; }
.aff-rifiuto .azioni-carta { margin-top: .5rem; }
.aff-interruttori { border-top: 1px solid var(--border); padding-top: .8rem; }
/* Il toast della demo (5 set sera): nel viola di --demo, lo stesso del bollino sul bottone d'ingresso. */
.avviso-toast.demo { background: var(--demo); color: var(--demo-on); border-color: var(--demo); }
.avviso-toast.demo .avviso-ico { background: rgba(255, 255, 255, .28); color: var(--demo-on); }
.avviso-toast.demo .avviso-x { color: var(--demo-on); }
/* L'icona della galleria nella riga di un seminar fatto (5 set sera): il riquadro-foto e il numero,
   tenui — dicono «c'è da vedere», l'azione è la riga. */
.foto-galleria { display: inline-flex; align-items: center; gap: .2rem; color: var(--muted); font-size: .78rem; }
.foto-galleria svg { width: 16px; height: 16px; }

/* La nota «volti e foto generati con l'AI» sotto il sottotitolo del catalogo demo (5 set sera). */
/* La nota «immagini generate» in evidenza (6 set): un riquadro nel viola della demo col bollino «AI». */
.auth.demo .demo-nota-ai { display: flex; align-items: center; gap: .6rem; margin: -.3rem 0 1rem; font-size: .8rem; line-height: 1.35;
  color: var(--text); background: color-mix(in srgb, var(--demo) 9%, transparent); border: 1px solid color-mix(in srgb, var(--demo) 30%, transparent);
  border-radius: 10px; padding: .5rem .7rem; }
.auth.demo .demo-nota-ai .bollino-demo.ai { position: static; flex: 0 0 auto; }
/* La spunta del pilota prima di entrare (6 set). */
.auth.demo .dm-spunta { margin: 0 0 .9rem; font-weight: 500; }
/* La tegola «＋» in coda alla galleria del seminar (5 set sera): vuota, bordo tratteggiato, il più al
   centro; all'hover prende l'accento. È la porta per aggiungere una foto, solo per chi ha partecipato. */
.sg-ph.sg-ph-aggiungi {
  display: flex; align-items: center; justify-content: center; text-decoration: none;
  border: 1.5px dashed var(--border); background: transparent; color: var(--muted); font-size: 2rem; line-height: 1;
}
.sg-ph.sg-ph-aggiungi:hover { border-color: var(--accent); color: var(--accent-text); background: var(--accent-tenue); }
/* Le voci del pannello del giorno nel calendario (5 set sera, Fudo: «sistema questi allineamenti»):
   il corpo prende tutto lo spazio, così la pastiglia «Seminar» e il chevron stanno a destra come nelle
   lezioni, invece di appoggiarsi al titolo. */
.cal-giorno .dp-lz .dp-corpo { flex: 1 1 auto; }
/* La fila dei loghi di un seminar SOTTO il testo (5 set sera): piccoli, leggermente sovrapposti,
   col bordo della carta a staccarli. Ovunque un seminar compare in riga. */
.loghi-fila { display: flex; align-items: center; margin-top: .3rem; }
.logo-ev.mini { width: 22px; height: 22px; border-radius: 6px; font-size: .55rem; border-width: 1.5px; background: var(--card); }
.logo-ev.mini.ini { background: var(--accent-tenue); }
.logo-ev.mini + .logo-ev.mini { margin-left: -3px; }
/* La foto del maestro nel foglio (5 set sera): il tondo che si tocca per scegliere il file, le
   iniziali finché non c'è, e «Rimuovi» accanto quando c'è. */
/* Tondo e «Rimuovi» sulla stessa linea di mezzo, con un'aria giusta fra loro (5 set sera, Fudo:
   «controlla allineamento e spaziatura Rimuovi»); l'errore va a capo sotto. */
.foto-maestro-riga { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.foto-maestro-riga .campo-errore { flex-basis: 100%; }
.timbro-carica.foto { border-radius: 50%; font-family: var(--sans); font-size: .95rem; font-weight: 600; background: var(--accent-tenue); color: var(--accent-text); }
.timbro-carica.foto img { width: 100%; height: 100%; object-fit: cover; }
/* Le azioni della testata (5 set sera, Fudo: «badge non allineato»): pastiglia e bottone sulla stessa
   linea di mezzo — il badge aveva il suo margine sotto, pensato per stare in fila coi fratelli. */
.testata-azioni { align-items: center; }
.testata-azioni .badge { margin: 0; }
/* La biografia del maestro nella scheda pubblica dell'ente (5 set sera): sotto nome e grado, nel tono
   del testo, a righe corte; il ritratto tondo nella casella davanti. */
.maestro-bio { margin: .35rem 0 0; font-size: .86rem; line-height: 1.45; color: var(--text); white-space: pre-line; }
.maestro-bio-apri { background: none; border: 0; padding: 0; margin-top: .25rem; font: inherit; font-size: .82rem; cursor: pointer; text-align: left; }
.riga-titolo .badge { margin-left: .4rem; vertical-align: middle; }
/* La matita sul tondo della foto del maestro nel foglio (5 set sera, Fudo: «aggiungi matita per
   upload photo, MAUI già c'è»): il bollino nell'accento sull'angolo in basso a destra. */
.timbro-carica.foto { position: relative; overflow: visible; }
.timbro-carica.foto .foto-matita {
  position: absolute; right: -4px; bottom: -4px; width: 20px; height: 20px; border-radius: 50%;
  background: var(--accent); color: var(--accent-on); border: 2px solid var(--card);
  display: flex; align-items: center; justify-content: center;
}
.timbro-carica.foto .foto-matita svg { width: 11px; height: 11px; }
/* La sagoma al posto delle iniziali per il maestro senza foto (5 set sera): nel tondo del foglio,
   nella casella della riga in lista e nella scheda dell'ente. */
.sagoma { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; color: var(--accent-text); }
.sagoma svg { width: 22px; height: 22px; }
.timbro-carica.foto .sagoma svg { width: 26px; height: 26px; }
/* «Rimuovi» nella coda della riga del timbro (6 set, Fudo: «rimuovi ancora disallineato»): il
   margine sopra di .link-rimuovi serve dove sta sotto una foto, non in fila col radio; qui si azzera
   e i due stanno sulla stessa linea di mezzo. */
.riga-coda .link-rimuovi { margin: 0; line-height: 1.2; align-self: center; }
.riga-coda .tdef { line-height: 1.2; }
/* La tessera sul budopass di un dojo (6 set, Fudo: «la pagina budopass in un profilo mostra la
   foto ma non permette la modifica; mancano badge stato e dati del budopass, vedi app»): la
   stessa carta di BudopassPage — logo, ente e stato in testa; sotto la foto della tessera con la
   matita, il numero, «Iscritto dal» e «Scadenza». */
.mb-tessera { padding: 0; }
.mb-tess-testa { display: flex; align-items: center; gap: .7rem; padding: .85rem 1rem; border-bottom: 1px solid var(--border); }
.mb-tess-testa .en { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.mb-tess-testa .en b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mb-tess-testa .en small { color: var(--muted); font-size: .8rem; }
.mb-tess-corpo { display: flex; align-items: center; gap: 1rem; padding: 1rem; }
.mb-tess-foto { position: relative; width: 64px; height: 83px; flex: 0 0 auto; border-radius: 10px; overflow: visible; cursor: pointer;
  background: var(--accent-tenue); color: var(--accent-text); display: flex; align-items: center; justify-content: center; font-weight: 600; }
.mb-tess-foto img { width: 100%; height: 100%; object-fit: cover; border-radius: 10px; }
.mb-tess-foto .foto-matita { position: absolute; right: -5px; bottom: -5px; width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent); color: var(--accent-on); border: 2px solid var(--card); display: flex; align-items: center; justify-content: center; }
.mb-tess-foto .foto-matita svg { width: 12px; height: 12px; }
.mb-tess-dati { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .35rem; }
.mb-tess-dati .num { font-weight: 600; }
.mb-tess-dati .riga { display: flex; justify-content: space-between; gap: .8rem; font-size: .9rem; }
.mb-tess-dati .riga span:first-child { color: var(--muted); }
.mb-tess-dati .riga b { font-weight: 600; font-variant-numeric: tabular-nums; }
.mb-tess-azioni { padding: 0 1rem .85rem; display: flex; gap: .6rem; align-items: center; }
/* La prima pagina della demo (6 set): la porta verso l'app coi bottoni degli store della landing —
   stessa forma (index.html .store), TestFlight e Google Play in test aperto col badge verde. */
.auth.demo .dm-app { border: 1px solid var(--border); border-radius: 12px; padding: .8rem .9rem; background: var(--card); margin: 0 0 1rem; }
.auth.demo .dm-app > b { display: block; font-size: .92rem; font-weight: 700; margin-bottom: .15rem; color: var(--text) !important; opacity: 1 !important; }
.auth.demo .dm-app p { margin: 0 0 .7rem; font-size: .8rem; color: var(--muted); line-height: 1.4; }
.auth.demo .dm-stores { display: flex; gap: 10px; flex-wrap: wrap; }
.auth.demo .dm-store { position: relative; display: inline-flex; align-items: center; gap: 10px; background: #23201C; color: #fff; padding: 9px 14px; border-radius: 11px; font-size: 11px; text-decoration: none; line-height: 1.1; }
.auth.demo .dm-store b { font-size: 14px; font-weight: 600; display: block; line-height: 1.15; }
.auth.demo .dm-store .si { width: 20px; height: 20px; flex: none; display: block; }
.auth.demo .dm-store .soon { position: absolute; top: -9px; right: -7px; background: var(--ok); color: #fff; font-size: 8.5px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase; padding: 2px 7px; border-radius: 20px; box-shadow: 0 2px 5px rgba(0,0,0,.22); }
.auth.demo .dm-torna { margin: 0 0 .6rem; }
/* La riga «la demo arriva anche nell'app» (6 set), al posto dei bottoni finché le app non ci sono. */
.auth.demo .dm-presto { display: flex; gap: .55rem; align-items: flex-start; border: 1px dashed var(--border); border-radius: 10px; padding: .55rem .75rem; margin: 0 0 1rem; font-size: .78rem; color: var(--muted); line-height: 1.4; }
.auth.demo .dm-presto svg { width: 16px; height: 16px; flex: none; margin-top: 1px; }

/* La carta «Prova la demo» in home (6 set): testo e bottone, la ✕ nell'azione come le altre. */
.carta.sugg-demo p { margin: 0 0 .8rem; color: var(--muted); font-size: .9rem; line-height: 1.45; }
.carta.sugg-demo .bottone { display: inline-flex; }

/* I corsi con gli orari nella scheda pubblica dell'ente (6 set): un titolo per disciplina col kanji,
   una riga per corso — nome, maestro, gli orari come pastiglie — e la nota in fondo. */
.scheda-corsi .sc-disc { display: flex; align-items: center; gap: .5rem; font-weight: 700; font-size: .92rem; margin: .6rem 0 .2rem; }
.scheda-corsi .sc-disc:first-child { margin-top: 0; }
.scheda-corsi .sc-kanji { width: 24px; height: 24px; border-radius: 7px; background: var(--accent); color: var(--accent-on); display: inline-flex; align-items: center; justify-content: center; font-family: var(--jp); font-size: .8rem; }
.scheda-corsi .sc-corso { padding: .55rem 0; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: .15rem; }
.scheda-corsi .sc-disc + .sc-corso, .scheda-corsi .sc-corso:first-child { border-top: none; }
.scheda-corsi .sc-corso > b { font-weight: 600; font-size: .92rem; }
.scheda-corsi .sc-maestro { font-size: .78rem; color: var(--muted); }
.scheda-corsi .sc-orari { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .25rem; }
.scheda-corsi .sc-ora { border: 1px solid var(--border); background: var(--card); border-radius: 8px; padding: .15rem .5rem; font-size: .78rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.scheda-corsi .sc-ora b { font-weight: 700; margin-right: .3rem; }
.scheda-corsi .sc-nota { margin: .7rem 0 0; padding-top: .55rem; border-top: 1px dashed var(--border); font-size: .78rem; color: var(--muted); line-height: 1.4; }

/* Il visore della galleria del seminar (6 set): velo scuro sopra tutto, la foto intera al centro,
   ‹ › ai lati, ✕ in alto a destra, la nota con la visibilità e il contatore sotto la foto. */
.lightbox { position: fixed; inset: 0; z-index: 80; background: rgba(12, 11, 10, .94); display: grid; place-items: center; padding: 1rem; outline: none; }
.lightbox .lb-corpo { display: flex; flex-direction: column; align-items: center; gap: .6rem; max-width: min(96vw, 1200px); }
.lightbox .lb-corpo img { max-width: 96vw; max-height: 82vh; object-fit: contain; border-radius: 8px; display: block; box-shadow: 0 10px 40px rgba(0,0,0,.5); }
.lightbox .lb-corpo img.lb-mini { filter: blur(2px); }
.lightbox .lb-nota { color: rgba(255,255,255,.85); font-size: .82rem; display: flex; gap: 1rem; align-items: center; }
.lightbox .lb-conta { font-variant-numeric: tabular-nums; opacity: .7; }
.lightbox .lb-x, .lightbox .lb-nav { position: absolute; border: 0; cursor: pointer; color: #fff; background: rgba(255,255,255,.14); border-radius: 50%; display: grid; place-items: center; line-height: 1; }
.lightbox .lb-x { top: 1rem; right: 1rem; width: 40px; height: 40px; font-size: 1.1rem; }
.lightbox .lb-nav { top: 50%; transform: translateY(-50%); width: 48px; height: 48px; font-size: 2rem; padding-bottom: 4px; }
.lightbox .lb-nav.prec { left: 1rem; } .lightbox .lb-nav.succ { right: 1rem; }
.lightbox .lb-x:hover, .lightbox .lb-nav:hover { background: rgba(255,255,255,.28); }
@media (max-width: 640px) { .lightbox .lb-nav { width: 40px; height: 40px; font-size: 1.6rem; } .lightbox .lb-nav.prec { left: .4rem; } .lightbox .lb-nav.succ { right: .4rem; } }

/* Un consenso obbligatorio non accettato alla conferma (6 set): la spunta nel tono d'errore. */
.in-errore .spunta { color: var(--err-text); }
.in-errore .spunta-box { border-color: var(--err); box-shadow: 0 0 0 2px color-mix(in srgb, var(--err) 25%, transparent); }

/* Il congedo della demo (6 set): la domanda, i tre tocchi in fila, l'uscita come link sotto. */
.modale.dm-congedo { text-align: center; }
.modale.dm-congedo h2 { margin: 0 0 .35rem; font-size: 1.1rem; }
.modale.dm-congedo p { margin: 0 0 1rem; color: var(--muted); font-size: .9rem; }
.dm-congedo-azioni { display: flex; gap: .5rem; justify-content: center; flex-wrap: wrap; }
.dm-congedo-azioni .bottone { display: inline-flex; align-items: center; gap: .4rem; }
.dm-congedo-azioni svg { width: 18px; height: 18px; }
.dm-congedo-nota { margin: .6rem 0 0 !important; font-size: .8rem; }
.dm-congedo-esci { display: block; margin: 1rem auto 0; background: none; border: 0; color: var(--muted); font: inherit; font-size: .85rem; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }

/* Il commento della demo (6 set): il modale dall'icona della fascia, e la riga nel congedo. */
.modale.dm-commento textarea, .dm-congedo-commento {
  width: 100%; box-sizing: border-box; resize: vertical; font: inherit; line-height: 1.45;
  padding: .55rem .7rem; border: 1px solid var(--border); border-radius: 10px;
  background: var(--card); color: var(--text);
}
.modale.dm-commento textarea { min-height: 7rem; }
.modale.dm-commento .dm-commento-nota { margin: 0 0 .8rem; color: var(--muted); font-size: .85rem; }
.dm-commento-azioni { display: flex; gap: .5rem; align-items: center; margin-top: .8rem; }
.dm-commento-spazio { flex: 1; }
.dm-congedo-commento { min-height: 4.2rem; margin-top: 1rem; text-align: left; font-size: .9rem; }

/* Piattaforma › Demo: i commenti per esteso, a tutta larghezza sotto le tabelline. */
.st-demo-commenti { grid-column: 1 / -1; }
.st-cm { padding: .6rem 0; border-top: 1px solid var(--border); }
.st-cm:first-of-type { border-top: 0; }
.st-cm-testa { display: flex; gap: .6rem; align-items: baseline; font-size: .78rem; color: var(--muted); margin-bottom: .2rem; }
.st-cm-testa b { color: var(--text); font-size: .85rem; }
.st-cm-quando { margin-left: auto; }
.st-cm-testo { white-space: pre-wrap; font-size: .9rem; line-height: 1.45; }

/* L'avviso «in fase di studio» in cima all'evento (6 set): l'ambra degli avvisi, il testo in grassetto
   e sotto l'invito al commento come link, nello stesso colore. */
.avviso.ambra.ev-studio { display: flex; flex-direction: column; gap: .3rem; align-items: flex-start; }
.ev-studio-commento { background: none; border: 0; padding: 0; font: inherit; font-weight: 600; color: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }

/* La registrazione in evidenza sull'accesso (6 set, proposta B): carta tenue, la domanda a sinistra
   che può andare a capo, il bottone pieno a destra che non si stringe mai. Tutta la carta è il link. */
.auth-registra {
  display: flex; align-items: center; gap: .8rem; margin-top: 1rem; padding: .8rem .9rem;
  background: var(--page-tenue); border: 1px solid var(--border); border-radius: var(--raggio);
  color: var(--text); text-decoration: none;
}
.auth-registra:hover { border-color: var(--muted); text-decoration: none; }
.auth-registra-testo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
.auth-registra-testo b { font-size: .95rem; font-weight: 600; line-height: 1.3; }
.auth-registra-testo span { font-size: .78rem; color: var(--muted); }
/* `.auth .bottone.accento` dà larghezza piena a «Entra»: qui il bottone è la pastiglia a destra. */
.auth .auth-registra .bottone.accento { width: auto; flex: none; white-space: nowrap; margin: 0; }
.auth .auth-registra .bottone.compatto { padding: .45rem .9rem; font-size: .85rem; }

/* La riga del grado nel percorso della home apre il percorso come la linea (6 set). */
.perc-testa.tocca { cursor: pointer; border-radius: 10px; }
.perc-testa.tocca:hover { background: var(--riga-hover); }
