/* 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;
  --err:#A63125;  --err-bg:#F6E4E1;  --err-text:#7A231B;

  /* 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: 620ms;
  --curva: cubic-bezier(.22,.68,.28,1);   /* esce svelta, si posa piano */

  /* 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;
  --err:#E0776B;  --err-bg:#4A2723;  --err-text:#F0A99F;

  --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;
    --err:#E0776B; --err-bg:#4A2723; --err-text:#F0A99F;
    --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, .gestione-tile:hover, .ev-riga:hover, .link-indietro:hover { text-decoration: none; }

/* --- struttura ---------------------------------------------------------- */

.guscio { display: flex; min-height: 100vh; }

/* Rail chiaro su washi al posto della sidebar inchiostro (§3.1), alto quanto la FINESTRA e fermo
   mentre la pagina scorre (rilievo del 24 ago).
   Prima era un semplice flex item di `.guscio` e si stirava all'altezza del CONTENUTO: quindi ciò
   che `margin-top: auto` spinge in basso — le sezioni di coda e il `.piede-laterale` con email e
   versione — finiva in fondo al DOCUMENTO, non della finestra. Su una pagina corta sembrava giusto;
   sul cruscotto pieno sprofondava sotto la piega, ed era il «di colpo cambia» appena loggati.
   `align-self: flex-start` è la riga che morde: senza, lo stretch del flex item vince sull'altezza
   e i 100vh non contano niente.
   `position: sticky` assorbe il vecchio `position: relative` — è anch'esso un valore posizionato,
   quindi il box della filigrana qui sotto continua ad ancorarsi all'aside, ora in fondo alla
   finestra. Nessun `overflow` qui: il menù dello switcher scende DENTRO la barra e verrebbe
   tagliato (vedi il commento di .rail-wm-box) — a scorrere è la sola .nav.

   E `z-index: 45`, che non è un ritocco: `sticky`, come `fixed`, crea SEMPRE un contesto
   d'impilamento, qualunque sia lo z-index. Da quando il rail è sticky, tutto ciò che sta dentro
   — menù dello switcher compreso, col suo z-index 50 — si dipinge come un solo strato al valore
   dell'aside; con `auto` quello strato finiva SOTTO il `.menu-backdrop` (fixed, 40), il fondale
   invisibile che chiude i menù. Il menù restava visibile (il fondale è trasparente) ma ogni clic
   su un profilo atterrava sul fondale, che chiamava Chiudi(): lo switcher sembrava vivo e non
   commutava niente. Un caso diverso dalla trappola dell'`overflow` di cui sopra — quella
   taglierebbe il menù, questa gli rubava i clic. 45 tiene il rail sopra il fondale e sotto i menù
   della testata (.menu-pref / .menu-utente, 50), che scendono da là e devono restare in cima. */
.barra-laterale {
  width: 236px;
  flex: 0 0 236px;
  background: var(--rail);
  border-right: 1px solid var(--rail-border);
  color: var(--text);
  padding: 1.25rem 0;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  align-self: flex-start;
  z-index: 45;   /* sopra il .menu-backdrop (40), sotto i menù della testata (50) */
}

/* Filigrana di brand: il 武 non sta più dietro l'area di lavoro (era .guscio::after, fisso
   nell'angolo del viewport con z-index:-1 — sotto tabelle e card, e all'origine di una serie
   di bug di stacking). Ora è la FIRMA in fondo alla barra laterale, basso-destra, sbordante e
   ritagliata dal bordo del rail.
   Il ritaglio lo fa un BOX dedicato in fondo al rail, non `overflow` sull'aside: il menù dello
   switcher di contesto scende dentro la barra e un overflow sull'aside lo taglierebbe.
   Il colore usa --accent-text, quindi segue accento E tema da sé (resta la taratura d'opacità
   al buio, e la deroga Sumi — rail in accento pieno — più sotto). */
.rail-wm-box {
  position: absolute; left: 0; right: 0; bottom: 0; height: 180px;
  overflow: hidden; pointer-events: none; z-index: 0;
}
.rail-wm {
  position: absolute; right: -6px; bottom: -30px;
  font-family: var(--jp); font-weight: 700; line-height: 1;
  font-size: 11rem;
  color: var(--accent-text); opacity: .06;
  pointer-events: none; user-select: none;
}
/* Al buio la tinta è più chiara e desaturata: alza un filo l'opacità (come faceva la vecchia
   filigrana, e come su MAUI). */
html[data-theme="dark"] .rail-wm { opacity: .10; }
@media (prefers-color-scheme: dark) {
  html[data-theme="system"] .rail-wm,
  html:not([data-theme]) .rail-wm { opacity: .10; }
}

.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;
}

/* Testata-SWITCHER di contesto MINIMALE (variante D, deciso 3 ago dopo il render), sul modello di
   webadmin_switcher_minimale.html: la riga marchio «武 budopass» (muta), poi una RIGA sobria — logo
   piccolo in linea + nome/ruolo + chevron — che pesa come una voce di menù, non come una card (via
   la banda copertina e l'overhang di prima). Con più contesti è il <button>-switcher che apre il menù
   (che scende da QUI). `position: relative` àncora il menù. Colori dalle sole variabili → valgono
   anche per le skin scure (deroghe Sumi più sotto). */
.ente-brand { position: relative; margin: 0; }

/* Marchio nella top-bar (a sinistra): logo + wordmark «@budopass.app» (@ accento, .app attenuato). */
.brand-wm { display:flex; align-items:center; gap:.55rem; padding:0; }
.brand-wm .kk { width:28px; height:28px; border-radius:7px; }
.brand-wm .wm { font-size:1.12rem; font-weight:700; color:var(--text); letter-spacing:-.01em; }
.brand-wm .wm .at { color:var(--accent); }
.brand-wm .wm .tld { color:var(--muted); font-weight:600; }
/* Sotto il breakpoint il ☰ è già a sinistra: tieni il logo, nascondi il wordmark per non affollare. */
@media (max-width: 820px) { .testata .brand-wm .wm { display:none; } }

/* La riga-switcher: nessuna card, fondo trasparente, larga quanto la sidebar (piccoli margini),
   raggio solo per la forma dell'hover. Muta (<div>) con un contesto solo, <button>-switcher con più
   — che azzera lo stile nativo e accende un hover come le voci di nav, più un anello di focus. */
/* Lo switcher era una SCHEDA, messa lì «coerente con le schede di nav» — sparite quelle (24 ago), la
   coerenza è il contrario: la riga si appiattisce e tiene solo il suo box model, così pesa quanto
   una voce di nav. Fondo e bordo trasparenti invece che rimossi: le misure (larghezza, margini,
   raggio dell'hover) restano quelle, e le deroghe di skin hanno ancora dove attaccarsi. */
.brand-riga {
  display: block; width: calc(100% - 1rem); margin: 0 .5rem;
  background: transparent; border: 1px solid transparent;
  border-radius: 12px; color: inherit;
}
/* Variante <button> (più contesti): azzera padding/font/allineamento nativi. Senza più il contorno
   della scheda, è l'HOVER a dire che la riga si preme — quindi lo tiene, tenue, e il focus tiene il
   suo anello d'accento. */
.brand-btn {
  padding: 0; font: inherit; text-align: left; cursor: pointer;
  transition: background .12s;
}
.brand-btn:hover, .brand-btn:focus-visible { background: var(--page-tenue); }
.brand-btn:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }

/* La riga: logo + nome/ruolo + chevron, centrati. Padding come una voce di nav (niente banda). */
.brand-row { display: flex; align-items: center; gap: .6rem; padding: .45rem .55rem; }

/* Logo piccolo in linea (niente overhang). Tiene sotto l'INIZIALE come ripiego: se il logo manca —
   o l'<img> fallisce (onerror lo nasconde) — resta l'iniziale, mai un'immagine rotta. */
.brand-logo {
  position: relative; flex: 0 0 auto; width: 28px; height: 28px;
  border-radius: 8px; overflow: hidden;
}
.brand-ini {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: var(--accent); color: var(--accent-on);
  font-family: var(--jp); font-weight: 600; font-size: .8rem;
}
.brand-logo > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; background: var(--card); }

.brand-cn { min-width: 0; flex: 1; display: flex; flex-direction: column; line-height: 1.15; }
.brand-cn b { font-weight: 600; font-size: .9rem; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.brand-cn span { font-size: .72rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Chevron semplice: lo switcher è già chiaro come riga cliccabile (hover). */
.brand-chev { flex: 0 0 auto; align-self: center; color: var(--muted); font-size: .72rem; }

/* Barra divisoria spessa fra switcher e nav (variante D): ~3px, tono di bordo-rail (un filo di
   stacco dal fondo — più chiaro sul rail scuro, appena più marcato su quello chiaro). La deroga
   Sumi (rail in accento) la porta a bianco translucido, un filo PIÙ chiara del verde. */
/* Le sezioni di nav si separano da sé (il filo di .nav-sez + .nav-sez): qui basta lo spazio, e una
   riga in più sopra la prima sezione sarebbe un secondo stacco per la stessa cosa. */
.brand-sep { height: 0; margin: .5rem 0 0; background: none; }

/* La navigazione è PIATTA (deciso 24 ago, supera la «colonna di schede» del 5 ago): ogni gruppo è
   una .nav-sez senza superficie, e la separazione fra sezioni è un filo — non più il gap fra le
   schede, che qui va a zero: il filo lo disegna .nav-sez + .nav-sez con il proprio margine. */
/* `position: relative; z-index: 1`: la filigrana del rail (.rail-wm-box) è posizionata, quindi
   dipingerebbe SOPRA le voci; così le voci restano sopra di lei. Dentro la nav non vive nessun
   menù a tendina (lo switcher sta in .ente-brand), quindi il contesto d'impilamento non intrappola
   niente — ed è per questo che l'unica area a scorrere del rail può essere lei e non l'aside.
   Con la barra alta una finestra (sopra), quando le voci non ci stanno scorre QUI: testata dello
   switcher e piè con email e versione restano al loro posto, che è ciò che serve vedere sempre. */
.nav {
  padding: .5rem .6rem 0; flex: 1; display: flex; flex-direction: column; gap: 0;
  position: relative; z-index: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
/* La barra di scorrimento della nav, discreta: pollice del tono del bordo-rail su pista
   trasparente, così sul rail chiaro è un'ombra e sulla skin Sumi — rail in accento pieno — non
   diventa una striscia chiara. Solo variabili, nessun colore letterale. Firefox la fa da sé con
   `scrollbar-width: thin` qui sopra. */
.nav::-webkit-scrollbar { width: 8px; }
.nav::-webkit-scrollbar-track { background: transparent; }
.nav::-webkit-scrollbar-thumb { background: var(--rail-border); border-radius: 4px; }

/* La sezione-gruppo: nessuna superficie, nessun bordo, nessun raggio — cinque pannelli bianchi su
   rail aggiungevano peso grafico esattamente dove servirebbe togliere righe. Resta il solo
   raggruppamento logico, che l'occhiello .gruppo e il filo qui sotto raccontano già. */
.nav-sez {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
}
/* Il filo fra una sezione e l'altra: sulla PRIMA di ogni coppia non c'è (il selettore + parte dalla
   seconda), quindi la nav non si apre né si chiude con una riga. Tono --rail-border, lo stesso del
   bordo destro della barra: è una separazione interna al rail, non un bordo di scheda. */
.nav-sez + .nav-sez {
  border-top: 1px solid var(--rail-border);
  margin-top: 8px;
  padding-top: 4px;
}
/* L'ancoraggio in fondo (nav è colonna flex). `margin-top: auto` deve battere gli 8px della regola
   qui sopra, quindi arriva DOPO: il filo continua a disegnarsi anche sopra la sezione ancorata, che
   è la separazione fra il flusso e ciò che sta in fondo.

   Oggi lo porta UNA sola sezione: Piattaforma. «Configurazione ente» e le due porte dell'allievo vi
   hanno rinunciato (deciso 24 ago) perché la convenzione «ciò che non si tocca ogni settimana sta in
   fondo» reggeva con SEDICI voci e un rail pieno — il fondo era l'unico spazio libero. Scesi a nove,
   il rail è mezzo vuoto e la spinta ha smesso di leggersi come intenzione: sul lato allievo erano
   300px di niente prima di «Cerca un ente», che è l'imbuto del pilota. Resta a Piattaforma, che non è
   una sezione del dojo ma un altro ambito e la vede solo l'amministratore. */
.nav-sez.spinta { margin-top: auto; }
/* Guardia, oggi DORMIENTE: con una sola sezione di coda non scatta mai (il selettore ~ vuole una
   .spinta prima). Resta perché il meccanismo che para è reale — due `margin-top: auto` nella stessa
   colonna flex non spingono in fondo, si DIVIDONO lo spazio libero, ed è il buco doppio visto sul
   render del 24 ago. Se una seconda coda dovesse tornare, spinge solo la PRIMA: chi la segue torna al
   margine normale fra sezioni e le si attacca sotto. In CSS e non in Razor perché qui non serve
   sapere QUALE ramo ha reso la coda: basta che una ci sia. */
.nav .nav-sez.spinta ~ .nav-sez.spinta { margin-top: 8px; }

/* Voce a pastiglia: icona + etichetta + conteggio. Con l'icona il posto si trova a colpo
   d'occhio invece di leggere una riga per volta. Etichetta in --text, icona in --muted. */
.nav a {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: 9px 10px;
  margin: 1px 0;
  color: var(--text);
  font-size: .9rem;
  border-radius: 10px;
  position: relative;
}
/* Hover = fondo tenue; attiva = PASTIGLIA in accento tenue, testo e icona in accento
   («Plancia» del mockup). Colori dalle sole variabili → vale su washi e Sumi. */
.nav a:hover { background: var(--page-tenue); color: var(--text); text-decoration: none; }
.nav a.attivo { background: var(--accent-tenue); color: var(--accent); font-weight: 600; }

.nav a .ico { flex: 0 0 18px; width: 18px; height: 18px; color: var(--muted); display: inline-flex; }
.nav a:hover .ico { color: var(--text); }
.nav a.attivo .ico { color: var(--accent); }
.nav a .et { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Conteggio a pillola: accento PIENO = qualcosa da fare (Richieste, Da ratificare, Media);
   «quieta» = informativo, neutro (Soci). */
.nav a .conta {
  flex: 0 0 auto; font-size: .72rem; font-weight: 600; border-radius: 20px; padding: .05rem .5rem;
  background: var(--accent); color: var(--accent-on);
}
.nav a .conta.quieta { background: var(--page-tenue); color: var(--muted); }

/* Sotto-voci di sezione (Soci › Attivi | Cessati, §9 ago): rientrate con un filo a sinistra,
   testo più piccolo. Restano `.nav a`, così ereditano hover, pastiglia attiva e conteggio. */
.nav .sub { margin-left: 14px; padding-left: 10px; border-left: 1px solid var(--border); display: flex; flex-direction: column; }
.nav a.sub-i { padding: 6px 10px; font-size: .84rem; }

/* Voce «in arrivo» del rail (pilota): pastiglia ambra a destra della voce spenta. */
.nav a .pill-arrivo {
  margin-left: auto; flex: 0 0 auto;
  font-size: .58rem; text-transform: uppercase; letter-spacing: .03em; font-weight: 700;
  background: var(--warn-bg); color: var(--warn-text); border-radius: 20px; padding: .05rem .4rem;
}
/* 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) ===================== */
.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); }

/* Occhiello di gruppo, in cima alla sua sezione: minuscolo, spaziato, fioco. Senza la scheda che
   lo conteneva gli serve un filo d'aria in più sopra, sennò si appoggia alla riga di separazione;
   corpo, spaziatura e colore restano quelli. */
.nav .gruppo {
  padding: 12px 10px 3px;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  opacity: .7;
}

.piede-laterale {
  margin-top: auto;
  padding: 1rem 1.25rem 0;
  border-top: 1px solid var(--rail-border);
  font-size: .8rem;
  color: var(--muted);
  /* sopra la filigrana del rail, che gli passa dietro (email e link versione leggibili) */
  position: relative; z-index: 1;
}

/* Versione build sotto l'email, ora link allo storico «Novità»: eredita il colore già temato del
   piè (muted in chiaro, accent-on in Sumi) — non fissare --muted, sparisce sul rail scuro — e resta
   block col suo margine anche da <a>. text-decoration:none esplicito perché la regola globale «a»
   ha specificità minore della classe. */
.piede-versione { display: block; margin-top: .35rem; font-size: .72rem; color: inherit; opacity: .7; text-decoration: none; }
.piede-versione:hover { text-decoration: underline; }

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

/* Masthead: nome dell'ente in evidenza, selettore ente, badge ruolo, scelta tema (§3.1). */
.testata {
  background: var(--card-alta);
  border-bottom: 1px solid var(--border);
  padding: .7rem 1.5rem;
  display: flex;
  align-items: center;
  gap: 1rem;
}

.testata .ente { font-size: 1.15rem; font-weight: 600; }
.testata .spazio { flex: 1; }

.pagina { padding: 1.75rem; max-width: 1180px; 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; }
/* 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; }

/* --- 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;
}
.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; }
.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; }

/* 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; }
@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; }
.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; }

/* 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; }

/* 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 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); }
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. */
input, 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%;
}
/* L'altezza della famiglia. Caselle e radio restano fuori: non sono scatole di testo e non
   devono diventare alte 2.5rem. */
input:not([type="checkbox"]):not([type="radio"]), select, textarea {
  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. */
input:disabled, select:disabled, textarea:disabled {
  background: 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); }
.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; }

/* 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-azioni { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; padding-bottom: .2rem; }

.scheda-corpo { padding: 0 1.25rem 1.25rem; }
.scheda-descr { margin: .4rem 0 0; color: var(--text); line-height: 1.55; white-space: pre-line; }
.scheda-sez { margin-top: 1.2rem; }
.scheda-sez-tit { font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin-bottom: .5rem; }

/* 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. */
.aff-carta { transition: box-shadow .2s ease, border-color .2s ease; }
/* L'identità dell'ente (logo + nome) è un link alla vetrina: occupa la riga come prima, lo
   stato resta accanto fuori dal link. */
.aff-ente { flex: 1; min-width: 0; display: flex; align-items: center; gap: 1rem;
  text-decoration: none; color: inherit; }
.aff-ente:hover .nome { color: var(--accent-text); text-decoration: underline; }
/* La riga puntata da una notifica di esito (?ev=): un alone d'accento, non un colore pieno. */
.aff-carta.evidenziata { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tenue, rgba(0,0,0,.06)); }
.aff-dati { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem 1rem; margin: .9rem 0 0; }
.aff-dati > div { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.aff-dati dt { font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.aff-dati dd { margin: 0; font-size: .95rem; color: var(--text); }
.aff-dati dd.mono { font-family: monospace; letter-spacing: .05em; }
.aff-rifiuto { margin-top: .9rem; padding-top: .8rem; border-top: 1px solid var(--border); }
.aff-motivo { font-weight: 600; color: var(--text); }

.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; }

/* 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); }

/* --- testata: a sinistra vuota (solo ☰ sotto il breakpoint), preferenze e utente a destra ------
   Il titolo di pagina in alto è stato tolto (deciso 3 ago): dove sei lo dicono la voce di sidebar
   evidenziata e l'H1. Tema/accento/skin dietro l'icona preferenze (§3.1). */
.testata { position: relative; }

/* 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 .lc { font-size: .78rem; font-weight: 700; letter-spacing: .4px; color: var(--text); }
.lingua .cx { font-size: .6rem; color: var(--muted); }

.me-btn {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .2rem .4rem .2rem .2rem; border-radius: 999px;
  border: 1px solid var(--border); background: var(--card); cursor: pointer;
}
.me-btn:hover { background: var(--riga-hover); }
.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;
}
/* Il menù dei contesti scende dalla testata brandizzata della sidebar (àncora .ente-brand,
   position: relative): non più da `left: 1.5rem` nella barra in alto. Largo quanto la sidebar,
   con un filo di stacco sotto la card. */
.menu-contesto { top: calc(100% + .3rem); left: .5rem; right: .5rem; }
.menu-pref { right: 4rem; width: 268px; }
.menu-utente { right: 1.5rem; width: 236px; }
/* Il menù lingua scende dal pulsante globo, alla sua sinistra: sta a destra di quanto basta a
   restare sotto la barra (campana + preferenze + utente lo spingono verso il centro). */
.menu-lingua { right: 9.5rem; width: 200px; }

/* 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; }

/* Voce del menù utente: icona a sinistra + testo, con gap (restyle §menù utente). L'icona segue
   il tratto muted; «Esci» è la variante in accento, un'azione a sé staccata da un menu-sep. */
.menu-voce {
  display: flex; align-items: center; gap: .6rem; width: 100%; text-align: left; padding: .5rem;
  border: none; background: transparent; border-radius: var(--raggio-s);
  cursor: pointer; color: var(--text); font-family: var(--sans); font-size: .9rem;
}
.menu-voce:hover { background: var(--riga-hover); }
.menu-voce .mv-ico { display: inline-flex; color: var(--muted); }
.menu-voce .mv-ico svg { width: 17px; height: 17px; }
.menu-voce.esci, .menu-voce.esci .mv-ico { color: var(--accent-text); }
.menu-utente-testa { display: flex; align-items: center; gap: .6rem; padding: .5rem; min-width: 0; }
.menu-utente-testa > div { min-width: 0; }
.menu-utente-testa b { font-size: .9rem; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.menu-utente-testa small { display: block; font-size: .74rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.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"] .nav .gruppo,
html[data-skin="obi"] .carta-titolo,
html[data-skin="obi"] .menu-sez { color: var(--accent-text); opacity: 1; }
html[data-skin="obi"] .carta-titolo,
html[data-skin="obi"] .nav .gruppo { 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"] .barra-laterale {
  background: var(--accent); border-right-color: var(--accent-banda);
}
html[data-skin="sumi"] .wordmark,
html[data-skin="sumi"] .nav a,
html[data-skin="sumi"] .nav a .ico,
html[data-skin="sumi"] .nav a .conta,
html[data-skin="sumi"] .piede-laterale { color: var(--accent-on); }
/* Sumi lava il rail d'accento pieno: la filigrana non può restare accento su accento — passa al
   bianco-carta (--accent-on) con un filo d'opacità in più, come gli altri segni sul rail. */
html[data-skin="sumi"] .rail-wm { color: var(--accent-on); opacity: .12; }
html[data-skin="sumi"] .nav .gruppo { color: var(--accent-on); opacity: .75; }
/* Sumi ha il rail in accento pieno: le sezioni non sono più pannelli da dipingere (nav piatta,
   24 ago) — resta il FILO di separazione, che in --rail-border sull'accento sparirebbe: qui passa a
   un bianco translucido appena percettibile. La pastiglia attiva (accent-tenue sul washi) continua
   a staccarsi con un bianco più marcato. */
html[data-skin="sumi"] .nav-sez + .nav-sez { border-top-color: rgba(255, 255, 255, .16); }
/* Stessa ragione per il pollice della barra di scorrimento della nav: --rail-border è una crema
   chiara e sull'accento pieno diventerebbe una STRISCIA, cioè l'unica cosa che si vede del rail.
   Bianco translucido come il filo qui sopra, un gradino più marcato perché è un comando e non una
   separazione. */
html[data-skin="sumi"] .nav::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .22); }
html[data-skin="sumi"] .nav a:hover { background: rgba(255, 255, 255, .14); color: var(--accent-on); }
html[data-skin="sumi"] .nav a.attivo { background: rgba(255, 255, 255, .24); color: var(--accent-on); }
html[data-skin="sumi"] .nav a:hover .ico,
html[data-skin="sumi"] .nav a.attivo .ico { color: var(--accent-on); }
/* I conteggi: l'accento pieno sul rail d'accento sparirebbe → bianco translucido, testo su-accento. */
html[data-skin="sumi"] .nav a .conta,
html[data-skin="sumi"] .nav a .conta.quieta { background: rgba(255, 255, 255, .18); color: var(--accent-on); }
/* Lo switcher minimale sull'accento pieno: il testo su --accent-on; l'hover un bianco translucido
   come le voci di nav (var(--card) sarebbe un blocco chiaro stonato) e il focus un anello bianco
   (l'accento su accento sparirebbe). La barra divisoria un bianco translucido, un filo PIÙ chiara
   del verde. */
html[data-skin="sumi"] .brand-cn b { color: var(--accent-on); }
html[data-skin="sumi"] .brand-cn span,
html[data-skin="sumi"] .brand-wm,
html[data-skin="sumi"] .brand-chev { color: var(--accent-on); opacity: .8; }
html[data-skin="sumi"] .brand-wm .kk { color: var(--accent-on); opacity: 1; }
/* Lo switcher è piatto anche qui: niente pannello da dipingere, resta il solo hover translucido
   (e il suo anello di focus bianco) — che senza contorno è ciò che dice «questa riga si preme». */
html[data-skin="sumi"] .brand-btn:hover,
html[data-skin="sumi"] .brand-btn:focus-visible { background: rgba(255, 255, 255, .14); }
html[data-skin="sumi"] .brand-btn:focus-visible { box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .55); }
html[data-skin="sumi"] .piede-laterale { border-top-color: var(--accent-banda); }
html[data-skin="sumi"] .testata {
  background: var(--accent); border-bottom-color: var(--accent-banda);
}
/* …e come la rail, anche il CONTENUTO della testata va ribaltato: sul fondo accento il testo scuro
   di default e i comandi a fondo chiaro (icona, utente) sparirebbero. Testo su --accent-on; i comandi
   su un bianco translucido, lo stesso stato attivo/hover della rail. I colori di stato non c'entrano
   — qui è solo cromo. */
html[data-skin="sumi"] .testata .chev,
html[data-skin="sumi"] .testata .ico-btn,
html[data-skin="sumi"] .testata .lingua,
html[data-skin="sumi"] .testata .lingua .lc,
html[data-skin="sumi"] .testata .lingua .cx,
html[data-skin="sumi"] .testata .me-btn { color: var(--accent-on); }

/* Il marchio nella top-bar: sul fondo accento di Sumi il wordmark (--text scuro), l'@ (--accent) e
   il .app (--muted) sparirebbero. Tutti su --accent-on; il .app appena attenuato. Il logo .kk è
   un'immagine e resta pieno. */
html[data-skin="sumi"] .testata .brand-wm .wm,
html[data-skin="sumi"] .testata .brand-wm .wm .at { color: var(--accent-on); }
html[data-skin="sumi"] .testata .brand-wm .wm .tld { color: var(--accent-on); opacity:.7; }

html[data-skin="sumi"] .testata .ico-btn,
html[data-skin="sumi"] .testata .lingua,
html[data-skin="sumi"] .testata .me-btn {
  background: rgba(255, 255, 255, .14);
  border-color: rgba(255, 255, 255, .24);
}
html[data-skin="sumi"] .testata .ico-btn:hover,
html[data-skin="sumi"] .testata .lingua:hover,
html[data-skin="sumi"] .testata .me-btn:hover { background: rgba(255, 255, 255, .24); }

/* L'avatar utente è ad accento-tenue: sull'accento pieno si annulla, quindi passa anch'esso
   al bianco translucido. */
html[data-skin="sumi"] .testata .av {
  background: rgba(255, 255, 255, .18); 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; }

/* --- 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;
  --err:#A63125;  --err-bg:#F6E4E1;  --err-text:#7A231B;
  --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; }
.lezione-oggi .presenti { font-weight: 600; white-space: nowrap; }

/* 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); }

/* 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); }
.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; }

.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); }

.reg-miss { background: var(--warn-bg); border: 1px solid var(--warn); border-radius: var(--raggio); padding: .7rem .9rem; margin-bottom: 1.1rem; font-size: .84rem; color: var(--warn-text); }
.reg-miss b { font-weight: 700; }

/* 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 (margin-top: 0) e incollerebbe un gruppo all'altro. La prima attaccata al
   bordo alto, le successive staccate — stesso respiro di .reg-actions, non un numero a caso. */
.reg-tab .sez { margin-top: 1.1rem; }
.reg-tab .sez:first-child { margin-top: 0; }
.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; }

.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; }
.modale { width: 100%; max-width: 420px; 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; }
.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; }

/* 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. */
.ah-stats { display: flex; gap: 1.4rem; flex-wrap: wrap; }
.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; }
.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 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: .2rem; }
.nz-head h1 { margin: 0; }
.nz-head .spazio { flex: 1; }

/* --- elenco gestione --- */
.nz-list { display: flex; flex-direction: column; gap: .8rem; max-width: 760px; }
.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-feed { display: flex; flex-direction: column; gap: 1rem; max-width: 640px; }
.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-fc > .chiudi-avviso { z-index: 2; background: rgba(0,0,0,.45); color: #fff; }
.nz-fc > .chiudi-avviso:hover { background: rgba(0,0,0,.65); color: #fff; }
.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-fcv .pin-badge { position: absolute; top: .5rem; left: .5rem; font-size: .72rem;
  padding: .12rem .5rem; border-radius: 999px; background: var(--warn-bg); color: var(--warn-text); border: 1px solid var(--warn); }
.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) --- */
.nz-det { max-width: 640px; }
.nz-det .torna { display: inline-block; margin-bottom: .8rem; font-size: .9rem; }
.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-pinl { display: inline-block; margin: .2rem 0 .6rem; font-size: .78rem; padding: .15rem .6rem;
  border-radius: 999px; background: var(--warn-bg); color: var(--warn-text); border: 1px solid var(--warn); }
.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 .6rem .95rem; 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; }
.camp-dot {
  position: absolute; left: .35rem; top: 50%; transform: translateY(-50%);
  width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
}
.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.avviso  { background: var(--warn-bg);      color: var(--warn-text); }
.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); }

/* 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: form a sinistra, «Gestione» (rimandi di navigazione) a destra ==== */
.imp-griglia { display: flex; gap: 1.5rem; align-items: flex-start; flex-wrap: wrap; }
.imp-form { flex: 1 1 460px; min-width: 300px; }
.imp-lato { flex: 0 0 300px; min-width: 260px; }
.imp-lato > h2 { margin: .2rem 0 .8rem; }

/* Card settaggi «Gestione» (17 ago): interruttori + modalità. La modalità (sotto lo switch
   acceso) rientra con un filetto, così si legge come sua sottopiega; un divisore separa i due
   interruttori. */
.imp-gestione { margin-bottom: .8rem; }
.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; }

/* Piastrella di navigazione: icona + titolo/conteggio + dettaglio + chevron. Non è il form —
   è un rimando alla pagina di gestione. */
.gestione-tile {
  display: flex; align-items: center; gap: .75rem;
  padding: .75rem .85rem; margin-bottom: .6rem;
  border: 1px solid var(--border); border-radius: var(--raggio-s);
  background: var(--card); color: var(--text); text-decoration: none;
  cursor: pointer; transition: background .12s, border-color .12s;
}
.gestione-tile:hover { background: var(--riga-hover); border-color: var(--accent); }
.gestione-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);
}
.gestione-ico svg { width: 18px; height: 18px; }
.gestione-corpo { flex: 1; min-width: 0; }
.gestione-corpo b { display: block; font-size: .92rem; }
.gestione-corpo span { display: block; font-size: .78rem; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gestione-chev { flex: 0 0 auto; color: var(--muted); }

/* ===== 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); }
.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; }
.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%); }

/* ============================================================================
   STRATO MOBILE (≤ 820px): barra in alto + hamburger + cassetto off-canvas,
   contenuto a tutta larghezza, pagine chiave a card e reti di sicurezza.
   Sopra il breakpoint TUTTO qui sotto è inerte: il layout desktop è invariato.
   Breakpoint 820px, coerente con le media query già presenti nel foglio.
   ============================================================================ */

/* L'hamburger e lo scrim non esistono su desktop: si accendono solo nel @media. */
.ham { display: none; }
.scrim-drawer { display: none; }

.ham {
  width: 38px; height: 38px; flex: 0 0 auto; padding: 0;
  border: 1px solid var(--border); border-radius: 9px;
  background: var(--card); color: var(--text);
  align-items: center; justify-content: center; cursor: pointer;
}
.ham:hover { background: var(--riga-hover); }
.ham svg { display: block; }
/* La skin Sumi lava la testata d'accento: l'hamburger la segue come gli altri comandi. */
html[data-skin="sumi"] .testata .ham { color: var(--accent-on); background: transparent; border-color: var(--accent-banda); }

@media (max-width: 820px) {
  /* --- il cassetto: la barra laterale scorre da sinistra sopra uno scrim ------------------- */
  .ham { display: inline-flex; }

  .barra-laterale {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 60;
    width: 274px; max-width: 84vw; flex-basis: auto;
    transform: translateX(-100%);
    transition: transform .22s ease;
    overflow-y: auto; overflow-x: hidden;
    box-shadow: 6px 0 24px rgba(0, 0, 0, .28);
  }
  .barra-laterale.aperto { transform: translateX(0); }

  /* Nel cassetto scorre la BARRA intera: una nav che scorre per conto suo darebbe due barre di
     scorrimento annidate, e il piè resterebbe appeso a metà. */
  .nav { overflow: visible; min-height: auto; }

  /* Nel cassetto la barra SCORRE (overflow-y: auto): un box in `absolute` (o `fixed`, che qui è
     contenuto dal transform del cassetto) resta ancorato al FONDO DELLA FINESTRELLA, quindi
     scorrendo risalirebbe e taglierebbe il 武 a metà cassetto. Qui la firma torna IN FLUSSO come
     ultimo elemento — sotto al piè — e il margine negativo le ridà i suoi 180px, così non allunga
     il contenuto: il 武 sta in fondo al cassetto, dove finiscono le voci, come sul rail desktop. */
  .rail-wm-box { position: relative; flex: 0 0 180px; margin-top: -180px; }

  .scrim-drawer {
    display: block; position: fixed; inset: 0; z-index: 55;
    background: rgba(20, 17, 14, .45);
  }

  /* 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 ------------------------ */
  /* Variante B (deciso 3 ago): niente titolo in alto — solo hamburger + campana/preferenze/utente.
     Lo switcher vive nella testata del cassetto. */
  .testata { padding: .55rem .8rem; gap: .5rem; }

  /* 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)); }
  .menu-utente { right: .8rem; width: min(224px, calc(100vw - 1.6rem)); }

  /* Il menù dei contesti scende dentro il cassetto, che è fisso e `overflow-y: auto`: un dropdown
     assoluto verrebbe TAGLIATO. Diventa quindi un pannello IN FLUSSO nella testata della sidebar —
     spinge giù le voci, scorre col cassetto, non lo taglia nessuno. Niente ombra da fluttuante. */
  .menu.menu-contesto {
    position: static; top: auto; left: auto; right: auto;
    width: auto; margin: 0 .5rem .4rem; box-shadow: none;
    max-height: 55vh; overflow-y: auto;
  }

  /* --- il corpo pagina: margini più stretti, niente overflow orizzontale ------------------- */
  .pagina { padding: 1rem; }

  /* 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) { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }

  /* --- Soci: la tabella ordinabile diventa un elenco di card (mockup budopass_mobile.html).
     Solo CSS: gli @onclick sulla riga e sulle intestazioni restano intatti, la tabella torna
     tabella sopra il breakpoint. */
  table.soci, table.soci tbody, table.soci tr, table.soci td { display: block; }
  table.soci thead { display: none; }
  table.soci tr {
    border: 1px solid var(--border); border-radius: var(--raggio);
    background: var(--card); box-shadow: var(--ombra);
    padding: .7rem .85rem; margin-bottom: .6rem;
  }
  table.soci tbody tr:hover { background: var(--card); }
  table.soci td { border: none; padding: .18rem 0; }
  /* Prima cella (segno + nome): testa della card, un filo più staccata. */
  table.soci td:first-child { padding-bottom: .35rem; }
  table.soci .cell-socio .risalto { font-weight: 600; }
  /* Celle centrali: etichetta della colonna a sinistra, valore a destra. */
  table.soci td[data-etichetta] {
    display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
    font-size: .86rem;
  }
  table.soci td[data-etichetta]::before {
    content: attr(data-etichetta); color: var(--muted); font-weight: 500; flex: 0 0 auto;
  }
  table.soci td[data-etichetta].num { font-variant-numeric: tabular-nums; }
  /* Ultima cella (stato): i badge a fondo card, che vanno a capo. */
  table.soci td:last-child {
    padding-top: .45rem; display: flex; flex-wrap: wrap; gap: .35rem;
  }
}

/* ============================================================================
   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;
}

/* 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; }
.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. */
.pagina > *:not(:where(.modale-fondo, .avviso-host, .toolbar, .vuoto)) {
  animation: entra-su var(--t-media) var(--curva) both;
}

/* 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 { transition: transform var(--t-corta) var(--curva); }
.faccenda: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;
  }
}
