/* ⚠️ COPIA di AVISNext.App/AVISNext.App.Shared/wwwroot/app.css: la demo dell app usa le stesse regole.
   Se l originale cambia, ricopiarlo. Si carica SOLO nelle pagine /demo-app (vedi App.razor). */

/*
   Gli stili che MudBlazor non copre: la barra di navigazione in fondo, la scala dei testi, il
   tesserino e i movimenti.

   ⚠️ Tutto ciò che riguarda i COLORI passa dalle variabili di MudBlazor (--mud-palette-*) e non da
   valori scritti a mano: sono le uniche che cambiano insieme al tema chiaro/scuro. Un colore
   cablato qui resterebbe uguale in modalità scura, ed è il modo più semplice per ottenere testo
   nero su fondo nero.
*/

/*
   ⚠️ Il fondo è il colore del TEMA, con il bianco della splash come ripiego.

   Il ripiego non è decorativo: `--mud-palette-background` la definisce MudBlazor quando disegna il
   tema, e prima di quel momento la variabile non esiste — quindi vale il bianco, ed è ciò che raccorda
   la splash al primo disegno. Appena il tema c'è, il fondo diventa quello giusto.

   ⚠️ Deve stare su <html> e non solo su <body>: il fondo della pagina lo dà l'elemento radice, e
   quello del body dipinge solo il proprio riquadro. Con il colore della splash fisso qui, scorrendo
   oltre il contenuto o aprendo la tastiera lo si vedeva spuntare da sotto, anche in modalità scura.
*/
html, body {
    height: 100%;
    margin: 0;
    background-color: var(--mud-palette-background, #FFFFFF);
    /* Impedisce il rimbalzo elastico dell'intera pagina: dentro un'app quel movimento rivela il
       fatto che sotto c'è una pagina web, e si nota soprattutto quando si arriva in fondo a un
       elenco. Lo scorrimento vero avviene dentro il contenuto. */
    overscroll-behavior-y: none;
}

body {
    /* Il testo non si seleziona con la pressione prolungata: in un'app quella pressione serve
       ad altro, e la lente di ingrandimento del sistema che compare sopra una scheda è solo
       fastidiosa. Gli elementi in cui la selezione ha senso la riabilitano più sotto. */
    -webkit-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
}

/* I dati del donatore si devono poter copiare: un codice fiscale o un numero di telefono si
   incollano altrove, ed è una delle poche cose che si fanno davvero da un tesserino. */
.selezionabile,
.selezionabile * {
    -webkit-user-select: text;
    user-select: text;
}

/* ── Scala dei testi ───────────────────────────────────────────────────────────────────────────
   Cresce tutto insieme — caratteri, spaziature, altezze dei campi — invece di ottenere testo
   grande dentro riquadri rimasti piccoli, perché le misure di MudBlazor sono in rem.

   ⚠️ Proprio per questo la classe va messa su <html> e su nient'altro: rem si calcola SEMPRE
   sull'elemento radice, quindi su un contenitore interno queste regole non ingrandirebbero niente
   di ciò che sta dentro. Ci è già successo, e senza alcun errore: il selettore c'era, funzionava,
   e non si vedeva cambiare nulla. La classe la applica avisnext.scalaTesto in index.html. */
.testo-normale { font-size: 100%; }
.testo-grande { font-size: 115%; }
.testo-molto-grande { font-size: 132%; }

/* ── Movimenti ─────────────────────────────────────────────────────────────────────────────────
   Le transizioni servono a far capire da dove arriva quello che compare: un contenuto che appare
   di colpo sembra un salto, uno che sale di dieci pixel sembra una risposta al tocco.

   ⚠️ Tutte le durate sono brevi (150-260ms). Sopra i 300ms un'app comincia a sembrare lenta
   invece che curata, e la differenza si sente proprio sulle schermate che si aprono spesso. */

/* ── Aree di sicurezza ─────────────────────────────────────────────────────────────────────────
   ⚠️ index.html dichiara viewport-fit=cover: la pagina arriva SOTTO la tacca e sotto la barra
   gestuale, e senza le regole qui sotto i controlli finiscono in zone che il dito non raggiunge o
   che il sistema copre. Il "cover" senza le env() è il modo più veloce per avere un'app che su
   iPhone sembra tagliata: su Android e Windows non si nota nulla, perché lì gli inset sono zero.

   Le misure stanno in variabili e non sparse nei fogli: la barra in fondo e lo spazio che le pagine
   devono lasciarle sono lo stesso numero, e scrivendolo due volte prima o poi divergono. */
:root {
    --vr-sicura-alto: env(safe-area-inset-top, 0px);
    --vr-sicura-basso: env(safe-area-inset-bottom, 0px);
    --vr-sicura-sinistra: env(safe-area-inset-left, 0px);
    --vr-sicura-destra: env(safe-area-inset-right, 0px);

    /* Altezza della barra di navigazione, tacca esclusa. Vedi .voce-navigazione. */
    --vr-barra-navigazione: 56px;

    /*
       Spazio riservato alla barra in alto.

       ⚠️ È un numero, non un calcolo su --mud-appbar-height. Quella variabile la emette il tema di
       MudBlazor a runtime: se un domani non ci fosse — tema cambiato, versione diversa — il calc()
       diventerebbe INVALIDO, la dichiarazione verrebbe scartata e la spaziatura sparirebbe di
       colpo, senza un errore da nessuna parte e con il contenuto sotto la barra. Un numero fisso
       sbaglia al massimo di qualche pixel; un calcolo invalido sbaglia di tutto.

       La barra è densa (42px reali con AppbarHeight a 56): i pixel in più sono margine voluto.
    */
    --vr-barra-alto: 56px;

    /* Imbottitura verticale del contenitore di pagina. La chat la sottrae per calcolare la propria
       altezza: se cambia qui, cambia anche là senza doversene ricordare. */
    --vr-imbottitura-pagina: 16px;

    /* Altezza utile di una schermata PRIMA dell'accesso, cioè quanto resta della finestra una
       volta tolti gli spazi che la incorniciano.

       ⚠️ Sostituisce i "min-height: 85vh" e "78vh" che c'erano nelle pagine, ed erano il difetto:
       un 85vh non sa niente della tacca, della barra gestuale né dell'imbottitura di pagina, che
       si SOMMANO. Su un telefono con la tacca il totale superava l'altezza dello schermo e la
       pagina di accesso diventava scorrevole senza averne motivo; sull'istruttiva succedeva il
       contrario — 78vh era troppo poco, e pulsante e pallini restavano a mezz'aria invece che in
       fondo.

       ⚠️ dvh e non vh: su Android la barra degli indirizzi non c'è, ma la barra di sistema può
       comparire e sparire, e vh resta fermo al valore più grande. dvh segue quello che si vede
       davvero.

       Le voci sottratte, nell'ordine in cui stanno nella pagina: area di sicurezza in alto,
       imbottitura di .vr-accesso (che è quella di pagina più otto), imbottitura in fondo di
       .vr-pagina, e lo spazio che .vr-senza-barra lascia alla barra gestuale. */
    --vr-schermata-accesso: calc(100dvh
        - var(--vr-sicura-alto)
        - (var(--vr-imbottitura-pagina) + 8px)
        - var(--vr-imbottitura-pagina)
        - (var(--vr-sicura-basso) + 12px));
}

/* La barra in alto scende sotto la tacca invece di finirci dentro. */
.mud-appbar {
    padding-top: var(--vr-sicura-alto);
    padding-left: var(--vr-sicura-sinistra);
    padding-right: var(--vr-sicura-destra);
}

/*
   E il contenuto scende della stessa misura, altrimenti la prima riga resta nascosta dietro. La
   barra è FISSA: il contenuto le scorre sotto, e questa imbottitura è l'unica cosa che tiene
   visibile l'inizio della pagina.

   ⚠️ Il secondo selettore NON è una ridondanza, ed è il motivo per cui prima non funzionava.
   MudBlazor dichiara `.mud-appbar-dense ~ .mud-main-content`, che con DUE classi ha specificità
   maggiore della sola `.mud-main-content`: vinceva sempre, qualunque fosse l'ordine dei fogli di
   stile, imponendo 42px e nessuna area di sicurezza. Il contenuto finiva sotto la tacca su tutte
   le pagine tranne la chat, che si salvava solo perché è posizionata a parte.
   Ripetendo lo stesso selettore si pareggia la specificità, e a parità vince l'ultimo dichiarato:
   app.css è caricato dopo MudBlazor.

   ⚠️ E vale SOLO dove la barra c'è davvero. Prima la regola era su ogni .mud-main-content, quindi
   anche sulle schermate prima dell'accesso — che una barra in alto non ce l'hanno. Il risultato
   erano 56px di vuoto in cima a presentazione, accesso e primo accesso: spazio per una barra che
   non esiste, che spingeva giù il contenuto e faceva scorrere pagine che ci sarebbero state
   comode. Le due classi le mettono già i layout, non c'è niente da aggiungere al markup.
*/
.mud-main-content.vr-con-barra,
.mud-appbar-dense ~ .mud-main-content.vr-con-barra {
    padding-top: calc(var(--vr-barra-alto) + var(--vr-sicura-alto));
}

/* Senza barra scende solo sotto la tacca: non c'è niente sopra da cui scansarsi. */
.mud-main-content.vr-senza-barra,
.mud-appbar-dense ~ .mud-main-content.vr-senza-barra {
    padding-top: var(--vr-sicura-alto);
}

/* Un filo di separazione sotto la barra: senza, il contenuto che le scorre sotto sembra sparire
   dentro di essa invece che passarci dietro — la barra è dello stesso colore della pagina e non
   ha ombra. */
.mud-appbar {
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

/*
   Finestre a schermo intero (il dettaglio di una presentazione, il menu delle sezioni).

   ⚠️ Non stanno dentro .mud-main-content: sono attaccate al fondo della pagina, quindi non
   ereditano NIENTE della spaziatura qui sopra. Aprendo un dettaglio, la sua intestazione finiva
   dritta sotto la tacca — ed è un caso che si nota solo su iPhone, perché altrove l'inset è zero.
*/
.mud-dialog.mud-dialog-fullscreen {
    padding-top: var(--vr-sicura-alto);
    padding-bottom: var(--vr-sicura-basso);
    padding-left: var(--vr-sicura-sinistra);
    padding-right: var(--vr-sicura-destra);
}

/* Contenitore delle pagine: imbottitura verticale dichiarata (al posto di py-4) e laterale che
   tiene conto degli angoli arrotondati in orizzontale. */
.vr-pagina {
    padding-top: var(--vr-imbottitura-pagina);
    padding-bottom: var(--vr-imbottitura-pagina);
    padding-left: max(12px, var(--vr-sicura-sinistra));
    padding-right: max(12px, var(--vr-sicura-destra));
}

/* ⚠️ Lo spazio che le pagine lasciano alla barra in fondo. Era un pb-16 di MudBlazor, cioè 64px
   fissi: ma la barra è alta 56px PIÙ l'area di sicurezza, che su un iPhone recente vale una
   trentina di pixel. 64 < 86, ed è il motivo per cui la barra copriva la fine del tesserino. */
.vr-con-barra {
    padding-bottom: calc(var(--vr-barra-navigazione) + var(--vr-sicura-basso) + 12px);
}

/* Schermate senza barra (accesso, presentazione): serve comunque lo spazio in fondo, altrimenti
   il pulsante di conferma finisce sotto la barra gestuale. */
.vr-senza-barra {
    padding-bottom: calc(var(--vr-sicura-basso) + 12px);
}

:root {
    --vr-durata-breve: 150ms;
    --vr-durata: 220ms;
    --vr-curva: cubic-bezier(.2, .7, .3, 1);

    /*
       Intensità delle pastiglie colorate dietro le icone.

       ⚠️ NON si usano le variabili --mud-palette-*-hover: sono calcolate sulla HoverOpacity del
       tema, cioè 0.04, e a quel livello la pastiglia è invisibile — l'icona sembrerebbe appoggiata
       sul nulla. Si parte invece dalle --mud-palette-*-rgb e si sceglie qui l'opacità.

       ⚠️ E non si usa color-mix(), che sarebbe più elegante: non esiste su iOS prima della 16.4, e
       il minimo supportato dall'app è iOS 15. Su quei dispositivi la regola verrebbe scartata e lo
       sfondo resterebbe trasparente, senza nessun errore da nessuna parte.
    */
    --vr-tinta: 0.12;
    --vr-tinta-forte: 0.16;
}

@keyframes vr-entra {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: none; }
}

@keyframes vr-dissolvi {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* Il contenuto della pagina entra dal basso. Si applica al contenitore, una volta sola. */
.pagina-entra {
    animation: vr-entra var(--vr-durata) var(--vr-curva) both;
}

/* Le righe di un elenco entrano una dopo l'altra. Il ritardo lo passa la pagina con --indice:
   scaglionare fa leggere l'elenco come una sequenza invece che come un blocco che appare.
   ⚠️ Il ritardo è limitato a 8 righe (vedi il calc): oltre, l'ultima riga arriverebbe mezzo
   secondo dopo la prima e sembrerebbe che l'app arranchi. */
.riga-entra {
    animation: vr-entra var(--vr-durata) var(--vr-curva) both;
    animation-delay: calc(min(var(--indice, 0), 8) * 35ms);
}

.dissolvi-entra {
    animation: vr-dissolvi var(--vr-durata) var(--vr-curva) both;
}

/* Riscontro al tocco su tutto ciò che è premibile: senza, su un elenco di sole righe non si
   capisce se il tocco è stato raccolto. */
.premibile {
    transition: transform var(--vr-durata-breve) var(--vr-curva),
                background-color var(--vr-durata-breve) var(--vr-curva),
                border-color var(--vr-durata-breve) var(--vr-curva);
}

.premibile:active {
    transform: scale(.985);
    background-color: rgba(var(--mud-palette-text-secondary-rgb, 113,119,132), .07);
}

/*
   ⚠️ Chi ha chiesto al sistema di ridurre i movimenti lo ha fatto per un motivo: per alcune
   persone le animazioni causano nausea o disorientamento. Qui si azzerano tutte, non si
   accorciano.
*/
@media (prefers-reduced-motion: reduce) {
    .pagina-entra,
    .riga-entra,
    .dissolvi-entra {
        animation: none;
    }

    .premibile {
        transition: none;
    }

    .premibile:active {
        transform: none;
    }
}

/* ── Barra di navigazione inferiore ─────────────────────────────────────────────────────────── */

.navigazione-inferiore {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1300;
    display: flex;
    justify-content: space-around;
    align-items: stretch;
    background-color: var(--mud-palette-surface);
    border-top: 1px solid var(--mud-palette-lines-default);
    /* L'area di sicurezza è la fascia in fondo agli schermi con la barra gestuale: senza questo
       spazio le etichette finiscono sotto quella barra e i tocchi vengono intercettati dal
       sistema invece che dall'app. */
    padding-bottom: env(safe-area-inset-bottom, 0px);
}

.voce-navigazione {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    /* 56px è l'altezza minima perché un tocco sia comodo: sotto questa misura si sbaglia voce, e
       si sbaglia soprattutto camminando o con una mano sola. */
    min-height: 56px;
    padding: 6px 4px;
    border: 0;
    background: none;
    color: var(--mud-palette-text-secondary);
    font: inherit;
    cursor: pointer;
    transition: color var(--vr-durata-breve) var(--vr-curva);
}

.voce-navigazione.attiva {
    color: var(--mud-palette-primary);
}

/* La pastiglia dietro l'icona della voce attiva: dice dove si è senza bisogno di leggere. */
.voce-navigazione .mud-icon-root {
    transition: transform var(--vr-durata) var(--vr-curva);
}

.voce-navigazione.attiva .mud-icon-root {
    transform: translateY(-1px) scale(1.08);
}

.etichetta-navigazione {
    font-size: 0.72rem;
    line-height: 1.1;
    text-align: center;
    /* L'etichetta non deve mai spezzare la barra: con i caratteri ingranditi una parola lunga
       manderebbe a capo tutta la riga e le icone si disallineerebbero. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

/* ── Avvisi (toast) ─────────────────────────────────────────────────────────────────────────────
   Di serie MudBlazor disegna l'avviso come una pastiglia stretta (min 288px, max 500px) appoggiata
   in un angolo. Su un telefono quella misura è quasi mezza riga appesa a sinistra: un oggetto che
   sembra fuori posto, e che con un messaggio lungo — gli errori del server lo sono — va a capo tre
   volte in una colonna sottile. Qui l'avviso prende la riga intera, come una fascia, e sta al
   centro: è la stessa larghezza delle schede che ha sotto, quindi si legge come parte della
   schermata e non come qualcosa che ci è caduto sopra.

   Il raggio è più stretto di quello del tema (16px). Un raggio grande su un oggetto largo e basso
   lo fa sembrare una pillola gonfia; sulle schede, che sono alte, lo stesso raggio invece funziona.

   La posizione la sceglie SnackbarConfiguration in MauiProgram (in alto al centro): qui si
   correggono solo le misure, perché la classe di posizione porta con sé un left:50% e una
   traslazione che a larghezza piena non servono più. */
#mud-snackbar-container {
    /* ⚠️ Vince sulla classe di posizione perché è un selettore di id: la classe resta comunque
       applicata, e senza queste tre righe l'avviso partirebbe da metà schermo. */
    left: 0;
    right: 0;
    transform: none;

    /* Lo stesso margine laterale delle pagine (.vr-pagina): l'avviso si allinea al contenuto
       invece di toccare i bordi dello schermo, dove gli angoli arrotondati lo taglierebbero. */
    padding-left: max(12px, var(--vr-sicura-sinistra));
    padding-right: max(12px, var(--vr-sicura-destra));

    /* ⚠️ L'avviso scende SOTTO la barra in alto, non sopra. Lo z-index degli avvisi è più alto di
       quello della barra: senza questo scarto una fascia larga quanto lo schermo coprirebbe il
       titolo della schermata e il pulsante delle impostazioni.

       Le due misure sono le stesse che usa .vr-con-barra per il contenuto — tacca più altezza della
       barra — così l'avviso si ferma esattamente dove comincia la pagina.

       Lo scarto vale anche dove la barra non c'è (accesso, presentazione): la barra vive dentro un
       layout che nel DOM viene DOPO il contenitore degli avvisi, e da qui non c'è modo di
       accorgersi se sia disegnata. Qualche decina di pixel di aria in più su quelle schermate è un
       prezzo minore di un avviso che, su tutte le altre, copre la barra. */
    top: calc(var(--vr-sicura-alto) + var(--vr-barra-alto) + 8px);
    bottom: auto;
}

.mud-snackbar {
    /* Riga intera: il max-width di MudBlazor è pensato per uno schermo da scrivania. */
    width: 100%;
    max-width: none;
    min-width: 0;
    border-radius: 8px;

    /* Avvisi impilati: 16px fra due fasce larghe è troppo, sembrano due cose scollegate. */
    margin-top: 8px;
}


/* ── Tendine (le combo aperte, i menu) ──────────────────────────────────────────────────────────
   ⚠️ Il tema spegne TUTTE le ombre (vedi SenzaOmbre in TemaAVISNext), e per le schede è la scelta
   giusta: stanno DENTRO la pagina, e a separarle bastano il colore e lo spazio. Una tendina no: è
   un foglio che sta SOPRA la pagina, e con l'ombra spenta restava bianco appoggiato su bianco —
   nello scuro, grigio su grigio. L'elenco non aveva più un contorno e le sue voci sembravano
   scritte dentro la scheda sottostante, che è esattamente il difetto per cui la combo "si
   confondeva con lo sfondo".

   La separazione la fanno DUE cose, e servono entrambe: il bordo, che regge nel tema scuro dove
   un'ombra su fondo scuro non si vede; e l'ombra, che regge nel chiaro dove il bordo da solo è un
   filo grigio chiaro su bianco. Sono le uniche ombre dell'app, e valgono solo per ciò che
   galleggia sopra il contenuto.

   ⚠️ Il selettore ha DUE classi apposta. MudBlazor mette sulla tendina anche .mud-elevation-8, che
   porta l'ombra del tema (cioè "none"): con una classe sola si pareggerebbe la specificità e a
   parità vincerebbe la regola dichiarata dopo, che è la sua. */
.mud-popover.mud-popover-open {
    border: 1px solid var(--mud-palette-lines-default);

    /* Più stretto dei 16px del tema: la tendina esce da un campo squadrato e ne prosegue il bordo.
       Con il raggio delle schede sembrerebbe un oggetto di un'altra famiglia appoggiato lì sopra. */
    border-radius: 12px;

    /* Due ombre e non una: quella larga stacca la tendina dalla pagina, quella stretta le disegna
       sotto un appoggio: con la sola ombra larga il foglio sembra fluttuare senza posarsi.

       ⚠️ È volutamente più marcata di quanto si userebbe altrove. Sotto la tendina c'è quasi sempre
       una scheda BIANCA (nel chiaro) dello stesso colore della tendina stessa: un'ombra discreta lì
       sopra non si vede, ed è il caso peggiore — proprio quello delle impostazioni. */
    box-shadow: 0 10px 28px rgba(0, 0, 0, .22), 0 2px 6px rgba(0, 0, 0, .10);

    /* ⚠️ Le voci hanno un fondo pieno quando sono scelte o toccate, e senza questo taglio quel
       fondo esce dagli angoli arrotondati: la prima e l'ultima voce squadrerebbero la tendina.
       Non tocca lo scorrimento degli elenchi lunghi, che MudBlazor dichiara nello stile in linea
       della tendina (overflow-y) e che quindi vince su questa riga. */
    overflow: hidden;
}

/* ── Guida a fumetti ────────────────────────────────────────────────────────────────────────────
   Il velo che spiega i comandi la prima volta. Tre pezzi: la lastra che intercetta i tocchi, il
   buco sul comando di cui si parla, il fumetto che lo racconta.

   ⚠️ Il buco NON è ritagliato: è un riquadro trasparente con un'ombra grande quanto lo schermo
   tutt'intorno. È il modo di bucare un velo senza SVG e senza quattro rettangoli da far combaciare
   ai bordi — che al primo cambio di misura si scoprono disallineati.

   ⚠️ Lo z-index sta SOPRA gli avvisi (1400), i dialoghi (1300) e la barra di navigazione (1300):
   la guida deve poter parlare della barra, e con un valore più basso finirebbe dietro proprio
   l'oggetto che sta spiegando. */
.guida-blocco {
    position: fixed;
    inset: 0;
    z-index: 2000;
    /* Trasparente ma non inerte: è ciò che impedisce di premere un comando mentre lo si spiega. */
    background: transparent;
}

.guida-velo {
    position: fixed;
    inset: 0;
    z-index: 2001;
    background: rgba(0, 0, 0, .62);
    pointer-events: none;
}

.guida-spot {
    position: fixed;
    z-index: 2001;
    border-radius: 12px;
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, .62);
    /* Il buco non intercetta niente: sotto c'è .guida-blocco, che intercetta tutto. Senza questa
       riga il comando evidenziato resterebbe premibile e si uscirebbe dalla guida a metà. */
    pointer-events: none;
    transition: top var(--vr-durata) var(--vr-curva),
                left var(--vr-durata) var(--vr-curva),
                width var(--vr-durata) var(--vr-curva),
                height var(--vr-durata) var(--vr-curva);
}

.guida-fumetto {
    position: fixed;
    z-index: 2002;
    /* Largo quanto lo schermo meno i margini, e non ancorato all'elemento: su un telefono un
       fumetto stretto quanto un pulsante andrebbe a capo ogni due parole. */
    left: max(12px, var(--vr-sicura-sinistra));
    right: max(12px, var(--vr-sicura-destra));
    padding: 16px;
    border-radius: 12px;
    background-color: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
    box-shadow: 0 10px 28px rgba(0, 0, 0, .3);
    animation: vr-entra var(--vr-durata) var(--vr-curva);
}

.guida-fumetto-testa {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 4px;
}

/* Il contatore dice quanto manca: senza, una guida di cinque passi sembra non finire mai.
   ⚠️ Cifre tabellari e non proporzionali: passando da "1/5" a "2/5" la scritta non deve ballare. */
.guida-contatore {
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-secondary);
}

.guida-fumetto-piede {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
}

/* ── Tesserino ──────────────────────────────────────────────────────────────────────────────────
   ⚠️ NON è più una scheda rossa piena. Lo era, e il rosso pieno litigava con tutto il resto
   dell'app, che è chiara e sobria: il tesserino sembrava incollato sopra un'altra applicazione.
   Adesso la scheda è della stessa materia delle altre — superficie, bordo, raggio — e il primario
   resta come ACCENTO: la banda in alto, il codice, le iniziali. Si nota lo stesso che è la
   schermata principale, ma perché è composta meglio, non perché grida. */

.tesserino {
    position: relative;
    background-color: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 16px;
    overflow: hidden;
}

/* La banda superiore: tre pixel di colore invece di un fondo intero. */
.tesserino::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: linear-gradient(90deg, var(--mud-palette-primary), var(--mud-palette-primary-lighten));
}

/* La fascia del codice, tinta appena: separa l'identità dal codice da mostrare in accettazione. */
.tesserino-codice {
    background-color: rgba(var(--mud-palette-text-secondary-rgb, 113,119,132), .07);
    border-top: 1px solid var(--mud-palette-lines-default);
    margin: 0 -16px -16px;
    padding: 12px 16px;
}

.tesserino-codice-valore {
    font-variant-numeric: tabular-nums;
    letter-spacing: .18rem;
}

/* Il ritratto del tesserino, che è anche il comando per cambiarlo.

   È un <button> e non un <div> con un gestore: così si raggiunge da tastiera e i lettori di
   schermo lo annunciano come qualcosa da premere, che di un ritratto non direbbero mai.
   Le tre righe dopo il display servono a togliergli l'aspetto da pulsante — fondo, bordo e
   imbottitura del sistema — lasciando solo il comportamento. */
.ritratto-donatore {
    position: relative;
    display: block;
    flex: 0 0 auto;
    padding: 0;
    border: 0;
    background: none;
    line-height: 0;
    cursor: pointer;
}

/* Il pallino con la macchina fotografica, appoggiato in basso a destra sul ritratto.

   ⚠️ Ha il bordo del colore della SCHEDA e non del ritratto: è il ritaglio che lo fa leggere come
   un oggetto staccato, appoggiato sopra: senza, la pastiglia colorata e il cerchio della foto si
   toccano e sembrano un unico disegno mal riuscito. */
.ritratto-comando {
    position: absolute;
    right: -2px;
    bottom: -2px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 2px solid var(--mud-palette-surface);
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    line-height: 1;
}

/* ⚠️ L'icona si rimpicciolisce ANCHE se è già "Size.Small": quella misura è pensata per stare in
   riga con del testo, e dentro una pastiglia da 24 pixel la riempirebbe fino ai bordi. */
.ritratto-comando .mud-icon-root {
    font-size: 14px;
}

/* Mentre la foto sale, il ritratto resta fermo ma non risponde: l'attesa la mostra il giro dentro
   la pastiglia. Il ritratto non si sbiadisce tutto — sarebbe la propria faccia che svanisce. */
.ritratto-donatore:disabled {
    cursor: default;
}

.iniziali-donatore {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    flex: 0 0 64px;
    border-radius: 50%;
    /* Tinta del primario invece del primario pieno: l'avatar deve accompagnare il nome, non
       diventare la cosa più vistosa della schermata. */
    background-color: rgba(var(--mud-palette-primary-rgb), var(--vr-tinta));
    color: var(--mud-palette-primary);
    font-size: 1.4rem;
    font-weight: 700;
}

/* Il pulsante delle benemerenze, sotto quello del tesserino digitale.

   ⚠️ È volutamente DIVERSO dal pulsante che gli sta sopra, e la differenza è il punto: sotto un
   pulsante primario pieno, un secondo pulsante primario pieno si legge come la seconda metà dello
   stesso comando. Qui il fondo è dorato e la medaglia sta in una pastiglia in rilievo — il
   riconoscimento si riconosce prima di leggere la parola, e nessuno lo confonde col codice da far
   scansionare in accettazione.

   ⚠️ L'oro è scritto in RGB fisso e non è una variabile della tavolozza: nella tavolozza non c'è,
   e l'unico modo di ottenerlo sarebbe piegare il colore di un'altra cosa. Le opacità sono scelte
   perché il fondo regga sia sulla scheda chiara sia su quella scura, dove la fascia sotto il
   tesserino è già leggermente tinta di suo. */
.benemerenze-comando {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    margin-top: 10px;
    padding: 10px 12px;
    border: 1px solid rgba(197, 154, 42, .5);
    border-radius: 12px;
    background: linear-gradient(135deg, rgba(212, 175, 55, .22), rgba(212, 175, 55, .07));
    color: var(--mud-palette-text-primary);
    font: inherit;
    line-height: 1.25;
    text-align: left;
    cursor: pointer;
}

/* La medaglia: cerchio dorato pieno, come un distintivo appoggiato sul pulsante. Ha misura fissa
   perché i distintivi del catalogo arrivano in proporzioni diverse e senza una cornice comune le
   righe ballerebbero da una sede all'altra. */
.benemerenze-medaglia {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: 0 0 40px;
    border-radius: 50%;
    background: linear-gradient(135deg, rgba(212, 175, 55, .95), rgba(184, 134, 11, .95));
    /* Il marrone scuro invece del bianco: sull'oro il bianco sparisce, questo è il colore che
       hanno le medaglie vere sotto la lucidatura. */
    color: #4a3708;
    line-height: 0;
}

.benemerenze-medaglia .mud-icon-root {
    font-size: 24px;
}

.benemerenze-testo {
    /* Il testo è l'unica parte elastica: medaglia e freccia restano della loro dimensione. */
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
}

.benemerenze-titolo {
    font-weight: 600;
    font-size: .9375rem;
}

/* ⚠️ Il nome VA A CAPO e non viene troncato con i puntini: "Benemerenza d'oro con diamante" è
   lungo di suo, e con i caratteri ingranditi una riga sola lo ridurrebbe a tre parole seguite da
   un troncamento — proprio la cosa che questa riga deve dire. */
.benemerenze-comando .nome-benemerenza {
    font-size: .8125rem;
    color: var(--mud-palette-text-secondary);
}

/* Riquadro di un dato importante (gruppo sanguigno, prossima donazione): icona a sinistra su
   pastiglia tinta, per dare un aggancio visivo senza aggiungere colore di fondo. */
.pastiglia-icona {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    flex: 0 0 44px;
    border-radius: 12px;
    background-color: rgba(var(--mud-palette-primary-rgb), var(--vr-tinta));
    color: var(--mud-palette-primary);
}

/* ── Codice a barre ─────────────────────────────────────────────────────────────────────────── */

.codice-a-barre {
    /* Fondo bianco imposto anche in modalità scura: un codice a barre chiaro su fondo scuro non
       viene letto da nessun lettore, ed è proprio il momento in cui deve funzionare. */
    background-color: #ffffff;
    padding: 16px;
    border-radius: 12px;
    display: inline-block;
}

.codice-a-barre svg {
    display: block;
    /* ⚠️ Larghezza al 100% e altezza automatica: l'SVG nasce con misure in pixel, e su uno schermo
       stretto uscirebbe dal riquadro invece di adattarsi. */
    width: 100%;
    height: auto;
}

/* ── Elenchi ────────────────────────────────────────────────────────────────────────────────── */

.riga-elenco {
    /* L'intera riga è toccabile, non solo il testo: su un elenco di date e descrizioni brevi le
       aree di tocco sarebbero altrimenti minuscole e distanti fra loro. */
    min-height: 64px;
}

/* La freccia di una riga apribile si sposta al tocco: piccolo segnale che si sta entrando. */
.riga-elenco .freccia-riga {
    transition: transform var(--vr-durata) var(--vr-curva);
}

.riga-elenco:active .freccia-riga {
    transform: translateX(3px);
}

/* ── Chat ───────────────────────────────────────────────────────────────────────────────────────
   La schermata è a colonna e occupa tutta l'altezza: la conversazione scorre, la riga di scrittura
   resta ferma in fondo. ⚠️ Non si usa position:fixed per la composizione — con la tastiera aperta
   su iOS resterebbe sotto di essa, che è esattamente il momento in cui serve vederla. */

/*
   ⚠️ La chat si ANCORA fra le due barre invece di calcolarsi un'altezza.

   Prima sottraeva dall'altezza dello schermo la barra in alto, quella in fondo, le aree di
   sicurezza e l'imbottitura del contenitore: cinque misure, e bastava che una non corrispondesse —
   l'imbottitura del contenitore di pagina, per dirne una — perché la casella di scrittura restasse
   sospesa a mezz'aria sopra la barra di navigazione. Ancorandola a `top` e `bottom` non c'è niente
   da sommare: la casella sta esattamente sopra la barra, per costruzione.

   Il prezzo è che questa schermata esce dal flusso della pagina. Va bene proprio per la chat, che
   occupa comunque tutto lo schermo e non scorre insieme al resto.
*/
.chat-schermata {
    position: fixed;
    top: calc(var(--vr-barra-alto) + var(--vr-sicura-alto));
    /* Il fondo sta sopra la barra di navigazione, oppure sopra la TASTIERA quando è aperta —
       vince il più alto dei due. Con la tastiera su, la barra di navigazione le sta dietro e non
       c'è motivo di lasciarle spazio; senza, la tastiera vale zero e resta la barra. */
    bottom: max(calc(var(--vr-barra-navigazione) + var(--vr-sicura-basso)), var(--vr-tastiera, 0px));
    left: 0;
    right: 0;
    display: flex;
    flex-direction: column;
    background-color: var(--mud-palette-background);
    min-height: 0;
    /* ⚠️ Nessuna imbottitura laterale QUI: ce l'aveva, e lasciava due strisce di fondo ai lati
       della casella di scrittura, come se non arrivasse ai bordi. Lo spazio serve ai messaggi, non
       alla barra di scrittura, che deve andare da un bordo all'altro: quindi lo mette ciascuno dei
       due per conto suo, qui sotto. */
}

/*
   ⚠️ La conversazione scorre DENTRO di sé, e la casella di scrittura non si muove.

   Prima non era così: il componente Contenuto avvolge quello che gli si passa in un <div> normale,
   che quindi si dimensionava sul suo contenuto. Con pochi messaggi quel div era alto poche
   centinaia di pixel e la casella di scrittura lo seguiva, comparendo a metà schermo come se fosse
   l'ultimo messaggio. Il primo figlio deve prendersi lo spazio che avanza — qualunque dei quattro
   stati stia mostrando — e scorrere al suo interno.
*/
.chat-schermata > :first-child {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    /* ⚠️ L'ancoraggio automatico del browser va SPENTO, e non è una micro-ottimizzazione.

       Chromium, aggiungendo contenuto sopra a quello che si sta guardando, sposta lo scorrimento
       da sé per non far saltare la vista; Safari non lo fa. Con il rimedio nostro attivo su
       entrambi (vedi conservaPosizione in index.html), su Android le due correzioni si SOMMANO e
       la conversazione salta in avanti di una pagina intera — misurato: caricando tre messaggi
       precedenti si passava dal messaggio 3 al messaggio 6, cioè si scavalcava proprio quello che
       il donatore stava leggendo. Spento qui, le due piattaforme si comportano allo stesso modo e
       la correzione è una sola. */
    overflow-anchor: none;
    -webkit-overflow-scrolling: touch;
    /* Lo spazio laterale sta sui messaggi, non sul contenitore: così le bolle respirano e la
       barra di scrittura arriva comunque ai bordi. */
    padding-left: max(12px, var(--vr-sicura-sinistra));
    padding-right: max(12px, var(--vr-sicura-destra));
}

/* Il velo dell'apertura.

   ⚠️ Sta SOPRA la conversazione invece di sostituirla, ed è tutto il punto: le immagini se le
   scarica ogni bolla per conto proprio, e una bolla non disegnata non scarica niente. Quindi la
   conversazione si disegna, lavora coperta, e si scopre quando è completa e ferma sull'ultimo
   messaggio (vedi AttendiConversazione in Chat.razor). Il fondo è quello della pagina: sotto non
   si deve intravedere niente che si muove.

   L'imbottitura ricalca quella del contenitore che scorre, così il segnaposto che ci sta dentro
   cade esattamente dove cadeva un attimo prima: fra l'attesa e la conversazione non si vede un
   salto.

   ⚠️ La casella di scrittura resta SOPRA il velo: coprirla vorrebbe dire impedire di scrivere
   mentre si carica una foto di due mesi fa, che non è quello che si sta cercando di evitare. */
.chat-velo {
    position: absolute;
    inset: 0;
    z-index: 1;
    overflow: hidden;
    background-color: var(--mud-palette-background);
    padding: 8px max(12px, var(--vr-sicura-destra)) 0 max(12px, var(--vr-sicura-sinistra));
}

/* La casella di scrittura non si restringe mai: è l'unica cosa che deve restare raggiungibile. */
.chat-composizione,
.chat-chiusa {
    flex: 0 0 auto;
    /* Sopra il velo dell'apertura: vedi la nota su .chat-velo. */
    position: relative;
    z-index: 2;
}

.chat-conversazione {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 8px 4px 12px;
}

.chat-giorno {
    display: flex;
    justify-content: center;
    margin: 12px 0 6px;
}

.chat-giorno span {
    font-size: .72rem;
    color: var(--mud-palette-text-secondary);
    background-color: rgba(var(--mud-palette-text-secondary-rgb, 113,119,132), .10);
    border-radius: 20px;
    padding: 3px 12px;
}

/*
   Il divisore dei messaggi nuovi.

   ⚠️ Deliberatamente DIVERSO dal separatore di giornata: quello è una pastiglia grigia in mezzo
   alla colonna, questo è una riga colorata che taglia la conversazione da parte a parte. Fatti
   uguali, a colpo d'occhio si leggerebbero come due date, e il confine — che è l'unica cosa che il
   donatore cerca riaprendo la chat — si perderebbe fra gli "Oggi" e gli "Ieri".
*/
.chat-nuovi {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 14px 0 6px;
}

.chat-nuovi::before,
.chat-nuovi::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background-color: rgba(var(--mud-palette-primary-rgb), .35);
}

.chat-nuovi span {
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--mud-palette-primary);
    /* Non va mai a capo: spezzata su due righe smetterebbe di leggersi come un'etichetta sulla
       linea e diventerebbe un blocco di testo in mezzo ai messaggi. */
    white-space: nowrap;
}

.chat-bolla-riga { display: flex; }
.chat-bolla-riga.mia { justify-content: flex-end; }
.chat-bolla-riga.loro { justify-content: flex-start; }

.chat-bolla {
    /* Non oltre l'85%: una bolla che tocca entrambi i bordi non si distingue più da un blocco di
       testo, e si perde il colpo d'occhio su chi ha detto cosa. */
    max-width: 85%;
    border-radius: 16px;
    padding: 8px 12px 5px;
    background-color: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
}

/* I propri messaggi sulla tinta del primario, non sul primario pieno: il primario pieno ripetuto su
   ogni bolla trasformerebbe la conversazione in un muro di colore. */
.chat-bolla-riga.mia .chat-bolla {
    background-color: rgba(var(--mud-palette-primary-rgb), var(--vr-tinta));
    border-color: rgba(var(--mud-palette-primary-rgb), var(--vr-tinta-forte));
    border-bottom-right-radius: 5px;
}

.chat-bolla-riga.loro .chat-bolla { border-bottom-left-radius: 5px; }

.chat-testo { white-space: pre-wrap; word-break: break-word; line-height: 1.4; }

/* ── La bolla di una convocazione ────────────────────────────────────────────────────────────
   Deve essere riconoscibile PRIMA di essere letta: è l'unico messaggio che chiede di fare
   qualcosa, e in una conversazione lunga uno che la scorre deve accorgersene senza fermarsi.
   Il colore è il primario — lo stesso di tutte le azioni dell'app — perché una convocazione È
   un'azione, e inventarle una tinta sua avrebbe aggiunto un significato in più da imparare.

   ⚠️ Più larga delle altre (95% invece di 85%): dentro ci sono quattro righe di dati e un
   pulsante, e a 85% il nome di un punto di prelievo andava a capo due volte. */
.chat-bolla.chat-convocazione {
    max-width: 95%;
    padding: 0 0 5px;
    background-color: rgba(var(--mud-palette-primary-rgb), var(--vr-tinta));
    border-color: rgba(var(--mud-palette-primary-rgb), var(--vr-tinta-forte));
}

/* Il testo del template e il piede recuperano il margine che la bolla ha ceduto alla fascia. */
.chat-bolla.chat-convocazione > .chat-testo,
.chat-bolla.chat-convocazione > .chat-piede,
.chat-bolla.chat-convocazione > .mud-button-root { margin-left: 12px; margin-right: 12px; }

.chat-convocazione-fascia {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    margin-bottom: 7px;
    /* Gli angoli superiori seguono quelli della bolla, meno il bordo: una fascia squadrata dentro
       un riquadro tondo si vede come un errore di disegno. */
    border-radius: 15px 15px 0 0;
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .02em;
}

.chat-convocazione-dati {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin: 8px 12px 0;
    padding-top: 8px;
    /* Una riga sottile invece di un riquadro dentro il riquadro: i dati sono la stessa cosa che il
       testo dice a parole, non un allegato. */
    border-top: 1px solid rgba(var(--mud-palette-primary-rgb), var(--vr-tinta-forte));
    font-size: .84rem;
}

.chat-convocazione-riga { display: flex; align-items: center; gap: 7px; }
.chat-convocazione-riga .mud-icon-root { font-size: 16px !important; opacity: .75; }

/* Prima riga della data con l'iniziale maiuscola: "sabato 23 settembre" scritto minuscolo dentro
   un riquadro sembra un frammento, non una data. */
.chat-convocazione-riga:first-child span { text-transform: capitalize; font-weight: 600; }

.chat-convocazione-riga.liberi { color: var(--mud-palette-success); }
.chat-convocazione-riga.esaurita { color: var(--mud-palette-warning); }
.chat-convocazione-riga.scaduta { color: var(--mud-palette-text-secondary); }
.chat-convocazione-riga.liberi .mud-icon-root,
.chat-convocazione-riga.esaurita .mud-icon-root,
.chat-convocazione-riga.scaduta .mud-icon-root { opacity: 1; }

.chat-piede {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 4px;
    margin-top: 2px;
    font-size: .68rem;
    color: var(--mud-palette-text-secondary);
}

.chat-spunta { font-size: 14px !important; }
.chat-spunta.letta { color: var(--mud-palette-info); }

.chat-allegato {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 7px 9px;
    margin-bottom: 5px;
    border-radius: 10px;
    background-color: rgba(var(--mud-palette-text-secondary-rgb, 113,119,132), .09);
    color: inherit;
    text-decoration: none;
    font-size: .84rem;
}

.chat-allegato-nome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-allegato-peso { color: var(--mud-palette-text-secondary); font-size: .74rem; white-space: nowrap; }

/* Il richiamo dei messaggi arrivati mentre si guardava piu' su.

   Sta SOPRA la casella di scrittura e non sospeso in mezzo alla conversazione: lì coprirebbe un
   messaggio, e quello coperto sarebbe proprio uno degli ultimi. */
.chat-richiamo {
    display: flex;
    justify-content: center;
    padding: 6px 8px 0;
    flex: 0 0 auto;
}

/* L'anteprima di un'immagine allegata.

   ⚠️ L'altezza è limitata e non libera: una foto verticale scattata col telefono, mostrata alla
   sua proporzione, riempirebbe da sola tutto lo schermo e spingerebbe fuori i messaggi intorno.
   Con un tetto si vede che c'è e che cosa raffigura, e si apre a schermo intero toccandola. */
.chat-immagine {
    display: block;
    max-width: 100%;
    max-height: 260px;
    border-radius: 10px;
    margin-bottom: 4px;
    object-fit: cover;
    background-color: rgba(var(--mud-palette-text-secondary-rgb, 113,119,132), .08);
}

/* Il posto dell'immagine mentre si sta scaricando: tiene lo spazio, così la conversazione non
   sussulta quando l'immagine arriva. */
.chat-immagine-attesa {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 200px;
    height: 140px;
    border-radius: 10px;
    margin-bottom: 4px;
    background-color: rgba(var(--mud-palette-text-secondary-rgb, 113,119,132), .08);
}

.chat-composizione {
    /* Da bordo a bordo, con la sola area di sicurezza a proteggere gli angoli in orizzontale. */
    padding: 8px max(8px, var(--vr-sicura-destra)) 8px max(8px, var(--vr-sicura-sinistra));
    border-top: 1px solid var(--mud-palette-lines-default);
    background-color: var(--mud-palette-surface);
}

.chat-allegato-scelto {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 5px 8px;
    margin-bottom: 6px;
    border-radius: 9px;
    background-color: rgba(var(--mud-palette-primary-rgb), var(--vr-tinta));
}

.chat-chiusa {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 12px;
    border-top: 1px solid var(--mud-palette-lines-default);
    color: var(--mud-palette-text-secondary);
    text-align: center;
}

/* La voce del menu su cui ci si trova già. */
.voce-menu-corrente {
    background-color: rgba(var(--mud-palette-primary-rgb), .07);
}

/* Le schermate prima dell'accesso non hanno la barra in alto: MudBlazor lascia comunque il suo
   spazio, ma qui serve un po' di respiro in più e soprattutto l'area di sicurezza superiore, che
   senza barra non la mette nessuno. */
.vr-accesso {
    padding-top: calc(var(--vr-imbottitura-pagina) + 8px);
}

/* ── "Non ho ricevuto il codice" ───────────────────────────────────────────────────────────────
   Un blocco solo, staccato dal resto da una riga sottile: prima erano una frase e un pulsante
   larghi quanto la schermata, appoggiati sotto la conferma senza niente a dire che fossero la
   stessa cosa — e il pulsante di testo grande quanto quello principale se lo prendeva in pieno. */
.reinvio-codice {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    margin-top: 24px;
    padding-top: 16px;
    border-top: 1px solid var(--mud-palette-lines-default);
}

/* ⚠️ I secondi che restano hanno una larghezza FISSA e le cifre tabellari. Il conto alla rovescia
   cambia una volta al secondo e passa da due cifre a una: senza queste due righe l'etichetta si
   accorcia sotto il dito e il pulsante balla per tutta l'attesa. */
.reinvio-attesa {
    display: inline-block;
    /* Quanto basta per "30 s": due cifre, lo spazio e l'unità. Sotto questa misura il pulsante si
       accorcia da solo quando i secondi scendono sotto il dieci. */
    min-width: 3.4ch;
    /* A destra così l'unità resta ferma e a muoversi è il numero, che è la parte che cambia. */
    text-align: right;
    margin-left: 6px;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-secondary);
}

.reinvio-attesa::after {
    /* L'unità sta nel CSS e non nella traduzione: "s" è la stessa in tutte le lingue dell'app, e
       nel testo tradotto diventerebbe un pezzo di frase che qualcuno prima o poi declina. */
    content: " s";
}

/* ── Segnaposto di caricamento ─────────────────────────────────────────────────────────────────
   ⚠️ Sono RETTANGOLI e non "testo", e non è un dettaglio: MudBlazor applica ai segnaposto di tipo
   testo un `transform: scale(1, 0.6)` — è il suo modo di far sembrare una riga scritta — e quel
   tipo è il predefinito. Con un'altezza dichiarata se ne vedeva il 60%, e tutti i segnaposto
   risultavano schiacciati in verticale. I rettangoli l'altezza la rispettano.

   Gli angoli arrotondati qui: senza, un rettangolo pieno accanto a schede tutte smussate stona. */
/* ⚠️ Il rettangolo non aggiunge nessuna classe propria: si riconosce per esclusione. */
/*
   ⚠️ Il raggio passa da una VARIABILE con un ripiego, e non è un giro inutile.

   Alcuni segnaposto devono smussarsi come la cosa che stanno imitando — un campo di testo a 16px
   come il tema, la pastiglia della data tonda, l'anteprima di una foto a 10 — e per ottenerlo
   scrivendo un'altra regola bisognerebbe VINCERE su questa: fra i due :not() e la classe, qui la
   specificità è di tre classi, mentre un `.mud-skeleton.scheletro-campo` ne vale due e perderebbe
   comunque, scritto sopra o sotto che sia. Si finirebbe a rincorrere con !important o con
   selettori sempre più lunghi.

   Le variabili non hanno questo problema: si ereditano dall'elemento, e chi vuole un raggio suo lo
   dichiara e basta (vedi il blocco più in basso). Chi non dichiara niente prende i 6px.
*/
.mud-skeleton:not(.mud-skeleton-text):not(.mud-skeleton-circle) {
    border-radius: var(--vr-raggio-segnaposto, 6px);
}

/* ── Segnaposto del modulo di accesso ──────────────────────────────────────────────────────────
   I campi e il pulsante disegnati in grigio mentre il server dice se il rientro rapido vale
   ancora. Vedi la nota estesa in Accesso.razor. */

/* Lo stesso raggio del tema (DefaultBorderRadius, 16px): un campo finto squadrato accanto a campi
   veri tutti smussati si vede cambiare forma sotto gli occhi. */
.scheletro-campo,
.scheletro-pulsante {
    --vr-raggio-segnaposto: 16px;
}

/* ⚠️ Il pulsante "Entra" è sulla tinta del primario e non grigio come il resto: è l'unico elemento
   colorato del modulo, e in grigio l'attesa sembra una schermata disattivata invece che una
   schermata in arrivo.

   ⚠️ Il colore si cambia, l'animazione no: MudBlazor fa pulsare i segnaposto muovendo l'OPACITÀ e
   non lo sfondo, quindi una tinta propria continua a respirare come tutte le altre. */
.mud-skeleton.scheletro-pulsante {
    background-color: rgba(var(--mud-palette-primary-rgb), var(--vr-tinta-forte));
}

/* La riga di un collegamento di testo: alta quanto il pulsante vero (36px), con dentro un riquadro
   alto quanto la sola scritta. Vedi la nota in Accesso.razor. */
.scheletro-collegamento {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 36px;
}

/* ── Segnaposto della conversazione ────────────────────────────────────────────────────────────
   Le bolle finte della chat. La forma gliela danno le classi VERE della chat (.chat-bolla e
   compagne, più in alto): qui c'è solo quello che riguarda i riquadri grigi che stanno dentro. */

/* La pastiglia della data: tonda come quella vera (.chat-giorno span), non un rettangolo smussato. */
.scheletro-giorno {
    --vr-raggio-segnaposto: 20px;
}

/* ⚠️ 14px di riquadro più 8px di stacco fanno i 22px che una riga di testo occupa davvero
   (interlinea 1.4 su un corpo da 16px, vedi .chat-testo). Con misure a occhio la bolla finta
   risultava più bassa di quella vera, e la conversazione arrivando si allungava tutta insieme.
   Lo stacco resta anche sull'ULTIMA riga: è lo spazio che la separa dall'ora. */
.scheletro-riga {
    margin-bottom: 8px;
}

/* Lo stesso posto, e lo stesso raggio, dell'anteprima di una foto (.chat-immagine). */
.scheletro-immagine {
    --vr-raggio-segnaposto: 10px;
    margin-bottom: 4px;
}

/* ⚠️ Il piede della bolla finta non si dimensiona da sé: dentro ci sono riquadri alti 10px, mentre
   l'ora vera si porta dietro la propria interlinea (.68rem, ~15px). Senza questa altezza ogni
   bolla sarebbe cinque pixel più bassa del dovuto — poco su una, visibile su sei. */
.chat-bolla .chat-piede {
    min-height: 15px;
}

/* Fondo pagina comodo: sopra la barra gestuale e fuori dalla presa della mano.

   ⚠️ La misura non è fissa. L'area di sicurezza in basso vale una trentina di pixel su un iPhone
   recente e zero su un telefono con i tasti: sommarci sempre lo stesso numero darebbe un vuoto
   esagerato su metà dei dispositivi e nessuno spazio sull'altra metà. */
.vr-fondo-comodo {
    padding-bottom: calc(24px + var(--vr-sicura-basso));
}

/* Una riga "etichetta / valore" che porta a un'altra pagina. Deve restare identica alle altre
   righe della scheda — cambia solo la freccia — altrimenti la scheda sembra fatta di due tipi di
   contenuto invece che di uno solo. */
.voce-premibile {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
}

.voce-premibile .voce-corpo { flex: 1 1 auto; min-width: 0; }

/* Il richiamo per i messaggi più vecchi, in cima alla conversazione. Tondo come una pillola e non
   squadrato: sta in mezzo alle bolle, e un rettangolo con il bordo sembrerebbe un messaggio. */
.chat-precedenti {
    border-radius: 999px;
}

/* Il pallino di "non ancora aperta", sulle righe dell'elenco delle presentazioni.

   ⚠️ Ha una dimensione FISSA in px e non in em: deve restare un punto anche quando il donatore
   sceglie i caratteri molto grandi, altrimenti a fianco di un testo ingrandito diventa una palla
   che sembra un pulsante. */
.pallino-novita {
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: var(--mud-palette-primary);
}

/* Il QR del tesserino. ⚠️ Ha un TETTO di larghezza e non prende tutta la riga come le barre: è
   quadrato, quindi a larghezza piena diventerebbe alto quanto mezzo schermo e il telefono andrebbe
   allontanato dal lettore invece che avvicinato. 260px è grande abbastanza da leggersi da vicino. */
.codice-qr {
    width: 100%;
    max-width: 260px;
    margin-left: auto;
    margin-right: auto;
}
