/* ==========================================================================
   PlayRustLegacy — design system
   ==========================================================================

   Stile: terminale industriale scuro. La scelta viene dal soggetto — un
   archivio di un gioco del 2013 mantenuto in vita — piu' che dal gusto: un
   registro tecnico, monospaziato e numerato, dice "questa cosa e' tenuta in
   funzione da qualcuno" meglio di una grafica levigata.

   TIPOGRAFIA: font di sistema, nessun webfont.
   Non e' una scorciatoia. Un webfont da Google Fonts significa una richiesta a
   un terzo host, che la CSP di questo sito vieta di proposito, e un testo
   invisibile per i primi 200 ms su una connessione lenta. Gli stack monospaziati
   di sistema (SF Mono, Consolas, DejaVu Sans Mono) sono buoni e arrivano in zero
   millisecondi. Se un giorno servisse un carattere proprio, va ospitato in
   public/css/ e aggiunto a font-src in vercel.json — non caricato da un CDN.

   MODALITA' CHIARA: assente, deliberatamente.
   Il tema e' un'unica scelta scura. Non e' una svista da correggere con una
   media query: un archivio di Rust Legacy in tema chiaro non ha senso visivo, e
   mantenere due palette per un sito di cinque pagine sarebbe lavoro che nessuno
   guarda. La conseguenza va detta: chi ha impostato "chiaro" nel sistema vede
   comunque scuro. color-scheme: dark lo dichiara al browser, cosi' almeno i
   controlli nativi (barre di scorrimento, campi) si adeguano invece di stonare.
   ========================================================================== */

:root {
  color-scheme: dark;

  /* --- colori ------------------------------------------------------------
     LA PALETTE VIENE DAL LOGO, non da un accostamento scelto a parte.
     I tre colori sono quelli che si contano nei pixel di img/site-logo.webp:

       #CD412B   il rosso ruggine del marchio          27% dei pixel opachi
       #A4A6A7   il grigio argento del lettering       62%
       #1E2020   il nero verdastro del fondo            5%

     Quel nero non e' un grigio neutro: ha una tinta ciano (H=180) e una
     saturazione bassa ma non nulla. I fondi e i bordi qui sotto sono costruiti
     su quella stessa tinta, e i grigi del testo su quella del lettering
     (H=200). E' il motivo per cui la pagina sembra lo stesso oggetto del logo:
     conta piu' la tinta dei grigi che il rosso, che si vede in poche aree.
     Chi li ricalcola: build/contrasti.py, che stampa anche i contrasti.

     QUEL ROSSO NON PUO' ESSERE USATO PER IL TESTO, e la ragione va scritta
     qui perche' altrimenti qualcuno lo "correggera'" tornando al colore di
     marca. Su fondo #0B0B0B da 4.11:1, sotto la soglia di 4.5:1 che WCAG
     chiede per il testo normale. Quindi i rossi sono due, con compiti diversi:

       --rust        #CD412B   4.11:1  riempimenti, bordi, aree piene. Come
                                       fondo di un pulsante con testo bianco
                                       sopra da 4.79:1, che e' conforme:
                                       la coppia va letta nel verso giusto.
       --rust-chiaro #FB6F59   7.05:1  tutto il testo rosso, i link, le icone.
                                       AAA anche per il corpo piccolo. E' il
                                       rosso del logo schiarito mantenendone
                                       tinta (H=8.1) e saturazione: un rosso
                                       piu' spento diventerebbe rosa e
                                       perderebbe il carattere del marchio.

     Gli altri, sul fondo #0B0B0B:
       --testo       #FFFFFF  19.7:1  bianco pieno
       --testo-2     #B9BBBB  10.2:1  (AAA)
       --testo-3     #939697   6.6:1  (AA per il testo normale)
       --argento     #A4A6A7   8.1:1  il grigio del logo tale e quale, per i
                                       pochi punti che devono richiamarlo

     Il rosso non e' mai l'unico segnale: ogni stato porta anche un'icona e una
     parola, perche' circa un uomo su dodici non distingue il rosso dal verde.
     Qui conta il doppio, perche' rosso e' insieme il colore del marchio e
     quello dell'errore: senza la parola accanto, un bordo rosso e' ambiguo
     anche per chi i colori li vede benissimo. */
  --fondo: #0B0B0B;
  --fondo-2: #111212;
  --fondo-3: #191B1B;
  /* Il nero del logo tale e quale: e' la superficie piu' sollevata, cosi' il
     colore del marchio compare *dentro* la pagina invece di esserne il fondo,
     dove sarebbe indistinguibile da un nero qualunque. */
  --fondo-4: #1E2020;

  --testo: #FFFFFF;
  --testo-2: #B9BBBB;
  --testo-3: #939697;
  --argento: #A4A6A7;

  --rust: #CD412B;
  --rust-chiaro: #FB6F59;
  --rust-scuro: #2B100A;
  /* Sul rosso pieno va il bianco, non il nero: 4.79:1 contro 3.42:1. */
  --su-rust: #FFFFFF;

  /* Verde solo per lo stato "server attivo". Non e' un colore del marchio e non
     compare altrove: qui serve perche' rosso e' gia' occupato dall'identita',
     e usarlo anche per "attivo" renderebbe indistinguibili acceso e spento. */
  --verde: #3DDC7F;
  --verde-scuro: #0E2A18;

  /* Ambra: come il verde, un segnale funzionale e non un colore del marchio.
     Serve per gli avvisi che non sono errori — "il sistema mostrera' una
     schermata di sicurezza", "questa azione ti disconnette" — che in rosso
     leggerebbero come guasti e in bianco non si noterebbero affatto.
     9.44:1 su #0B0B0B. */
  --ambra: #F0B429;
  /* L'errore riusa il rosso chiaro: due rossi diversi per marchio ed errore
     sarebbero indistinguibili a occhio e darebbero solo l'illusione di una
     distinzione. Sono la parola e l'icona a dire di quale dei due si tratta. */
  --rosso: var(--rust-chiaro);
  --rosso-scuro: #2B100A;

  /* Anche i bordi stanno sulla tinta del nero del logo: un bordo grigio neutro
     accanto a un fondo che tende al ciano si legge come una riga sporca. */
  --bordo: #242626;
  --bordo-2: #333636;

  /* --- tipografia -------------------------------------------------------- */
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
    "DejaVu Sans Mono", monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, sans-serif;

  /* Scala tipografica. I salti sono ampi di proposito: in uno stile brutalista
     la gerarchia la fa la dimensione, non il peso o il colore. */
  --t-xs: 0.6875rem;  /* 11px — solo etichette maiuscole, mai testo corrente */
  --t-sm: 0.8125rem;  /* 13px */
  --t-base: 1rem;     /* 16px — minimo per il testo corrente: sotto, iOS
                         ingrandisce da se' i campi al primo tocco */
  --t-lg: 1.125rem;
  --t-xl: 1.5rem;
  --t-2xl: 2rem;
  --t-3xl: 2.75rem;
  --t-4xl: 4rem;

  /* --- spaziatura: scala da 4px ------------------------------------------ */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;
  --s-8: 4rem;
  --s-9: 6rem;

  /* --- struttura --------------------------------------------------------- */
  --larghezza: 1200px;
  --raggio: 2px;      /* quasi nullo: e' la cifra dello stile */
  --bordo-largo: 1px;

  /* --- movimento ---------------------------------------------------------
     150-200 ms: sopra i 300 ms un'interfaccia sembra lenta, sotto i 100 ms il
     cambiamento non si legge come transizione. */
  --t-rapida: 150ms;
  --t-media: 200ms;
  --curva: cubic-bezier(0.4, 0, 0.2, 1);

  /* --- livelli ----------------------------------------------------------- */
  --z-barra: 100;
  --z-menu: 200;
  --z-avviso: 300;
}

/* ==========================================================================
   Azzeramento
   ========================================================================== */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* La barra in alto e' fissa: senza questo, un'ancora porterebbe il titolo
     della sezione sotto la barra, invisibile. */
  scroll-padding-top: 5rem;
}

body {
  background: var(--fondo);
  color: var(--testo);
  font-family: var(--sans);
  font-size: var(--t-base);
  line-height: 1.6;
  min-height: 100dvh;
  /* Trama a puntini: due gradienti, nessuna immagine da scaricare. Molto
     tenue — a piena opacita' competerebbe col testo. */
  background-image:
    radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.025) 1px, transparent 0);
  background-size: 32px 32px;
}

img, svg { display: block; max-width: 100%; height: auto; }

button, input, textarea, select { font: inherit; color: inherit; }

a { color: inherit; text-decoration: none; }

/* Un collegamento in mezzo a un paragrafo deve distinguersi dal testo, e non
   basta il colore: circa un uomo su dodici non distingue il rosso, quindi la
   sottolineatura non e' decorazione ma il secondo segnale. Resta staccata dal
   testo — underline-offset — perche' attaccata rende illeggibili le lettere che
   scendono sotto la riga. */
.link-rosso {
  color: var(--rust-chiaro);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color var(--t-rapida) var(--curva);
}
.link-rosso:hover { color: var(--testo); }

/* ==========================================================================
   Accessibilita' trasversale
   ========================================================================== */

/* Anello di messa a fuoco visibile su tutto cio' che si puo' raggiungere da
   tastiera. :focus-visible e non :focus, cosi' non compare al clic del mouse
   dove non serve. Non va mai rimosso: chi naviga da tastiera perderebbe
   qualunque riferimento su dove si trova. */
:focus-visible {
  outline: 2px solid var(--rust-chiaro);
  outline-offset: 2px;
  border-radius: var(--raggio);
}

/* Chi ha chiesto meno movimento nelle impostazioni di sistema lo ottiene: le
   animazioni non vengono accorciate, vengono annullate. 0.01ms invece di 0
   perche' un evento di fine transizione deve comunque scattare, altrimenti il
   codice che lo attende resta appeso. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Visibile solo ai lettori di schermo. Il ritaglio a 1px invece di
   display:none e' necessario: un elemento nascosto del tutto viene escluso
   dall'albero di accessibilita' e non verrebbe letto. */
.sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Salta al contenuto: primo elemento raggiungibile con Tab. Fuori schermo
   finche' non riceve la messa a fuoco. */
.salta {
  position: absolute;
  top: -100%;
  left: var(--s-4);
  z-index: calc(var(--z-barra) + 1);
  padding: var(--s-3) var(--s-4);
  background: var(--rust);
  color: var(--su-rust);
  font-family: var(--mono);
  font-size: var(--t-sm);
  font-weight: 700;
  text-transform: uppercase;
}
.salta:focus { top: var(--s-4); }

/* ==========================================================================
   Struttura
   ========================================================================== */

.contenitore {
  width: 100%;
  max-width: var(--larghezza);
  margin-inline: auto;
  /* Margini laterali che crescono col viewport: su 375px 20px bastano, su
     desktop uno spazio piu' ampio evita che il testo tocchi il bordo. */
  padding-inline: var(--s-5);
}

@media (min-width: 768px) {
  .contenitore { padding-inline: var(--s-6); }
}

.sezione {
  padding-block: var(--s-8);
  border-top: var(--bordo-largo) solid var(--bordo);
}

@media (min-width: 768px) {
  .sezione { padding-block: var(--s-9); }
}

/* ==========================================================================
   Tipografia
   ========================================================================== */

.titolo-sezione {
  font-family: var(--mono);
  font-size: clamp(var(--t-2xl), 5vw, var(--t-3xl));
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}

/* Etichetta numerata sopra ogni sezione: 01 // IL PROGETTO.
   Il numero non e' decorazione — dice al lettore quanto e' lunga la pagina e
   dove si trova, che in uno scorrimento unico e' l'unico orientamento. */
.etichetta {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-4);
  color: var(--rust-chiaro);
  font-family: var(--mono);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.etichetta::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(to right, var(--bordo-2), transparent);
}

.sottotitolo {
  max-width: 62ch;  /* 60-75 caratteri: oltre, l'occhio perde la riga al ritorno */
  margin-top: var(--s-4);
  color: var(--testo-2);
  font-size: var(--t-lg);
}

.mono { font-family: var(--mono); }

/* Numeri incolonnati: le cifre tabulari hanno tutte la stessa larghezza, quindi
   un contatore che passa da 9 a 10 non fa sobbalzare cio' che gli sta accanto. */
.cifre { font-variant-numeric: tabular-nums; }

/* ==========================================================================
   Pulsanti
   ========================================================================== */

.pulsante {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  /* 44px di altezza minima: e' la soglia sotto la quale un bersaglio diventa
     difficile da centrare col pollice (Apple HIG; Material dice 48dp). */
  min-height: 44px;
  padding: var(--s-3) var(--s-5);
  border: var(--bordo-largo) solid transparent;
  border-radius: var(--raggio);
  background: none;
  cursor: pointer;
  font-family: var(--mono);
  font-size: var(--t-sm);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: center;
  transition: background var(--t-rapida) var(--curva),
              border-color var(--t-rapida) var(--curva),
              color var(--t-rapida) var(--curva),
              transform var(--t-rapida) var(--curva);
}

/* Un solo pulsante primario per schermata: se tutto e' primario, niente lo e'.
   Fondo rosso di marca con testo bianco: 4.73:1, conforme. Al contrario —
   rosso chiaro sotto testo nero — sarebbe piu' brillante ma leggerebbe come un
   avviso, e su un pulsante d'azione e' il segnale sbagliato. */
.pulsante-primario {
  background: var(--rust);
  border-color: var(--rust);
  color: var(--su-rust);
}
.pulsante-primario:hover:not(:disabled) {
  /* Si scurisce invece di schiarire, e non e' un vezzo: il bianco sopra deve
     restare conforme anche in hover, e schiarendo il rosso scenderebbe sotto
     la soglia. #B8391F col bianco da 5.76:1 — il cambiamento si vede e il
     contrasto sale invece di calare. */
  background: #B8391F;
  border-color: #B8391F;
}

.pulsante-secondario {
  border-color: var(--bordo-2);
  color: var(--testo);
}
.pulsante-secondario:hover:not(:disabled) {
  border-color: var(--rust);
  color: var(--rust-chiaro);
  background: rgba(205, 65, 43, 0.1);
}

.pulsante-fantasma {
  color: var(--testo-2);
  padding-inline: var(--s-3);
}
.pulsante-fantasma:hover:not(:disabled) { color: var(--testo); }

/* L'unica azione irreversibile del sito: eliminare l'account. Ha un aspetto
   proprio perche' non deve poter essere confusa con «salva» — il contorno rosso
   la distingue anche a colpo d'occhio, prima di leggere l'etichetta.

   Contorno e non fondo pieno: un fondo rosso sarebbe l'elemento piu' acceso
   della pagina e attirerebbe il clic invece di respingerlo. Il pieno arriva solo
   al passaggio del puntatore, cioe' quando l'intenzione c'e' gia'. */
.pulsante-pericolo {
  border-color: var(--rosso);
  color: var(--rosso);
}
.pulsante-pericolo:hover:not(:disabled) {
  background: var(--rosso);
  border-color: var(--rosso);
  /* Il fondo della pagina sopra il rosso chiaro: 7.05:1. Il bianco sullo stesso
     fondo darebbe 2.68:1, molto sotto la soglia — e' il rovescio del pulsante
     primario, dove il rosso e' scuro e il bianco e' la scelta giusta. */
  color: var(--fondo);
}

/* Pressione: uno spostamento di 1px, non uno schiacciamento in scala.
   translateY non altera lo spazio occupato, quindi non muove nulla intorno; una
   scala su un pulsante dentro una riga farebbe respirare la riga intera. */
.pulsante:active:not(:disabled) { transform: translateY(1px); }

/* Disabilitato: opacita' ridotta *e* cursore diverso *e* attributo disabled.
   L'opacita' da sola lascerebbe un elemento che sembra premibile e non fa
   niente, che e' il caso peggiore. */
.pulsante:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* ==========================================================================
   Barra di navigazione
   ========================================================================== */

.barra {
  position: sticky;
  top: 0;
  z-index: var(--z-barra);
  border-bottom: var(--bordo-largo) solid var(--bordo);
  /* Fondo quasi opaco: la sfocatura da sola lascerebbe passare il testo che
     scorre sotto, e su un fondo scuro con testo chiaro il risultato e'
     illeggibile. */
  background: rgba(8, 9, 11, 0.92);
  backdrop-filter: blur(12px);
}

.barra-interno {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: 64px;
}

/* Il marchio e' l'immagine ufficiale, non un testo ricomposto col CSS.
   Prima qui c'erano un quadrato rosso disegnato in SVG e la scritta
   PLAYRUSTLEGACY in monospaziato: due approssimazioni del logo che a ogni
   ritocco del vero logo divergevano. Ora e' il file, e il nome del sito resta
   leggibile per i lettori di schermo dall'alt dell'immagine.

   flex: 0 1 auto e non flex: none: puo' restringersi se serve, non crescere.
   Con flex: none il lockup non cedeva un pixel e su telefono usciva dallo
   schermo invece di adattarsi — vedi il blocco piu' sotto per il conto.
   min-width: 0 perche' un elemento flex non scende sotto la propria misura
   minima di contenuto se non gli si dice esplicitamente che puo'. */
.marchio {
  display: inline-flex;
  flex: 0 1 auto;
  min-width: 0;
  align-items: center;
}

/* Larghezza piena fino alla misura del file, altezza dedotta. Le due misure
   nominali (595x49) sono anche negli attributi width/height dell'elemento, cosi'
   il browser conosce il rapporto e riserva lo spazio prima di aver scaricato
   l'immagine: la barra non sussulta al caricamento.

   height: auto e non 26px fissi. Con l'altezza imposta e la larghezza limitata
   l'immagine si schiaccerebbe invece di rimpicciolirsi; con il rapporto libero
   scende in proporzione. max-width tiene la misura piena dove lo spazio c'e'. */
.marchio-logo {
  display: block;
  width: 100%;
  max-width: 315.7px;   /* 595 x 26 / 49: la larghezza a 26px di altezza */
  height: auto;
}

/* PERCHE' IL LOCKUP SI RESTRINGE INVECE DI SPARIRE
   Il file e' 595x49, quindi a 26px di altezza la larghezza e' 315.7 — non 291,
   come diceva il commento di prima. Con 48px di margini, 16 di gap e 44 di
   hamburger il conto fa 423.7: il lockup a piena altezza chiede un viewport da
   424px, e nessun telefono in verticale ce li ha. Su un iPhone da 390 sforava di
   34px e il nome del sito veniva tagliato dal bordo destro dello schermo, con
   inchiostro fino all'ultima colonna di pixel.

   La misura giusta era una soglia in meno, non una in piu': l'immagine si adatta
   e a 390px diventa alta 23.2px invece di 26, una differenza che non si nota.
   Sostituirla col solo quadrato era la soluzione peggiore delle due — il segno
   da solo non dice come si chiama il sito, e sulla home di un server che si
   cerca per nome quello e' l'unico posto dove il nome compare sopra la piega.

   Il segno quadrato resta nel markup ma non viene mostrato da nessuna parte:
   e' aria-hidden, quindi non aggiunge nulla per un lettore di schermo, e
   togliere il markup vorrebbe dire toccare dieci pagine per un elemento che non
   costa niente dov'e'. */
.marchio-segno { display: none; }
.marchio-segno img { display: block; height: 26px; width: 26px; }

/* Nel piede il logo e' un po' piu' grande e resta sempre intero: la colonna e'
   larga e non contesa, e il piede e' il punto in cui il nome del sito va detto
   per esteso perche' accanto c'e' la nota legale che lo riguarda.

   max-width in proporzione all'altezza (595 x 32 / 49 = 388.6) e non quella
   della barra: con il max-width piu' piccolo e l'altezza a 32 l'immagine si
   schiaccerebbe. Sul telefono la colonna del piede e' larga tutta la pagina, ma
   width: 100% con questo tetto tiene comunque il logo dentro il contenitore. */
.marchio-pie .marchio-logo {
  height: auto;
  max-width: 388.6px;
}

/* --- selettore di lingua -------------------------------------------------- */

/* Un <select> nativo, ristilizzato quanto basta per non stonare. Non viene
   sostituito da un menu costruito a mano perche' quello nativo apre il
   selettore di sistema su telefono, funziona da tastiera e viene annunciato
   correttamente: tre cose che costerebbero cento righe da rifare.
   L'altezza sta a 36px e non a 44 perche' non e' un bersaglio primario e sta in
   una barra alta 64: portarlo a 44 spingerebbe fuori i due pulsanti accanto. Su
   telefono la barra dei link e' chiusa nel menu e lo spazio non e' contestato,
   quindi la a media query lo riporta a 44. */
.lingua-select {
  height: 36px;
  padding: 0 var(--s-2);
  border: var(--bordo-largo) solid var(--bordo-2);
  border-radius: var(--raggio);
  background: var(--fondo-2);
  color: var(--testo-2);
  font-family: var(--mono);
  /* 16px e non meno: sotto questa soglia iOS ingrandisce da se' la pagina
     quando il campo riceve la messa a fuoco, e poi non la rimpicciolisce. */
  font-size: 16px;
  cursor: pointer;
  transition: border-color var(--t-rapida) var(--curva),
              color var(--t-rapida) var(--curva);
}
.lingua-select:hover { border-color: var(--rust); color: var(--testo); }

/* Le opzioni le disegna il sistema operativo, non il CSS. Dichiarare i colori
   serve comunque: su Windows un <select> scuro senza questo mostra un elenco
   bianco su bianco. */
.lingua-select option { background: var(--fondo-2); color: var(--testo); }

@media (max-width: 767px) {
  .lingua-select { height: 44px; }
}

.barra-link {
  display: none;
  align-items: center;
  gap: var(--s-1);
}

.barra-link a {
  padding: var(--s-2) var(--s-3);
  border-radius: var(--raggio);
  color: var(--testo-2);
  font-family: var(--mono);
  font-size: var(--t-sm);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  transition: color var(--t-rapida) var(--curva),
              background var(--t-rapida) var(--curva);
}
.barra-link a:hover { color: var(--testo); background: var(--fondo-3); }

/* La posizione corrente va segnalata: senza, in un sito di piu' pagine non si
   sa dove si e'. aria-current="page" nel markup fa entrambe le cose — regge lo
   stile e viene annunciato dai lettori di schermo. */
.barra-link a[aria-current="page"] {
  color: var(--rust-chiaro);
  background: var(--rust-scuro);
}

.barra-azioni {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

/* NELLE PAGINE DEI MODULI LA BARRA NON HA UN MENU DOVE METTERE LE COSE
   Accesso, registrazione, conferma, reimposta e password dimenticata hanno una
   barra piu' leggera — marchio, lingua e un solo pulsante — e nessun menu a
   tendina dove spostare niente. Il conto su 342px e' 26 + 16 + 102 + 8 + il
   pulsante: in italiano «TORNA AL SITO» sta, in inglese «BACK TO THE SITE»
   chiede circa 190px e il totale arriva a 342 esatti, cioe' al limite.

   Il pulsante puo' stringersi e mandare il testo a capo su due righe invece di
   spingere il marchio fuori. Due righe da 13px stanno nei 44px di altezza
   minima, quindi la barra non cresce; il selettore invece non si stringe, perche'
   un <select> compresso mostra due lettere e non si capisce piu' che cos'e'. */
@media (max-width: 639px) {
  .barra-interno:not(:has(.menu-pulsante)) .barra-azioni .pulsante {
    min-width: 0;
    padding-inline: var(--s-3);
    text-wrap: balance;
  }
  .barra-interno:not(:has(.menu-pulsante)) .barra-azioni .lingua { flex: none; }
}

/* SU TELEFONO LA BARRA NON CI STA IN UNA RIGA
   Misurato su un iPhone da 390px: marchio, selettore di lingua, «accedi»,
   «registrati» e il pulsante del menu chiedono circa 360px dentro un
   contenitore che, coi suoi 24px di margine per lato, ne offre 342. Flex non
   avvisa, comprime: «accedi» spariva del tutto e il pulsante del menu finiva a
   36px invece di 44 — sotto la soglia di un bersaglio da toccare col pollice —
   col bordo destro a 389.7 su 390, cioe' appiccicato al vetro.

   E 360px e' il caso inglese, il piu' corto. I due pulsanti portano testo
   tradotto in nove lingue: «SIGN UP» diventa «CRÉER UN COMPTE» in francese e
   «ZAREJESTRUJ SIĘ» in polacco, e a 13px monospaziati con 0.06em di spaziatura
   una riga da 15 caratteri chiede da sola circa 170px contro i 100 dell'inglese.
   In quelle lingue la riga arriva oltre 430px: non e' un caso limite, e' meta'
   del pubblico di un server europeo.

   La barra resta una riga sola, e non diventa due: e' sticky, quindi ogni pixel
   che prende lo prende per tutta la lettura. Su uno schermo alto 664 punti una
   barra da 120 si mangerebbe il 18% della pagina per sempre.

   LA SOLUZIONE E' QUELLA PER CUI L'HAMBURGER ESISTE
   Sotto i 900px i link di navigazione sono gia' nel menu a tendina. Lingua e
   pulsanti d'accesso seguono la stessa strada: nella barra restano il marchio e
   il pulsante del menu — due elementi, 26px e 44px, che stanno in qualunque
   schermo in qualunque lingua — e tutto il resto sta dietro un tocco, dove la
   larghezza non e' contesa e le stringhe lunghe non rompono niente.

   La soglia e' 900px, la stessa dell'hamburger, e non 640: fra 640 e 900 la
   barra mostra il lockup intero da 291px accanto a lingua e pulsanti, ed e'
   proprio la fascia dove il conto sfonda di piu'. Due soglie diverse per la
   stessa riga lasciavano rotta la fascia in mezzo.

   Sono due elementi veri e non copie del markup: lingua.js monta tutti i posti
   che trova con querySelectorAll invece del solo primo, con id numerati perche'
   due id uguali sono markup non valido e il <label for> si legherebbe comunque
   al primo. Per la sessione non serve un secondo posto: comune.js sposta il
   nodo [data-sessione] dentro il menu, quindi resta unico e il codice che lo
   corregge dopo /api/io continua a trovarlo.

   Le regole sono agganciate a .barra-interno:has(.menu-pulsante) e non alla
   sola larghezza: le cinque pagine dei moduli (accesso, registrazione,
   conferma, reimposta, password dimenticata) non hanno menu, e la loro barra ha
   solo marchio, lingua e un pulsante — la' non c'e' niente da liberare, e una
   regola sulla sola larghezza toglierebbe la lingua senza darle un altro
   posto. */
@media (max-width: 899px) {
  .barra-interno:has(.menu-pulsante) .barra-azioni .lingua,
  .barra-interno:has(.menu-pulsante) .barra-azioni [data-sessione] {
    display: none;
  }
}

/* Lingua e pulsanti dentro il menu: ci sono solo dove la barra non li tiene.
   Sopra i 900px stanno nella barra, e averli in due punti nella stessa pagina
   sarebbe lo stesso comando due volte. Il padding e il bordo li allineano ai
   link del menu, che hanno gli stessi. */
.menu-lingua, .menu-sessione { display: none; }

@media (max-width: 899px) {
  .menu-lingua, .menu-sessione {
    padding: var(--s-4) var(--s-5);
    border-bottom: var(--bordo-largo) solid var(--bordo);
  }
  .menu-lingua { display: block; }
  .menu-lingua .lingua-select { width: 100%; }

  /* I due pulsanti a larghezza piena, uno sopra l'altro: nel menu non c'e'
     ragione di stringerli, e a tutta larghezza il bersaglio e' piu' facile da
     centrare col pollice di un pulsante da 100px allineato a sinistra.
     display: flex e non contents come nella barra — qui la riga serve. */
  .menu-sessione { display: flex; flex-direction: column; gap: var(--s-2); }
  .menu-sessione [data-sessione] {
    display: flex !important;   /* vince sullo style inline display:contents */
    flex-direction: column;
    gap: var(--s-2);
  }
  .menu-sessione .pulsante { width: 100%; }

  /* Il :last-child dei link non vale piu' quando in fondo c'e' un blocco. */
  .menu > :last-child { border-bottom: none; }
}

/* Il pulsante del menu compare solo dove i link sono nascosti. 44x44 pieni. */
.menu-pulsante {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  border: var(--bordo-largo) solid var(--bordo-2);
  border-radius: var(--raggio);
  background: none;
  cursor: pointer;
  color: var(--testo);
}

@media (min-width: 900px) {
  .barra-link { display: flex; }
  .menu-pulsante { display: none; }
}

/* Menu a tendina su schermo piccolo. hidden nel markup lo chiude davvero — un
   pannello nascosto con la sola opacita' resterebbe raggiungibile con Tab, e chi
   naviga da tastiera si troverebbe a percorrere link invisibili. */
.menu {
  border-bottom: var(--bordo-largo) solid var(--bordo);
  background: var(--fondo-2);
}
.menu[hidden] { display: none; }
.menu a {
  display: block;
  padding: var(--s-4) var(--s-5);
  border-bottom: var(--bordo-largo) solid var(--bordo);
  color: var(--testo-2);
  font-family: var(--mono);
  font-size: var(--t-sm);
  text-transform: uppercase;
  min-height: 44px;
}
.menu a:last-child { border-bottom: none; }
.menu a[aria-current="page"] { color: var(--rust-chiaro); }

@media (min-width: 900px) {
  .menu { display: none !important; }
}

/* ==========================================================================
   Riquadri e schede
   ========================================================================== */

.riquadro {
  padding: var(--s-5);
  border: var(--bordo-largo) solid var(--bordo);
  border-radius: var(--raggio);
  background: var(--fondo-2);
}

.scheda {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: var(--s-5);
  border: var(--bordo-largo) solid var(--bordo);
  border-radius: var(--raggio);
  background: var(--fondo-2);
  transition: border-color var(--t-media) var(--curva),
              background var(--t-media) var(--curva);
}
.scheda:hover { border-color: var(--bordo-2); background: var(--fondo-3); }

.scheda-numero {
  color: var(--rust-chiaro);
  font-family: var(--mono);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.14em;
}

.scheda h3 {
  font-family: var(--mono);
  font-size: var(--t-lg);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}

.scheda p { color: var(--testo-2); font-size: var(--t-sm); }

.griglia {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .griglia-2, .griglia-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 900px) {
  .griglia-3 { grid-template-columns: repeat(3, 1fr); }
}

/* ==========================================================================
   Stato del server
   ========================================================================== */

.stato {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  border: var(--bordo-largo) solid var(--bordo-2);
  border-radius: var(--raggio);
  background: var(--fondo-2);
  font-family: var(--mono);
  font-size: var(--t-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
}

.pallino {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--testo-3);
  flex-shrink: 0;
}
/* Il colore non e' l'unico segnale: accanto al pallino c'e' sempre la parola
   ATTIVO / SPENTO / N/D. */
.stato[data-stato="attivo"] { border-color: var(--verde); color: var(--verde); }
.stato[data-stato="attivo"] .pallino {
  background: var(--verde);
  box-shadow: 0 0 0 3px rgba(61, 220, 127, 0.18);
  animation: pulsa 2.4s ease-in-out infinite;
}
.stato[data-stato="spento"] { border-color: var(--rosso); color: var(--rosso); }
.stato[data-stato="spento"] .pallino { background: var(--rosso); }

@keyframes pulsa {
  50% { box-shadow: 0 0 0 6px rgba(61, 220, 127, 0); }
}

/* --- contatori --- */
.numeri {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 900px) {
  .numeri { grid-template-columns: repeat(4, 1fr); }
}

/* L'indirizzo prende la riga intera finche' la griglia e' a due colonne.
   Giocatori, posti e account sono cifre di due o tre caratteri e in mezza
   colonna stanno larghe; un dominio no. Con la riga intera ci sta senza andare
   a capo, e chi deve copiarlo lo legge tutto insieme invece che spezzato in
   due. Sopra i 900px la griglia va a quattro colonne e non serve piu': la
   pagina e' abbastanza larga perche' ogni voce abbia il suo spazio. */
@media (max-width: 899px) {
  .numeri > .numero:has(.numero-indirizzo) { grid-column: 1 / -1; }
}

.numero {
  padding: var(--s-5);
  border: var(--bordo-largo) solid var(--bordo);
  border-radius: var(--raggio);
  background: var(--fondo-2);
}
.numero dt {
  color: var(--testo-3);
  font-family: var(--mono);
  font-size: var(--t-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.numero dd {
  margin: var(--s-2) 0 0;
  font-family: var(--mono);
  font-size: clamp(var(--t-2xl), 4vw, var(--t-3xl));
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  letter-spacing: -0.03em;
}

/* Riserva l'altezza mentre il valore arriva: senza, la pagina sobbalza quando
   /api/stato risponde, ed e' esattamente cio' che il CLS misura. */
.numero dd[data-attesa]::after {
  content: attr(data-attesa);
  color: var(--testo-3);
}

/* L'INDIRIZZO NON E' UNA CIFRA
   Sta nella stessa griglia dei contatori, quindi ereditava .numero dd: 2rem,
   peso 700. Ma «playrustlegacy.com» sono diciotto caratteri, non due, e a 32px
   in monospace chiedono circa 346px dentro una colonna che su un telefono da
   360px ne ha 112. Sfondava il riquadro di tre volte, e sfondava proprio il
   dato che serve per collegarsi.

   Ora il corpo parte da 16px — leggibile per chi deve ricopiarlo a mano — e
   cresce con lo schermo. Insieme alla riga intera qui sotto sta comodo: 173px
   di testo in 280 disponibili su un telefono da 360px.

   break-all resta come rete: se un browser non applica il :has() qui sotto, o
   se un domani l'indirizzo diventasse piu' lungo, un dominio non ha punti
   d'interruzione che il browser riconosca da se' e senza questo uscirebbe dal
   riquadro invece di andare a capo. */
.numero-indirizzo {
  font-size: clamp(var(--t-base), 4.2vw, var(--t-xl));
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: 0;
  overflow-wrap: break-word;
  word-break: break-all;
}

/* ==========================================================================
   Tabella
   ========================================================================== */

/* Il contenitore scorre, non la pagina: una tabella larga dentro un blocco con
   overflow-x resta consultabile su telefono senza che il corpo del documento
   scorra in orizzontale. */
.tabella-scorre {
  overflow-x: auto;
  border: var(--bordo-largo) solid var(--bordo);
  border-radius: var(--raggio);
  -webkit-overflow-scrolling: touch;
}

table {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
  font-size: var(--t-sm);
}

thead th {
  position: sticky;
  top: 0;
  padding: var(--s-3) var(--s-4);
  border-bottom: var(--bordo-largo) solid var(--bordo-2);
  background: var(--fondo-3);
  color: var(--testo-3);
  font-family: var(--mono);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: left;
  white-space: nowrap;
}

tbody td {
  padding: var(--s-3) var(--s-4);
  border-bottom: var(--bordo-largo) solid var(--bordo);
  color: var(--testo-2);
  vertical-align: middle;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover td { background: var(--fondo-2); }
tbody td:first-child { color: var(--testo); font-weight: 500; }

/* SU TELEFONO LA TABELLA SI IMPILA
   Cinque colonne con min-width 560px su un telefono da 360 significano 200px
   fuori campo: lo scorrimento orizzontale funziona, ma l'indirizzo con la porta
   — il dato per cui si guarda questa tabella — e' proprio quello che finisce
   oltre il bordo, e nessuno scorre una tabella che sembra gia' completa.

   Sotto i 700px ogni cella diventa una riga con la sua etichetta, presa da
   data-etichetta nel markup. L'intestazione viene nascosta perche' le etichette
   la ripetono, e la tabella resta una tabella per chi usa un lettore di
   schermo: display:block cambia come le celle si dispongono, non cosa sono, e
   scope="col" con la caption continuano a descrivere la struttura.

   Il min-width va azzerato qui: senza, il blocco continua a scorrere anche da
   impilato e resta una barra orizzontale che non porta in nessun posto. */
@media (max-width: 699px) {
  .tabella-scorre { overflow-x: visible; }

  table { min-width: 0; }

  thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

  tbody tr { display: block; }

  tbody td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-4);
    padding: var(--s-3) var(--s-4);
    text-align: right;
  }

  /* L'etichetta della riga, dal markup: senza intestazione visibile, «29015»
     da solo non dice di essere una porta. */
  tbody td[data-etichetta]::before {
    content: attr(data-etichetta);
    flex: 0 0 auto;
    color: var(--testo-3);
    font-family: var(--mono);
    font-size: var(--t-xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-align: left;
  }

  /* La prima cella e' il nome del server: fa da titolo del blocco, quindi non
     porta etichetta e sta su una riga sua. */
  tbody td:first-child {
    justify-content: flex-start;
    border-bottom-color: var(--bordo-2);
    background: var(--fondo-3);
    text-align: left;
  }

  /* L'indirizzo con la porta e' lungo e va spezzato, come quello dei
     contatori. */
  tbody td[data-indirizzo-porta] {
    overflow-wrap: break-word;
    word-break: break-all;
  }
}

/* ==========================================================================
   Moduli
   ========================================================================== */

.modulo {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}

.campo {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}

/* Etichetta sempre visibile, mai il solo segnaposto: il segnaposto scompare
   appena si comincia a scrivere, e chi torna sul modulo dopo una distrazione non
   sa piu' cosa stava compilando. */
.campo label {
  color: var(--testo-2);
  font-family: var(--mono);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.campo label .obbligatorio {
  color: var(--rust-chiaro);
  margin-left: 2px;
}

.campo input {
  /* 44px: sotto questa altezza il campo e' scomodo da centrare col pollice.
     16px di corpo: sotto, Safari su iOS ingrandisce la pagina al primo tocco e
     l'impaginazione salta. */
  min-height: 44px;
  padding: var(--s-3) var(--s-4);
  border: var(--bordo-largo) solid var(--bordo-2);
  border-radius: var(--raggio);
  background: var(--fondo);
  color: var(--testo);
  font-family: var(--mono);
  font-size: var(--t-base);
  transition: border-color var(--t-rapida) var(--curva);
}
.campo input::placeholder { color: var(--testo-3); }
.campo input:hover:not(:disabled) { border-color: var(--testo-3); }
.campo input:focus { border-color: var(--rust-chiaro); outline-offset: 1px; }

.campo input[aria-invalid="true"] { border-color: var(--rosso); }

/* Testo di aiuto persistente sotto il campo, non un segnaposto: resta leggibile
   mentre si scrive, che e' il momento in cui serve. */
.aiuto {
  color: var(--testo-3);
  font-size: var(--t-xs);
  font-family: var(--mono);
}

/* L'errore sta sotto il campo che lo riguarda, non in cima al modulo: chi legge
   deve capire quale casella correggere senza cercare. */
.errore-campo {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  color: var(--rosso);
  font-size: var(--t-xs);
  font-family: var(--mono);
}
.errore-campo[hidden] { display: none; }
.errore-campo svg { flex-shrink: 0; margin-top: 2px; }

/* Campo password con il pulsante mostra/nascondi dentro. */
.campo-password { position: relative; display: flex; flex-direction: column; }
.campo-password input { padding-right: 3rem; }
.mostra-password {
  position: absolute;
  right: 1px;
  /* Allineato al campo, non alla colonna: l'etichetta sta sopra e occupa
     spazio, quindi un centramento verticale semplice lo porterebbe fuori. */
  bottom: 1px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px; height: 42px;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--testo-3);
  border-radius: var(--raggio);
}
.mostra-password:hover { color: var(--testo); }

/* --- avvisi in cima al modulo --- */
.avviso {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-4);
  border: var(--bordo-largo) solid var(--bordo-2);
  border-radius: var(--raggio);
  background: var(--fondo-3);
  font-size: var(--t-sm);
}
.avviso[hidden] { display: none; }
.avviso svg { flex-shrink: 0; margin-top: 2px; }
.avviso-errore { border-color: var(--rosso); background: var(--rosso-scuro); color: #FFD5D5; }
.avviso-errore svg { color: var(--rosso); }
.avviso-ok { border-color: var(--verde); background: var(--verde-scuro); color: #C8F5DA; }
.avviso-ok svg { color: var(--verde); }
.avviso-nota { color: var(--testo-2); }
.avviso-nota svg { color: var(--ambra); }

/* --- rotella di attesa nel pulsante --- */
.rotella {
  width: 14px; height: 14px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: gira 700ms linear infinite;
  flex-shrink: 0;
}
@keyframes gira { to { transform: rotate(360deg); } }

/* ==========================================================================
   Pie' di pagina
   ========================================================================== */

.pie {
  padding-block: var(--s-7) var(--s-6);
  border-top: var(--bordo-largo) solid var(--bordo);
  background: var(--fondo-2);
  color: var(--testo-3);
  font-size: var(--t-sm);
}
.pie-griglia {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: 1fr;
  margin-bottom: var(--s-6);
}
@media (min-width: 700px) {
  /* Due per due: a questa larghezza quattro colonne darebbero circa 130px
     ciascuna alle tre di link, dove "Your profile" andrebbe a capo. */
  .pie-griglia { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 1000px) {
  /* Il marchio con la nota legale prende il doppio: e' un paragrafo, le altre
     tre sono colonne di link brevi. */
  .pie-griglia { grid-template-columns: 2fr 1fr 1fr 1fr; }
}
.pie h4 {
  margin-bottom: var(--s-3);
  color: var(--testo-2);
  font-family: var(--mono);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.pie ul { list-style: none; padding: 0; display: grid; gap: var(--s-2); }
.pie a { color: var(--testo-3); transition: color var(--t-rapida) var(--curva); }
.pie a:hover { color: var(--rust-chiaro); }
.pie-discord { display: inline-flex; align-items: center; gap: var(--s-2); }
.pie-discord img { border-radius: 4px; }
.pie-basso {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  justify-content: space-between;
  padding-top: var(--s-5);
  border-top: var(--bordo-largo) solid var(--bordo);
  font-family: var(--mono);
  font-size: var(--t-xs);
}

/* ==========================================================================
   Pagine e sezioni di testo lungo

   Regole, privacy, cookie e la sezione dei sostenitori nella home: quattro posti
   che sono documenti da leggere, non interfacce da usare. Stavano in conto.css
   quando li usavano solo le pagine dell'account; da quando la home ha la sezione
   dei sostenitori sono qui, perche' base.css e' il foglio che ogni pagina carica
   comunque e altrimenti la home dovrebbe scaricare tutto conto.css per sei
   paragrafi.
   ========================================================================== */

.testo {
  padding-block: var(--s-7) var(--s-8);
}

.testo-corpo {
  /* 68 caratteri: il limite oltre il quale l'occhio, tornando a capo, fatica a
     trovare la riga successiva. */
  max-width: 68ch;
}

.testo-corpo h2 {
  margin-top: var(--s-7);
  margin-bottom: var(--s-3);
  font-family: var(--mono);
  font-size: var(--t-lg);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}
.testo-corpo h2:first-child { margin-top: 0; }

.testo-corpo p,
.testo-corpo li {
  color: var(--testo-2);
  margin-bottom: var(--s-4);
}

.testo-corpo ol,
.testo-corpo ul {
  padding-left: var(--s-5);
  margin-bottom: var(--s-4);
}

.testo-corpo li { margin-bottom: var(--s-2); }

.testo-corpo strong { color: var(--testo); }

.testo-corpo a {
  color: var(--rust-chiaro);
  text-decoration: underline;
  text-underline-offset: 3px;
}
