/* burnroom — foglio di stile unico.
 *
 * Deriva dai mockup approvati in design/: stessi colori, stessi font, stesse
 * spaziature. Le differenze volute rispetto ai mockup sono annotate dove
 * capitano.
 *
 * Due vincoli che spiegano la forma del file:
 *  - La CSP del server e' `style-src 'self'`: nessuno stile in linea, nessun
 *    attributo style. Tutto quello che nei mockup stava in `style="..."` e'
 *    diventato una classe qui.
 *  - Esiste un solo layout, quello mobile dei mockup: nessun breakpoint,
 *    nessuna media query di larghezza, nessun elemento che cambia dimensione
 *    o disposizione su schermi larghi. Sul telefono la colonna prende tutta
 *    la larghezza; da 390px in su resta ferma a 390px e si centra, col fondo
 *    #0b0c0a ai lati. L'unica media query del file riguarda
 *    prefers-reduced-motion, che non tocca il layout.
 */

/* I @font-face stanno in /fonts/fonts.css, caricato con un <link> accanto a
   questo foglio: un @import qui costringerebbe il browser a scaricare prima
   questo file e poi l'altro, in fila. */

:root {
  --bg: #0b0c0a;
  --text: #c8d4c4;
  --dim: #7f8c7b;
  --border: #2a3328;
  --green: #3dff7a;
  --amber: #ffb000;
  --red: #ff6b5a;
  --bright: #e8f0e4;
  --muted: #9aa896;
  --guest: #7ad7ff;

  --mono: 'IBM Plex Mono', ui-monospace, monospace;
  --vt: 'VT323', 'IBM Plex Mono', monospace;
  --logo: 'Press Start 2P', 'IBM Plex Mono', monospace;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  /* Rete di sicurezza, non la soluzione: nessuna pagina deve mai scorrere in
     orizzontale. Le cause vere sono risolte dove nascono (min-width sui figli
     flex, overflow-wrap sui testi, font-size 16px nei campi). Questo serve a
     garantire che un elemento che sfora domani non produca comunque la barra
     laterale. Solo l'asse X: lo scorrimento verticale deve restare. */
  overflow-x: hidden;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--mono);
  font-size: 14px;
  line-height: 1.55;
  min-height: 100vh;
  min-height: 100dvh;
  /* Impedisce a iOS di ingrandire i caratteri per conto suo: le misure
     devono essere identiche a quelle dei mockup. */
  -webkit-text-size-adjust: 100%;
}

a {
  color: var(--green);
  text-decoration: none;
}

a:hover,
a:focus-visible {
  color: #9dffbc;
}

/* Il contenitore unico: e' questo l'intero sistema di layout del progetto.
   width 100% sul telefono, fermo a 390px (la misura dei mockup) da lì in su,
   centrato con margin auto. Non ci sono altre regole di larghezza da nessuna
   parte nel file.

   100dvh invece di 100vh: su mobile la barra degli indirizzi che compare e
   scompare cambierebbe l'altezza e taglierebbe il campo di scrittura della
   chat. 100vh resta come ripiego per i browser che non conoscono dvh. */
.app {
  position: relative;
  width: 100%;
  max-width: 390px;
  margin: 0 auto;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--bg);
  display: flex;
  flex-direction: column;
}

/* Pagina della chat: il documento non scorre affatto, scorre solo l'area dei
   messaggi. `position: fixed` sul body e' quello che impedisce a iOS di
   spostare la pagina sotto la tastiera, lasciando intestazione e campo di
   scrittura dove sono. */
body.pagina-chat {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  /* Il trascinamento a vuoto non deve rimbalzare tutta la pagina. */
  overscroll-behavior: none;
}

/* Variante per la chat: altezza bloccata a quella della finestra VISUALE, non
   di quella di layout. La differenza conta solo quando si apre la tastiera:
   la finestra di layout resta alta come prima e il campo di scrittura
   finirebbe coperto, mentre la finestra visuale si accorcia.
   --altezza-vista la aggiorna chat.js sull'evento resize di
   window.visualViewport; 100dvh e' il ripiego per i browser che non
   espongono visualViewport. */
.app--chat {
  height: 100dvh;
  height: var(--altezza-vista, 100dvh);
  max-height: var(--altezza-vista, 100dvh);
  overflow: hidden;
}

/* ------------------------------- effetto CRT ------------------------------- */

/* Scanline appena percepibili + vignettatura morbida, come da identita'
   visiva. `pointer-events: none` perche' copre tutta la colonna. */
.crt {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 10;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0px,
    rgba(0, 0, 0, 0) 3px,
    rgba(0, 0, 0, 0.07) 4px
  );
  box-shadow: inset 0 0 90px rgba(0, 0, 0, 0.6);
  animation: crt 4s linear infinite;
}

@keyframes crt {
  0%,
  48%,
  52%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.82;
  }
}

/* ------------------------------- tipografia ------------------------------- */

.riga-dim {
  font-size: 12px;
  color: var(--dim);
}

.piccolo {
  font-size: 12px;
}

.chiaro {
  color: var(--bright);
}

.verde {
  color: var(--green);
}

.ambra {
  color: var(--amber);
}

.rosso {
  color: var(--red);
}

/* Cursore lampeggiante dei terminali. */
.blink {
  color: var(--green);
  animation: blink 1s steps(1) infinite;
}

@keyframes blink {
  50% {
    opacity: 0;
  }
}

/* --------------------------------- splash --------------------------------- */

/* Spaziature della splash.
 *
 * Obiettivo dichiarato: la splash sta tutta nello schermo senza scorrimento
 * verticale, anche su un telefono basso (375x667). I mockup sono disegnati a
 * 390x844 e con quei valori (padding 28/24, gap 22) l'altezza minima del
 * contenuto e' circa 758px: entra in 844 ma sfora di una novantina di pixel
 * in 667.
 *
 * Qui gli spazi verticali sono ridotti fino a stare in 667. Le dimensioni dei
 * font e dei pulsanti NON sono state toccate: solo padding, gap e margini.
 * Il conto sta in deploy/misura-splash.mjs, che lo rifa' leggendo questo
 * file. Non ci sono media query: i valori sono gli stessi su ogni schermo. */
.splash {
  padding: 18px 24px 14px;
  gap: 13px;
}

.barra-alta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: var(--dim);
  letter-spacing: 0.04em;
}

/* Riga di avvio: UNA sola riga, che si cancella e si riscrive quattro volte
   prima di fermarsi su "> pronto_".
 *
 * La sequenza la guida public/js/splash.js e non il CSS: qui servirebbe
 * cambiare il testo della riga a ogni passo, e la proprieta' `content` non e'
 * animabile in modo affidabile.
 *
 * min-height fissa l'altezza della riga. Senza, nell'istante in cui il testo
 * viene cancellato il blocco non avrebbe nessuna riga di testo dentro,
 * l'altezza andrebbe a zero e tutto quello che sta sotto farebbe un salto a
 * ogni passo. 1.55em sono i 18.6px di una riga a 12px con interlinea 1.55.
 *
 * L'HTML contiene gia' "> pronto_": e' lo stato finale, quindi senza
 * JavaScript, o con prefers-reduced-motion, la splash e' quella giusta e
 * ferma. Lo script cancella la riga e riparte da capo solo se le animazioni
 * sono ammesse. */
.avvio {
  font-size: 12px;
  color: var(--dim);
  min-height: 1.55em;
  white-space: nowrap;
  overflow: hidden;
}

/* Il blocco logo + pulsanti entra dopo l'ultima riga di avvio. */
/* Il blocco logo + pulsanti entra a 1.75s, cioe' subito dopo che la riga di
   avvio si e' fermata su "> pronto_" (l'ultimo passo parte a 1.55s e scrive
   otto caratteri a 10ms, quindi finisce verso 1.63s). La battuta sta in
   MS_PER_CARATTERE in public/js/splash.js: se cambia, questo ritardo va
   ricontrollato. */
.sale {
  display: flex;
  flex-direction: column;
  gap: 13px;
  opacity: 0;
  animation: sale 0.5s ease-out 1.75s forwards;
}

@keyframes sale {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.intestazione {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.riga-logo {
  display: flex;
  align-items: flex-end;
  gap: 14px;
}

.marchio {
  font-family: var(--logo);
  font-size: 30px;
  line-height: 1;
  color: var(--green);
  padding-bottom: 2px;
  text-shadow: 0 0 12px rgba(61, 255, 122, 0.35);
}

.slogan {
  font-family: var(--vt);
  font-size: 26px;
  line-height: 1;
  color: var(--bright);
}

.sottotitolo {
  color: var(--muted);
  font-size: 13px;
}

/* Fiamma in pixel: due fotogrammi alternati sulla punta. */
.fiamma-a {
  animation: fiamma-a 0.5s steps(1) infinite;
}

.fiamma-b {
  animation: fiamma-b 0.5s steps(1) infinite;
}

@keyframes fiamma-a {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}

@keyframes fiamma-b {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
}

/* --------------------------------- riquadri -------------------------------- */

/* Padding verticale 13 invece di 16 e gap 10 invece di 12: i due riquadri
   sono il blocco piu' alto della splash, qui si recuperano 22px in tutto.
   L'orizzontale resta a 16 per non cambiare il rientro del testo. */
.riquadro {
  display: flex;
  flex-direction: column;
  gap: 10px;
  border: 1px solid var(--border);
  padding: 13px 16px;
}

/* Nei mockup il bordo verde stava sul riquadro dell'alias. Nel modulo 1
   l'alias e' disattivato, quindi l'evidenza passa all'opzione utilizzabile:
   stessi due bordi del mockup, scambiati di posto. */
.riquadro--attivo {
  border-color: var(--green);
}

.riquadro--inattivo {
  border-color: var(--border);
}

.riquadro-testa {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
}

.riquadro-testa > * {
  min-width: 0;
}

.riquadro-titolo {
  color: var(--bright);
  font-weight: 600;
}

.riquadro-nota {
  font-size: 12px;
  color: var(--muted);
}

/* --------------------------------- pulsanti -------------------------------- */

/* Pulsanti tra parentesi quadre, come da identita'. Area di tocco >= 48px. */
.bottone {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 12px;
  border: 1px solid var(--green);
  background: transparent;
  color: var(--green);
  font-family: var(--mono);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.06em;
  text-decoration: none;
  cursor: pointer;
  width: 100%;
}

.bottone:hover:not(:disabled),
.bottone:focus-visible:not(:disabled) {
  background: rgba(61, 255, 122, 0.08);
  color: #9dffbc;
}

.bottone--pieno {
  min-height: 52px;
  background: var(--green);
  border-color: var(--green);
  color: var(--bg);
}

.bottone--pieno:hover:not(:disabled),
.bottone--pieno:focus-visible:not(:disabled) {
  background: #9dffbc;
  color: var(--bg);
}

/* Disattivato: resta leggibile e visibile, ma non sembra premibile. Un
   pulsante verde pieno che non fa niente sarebbe un inganno. */
.bottone:disabled,
.bottone[aria-disabled='true'] {
  border-color: var(--border);
  background: transparent;
  color: var(--dim);
  cursor: not-allowed;
}

/* INVIA non si stringe mai: la larghezza che cede e' quella del campo di
   scrittura accanto. flex-shrink: 0 oltre a min-width, perche' min-width da
   sola lascerebbe il pulsante scendere fino a 72px prima di fermarsi. */
.bottone--invia {
  width: auto;
  min-width: 72px;
  flex-shrink: 0;
  background: var(--green);
  border: none;
  color: var(--bg);
  letter-spacing: 0.04em;
}

.bottone--invia:disabled {
  background: var(--border);
  color: var(--dim);
}

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

.campo {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.campo label {
  font-size: 12px;
  color: var(--dim);
}

.campo-prefisso {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--border);
  min-height: 48px;
}

.campo-prefisso span {
  display: flex;
  align-items: center;
  padding-left: 12px;
  color: var(--dim);
  font-size: 13px;
}

/* I due tipi di campo sono definiti separatamente e NON si sovrappongono.
 *
 * Prima qui c'era una regola `input[type='text']` con i valori del campo
 * alias, e `.campo-riquadrato` doveva sovrascriverli. Non succedeva: un
 * selettore di tipo con attributo vale (0,0,1,1) di specificita', una classe
 * (0,0,1,0), quindi vinceva la regola generica e i campi riquadrati
 * finivano a font-size 13px, senza bordo e senza padding interno.
 *
 * Conseguenza su iPhone: Safari ingrandisce automaticamente la pagina quando
 * si tocca un campo con font-size sotto i 16px, e l'ingrandimento rende la
 * pagina piu' larga della finestra. Da li' veniva lo scorrimento orizzontale
 * della chat, che restava anche dopo la chiusura della tastiera. Un motore
 * desktop non riproduce quell'ingrandimento, percio' la misura a 360, 375 e
 * 390px non mostrava niente.
 *
 * Ora il campo con prefisso e' agganciato al suo contenitore e i due insiemi
 * di regole non si incontrano piu'. */

/* Campo dentro un contenitore con prefisso fisso ("burnroom.app/"): la
   cornice la disegna .campo-prefisso, il campo e' nudo. */
.campo-prefisso input[type='text'] {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--bg);
  border: none;
  color: var(--bright);
  font-family: var(--mono);
  font-size: 13px;
  padding: 0 12px 0 0;
  outline: none;
}

/* Campo riquadrato autonomo: nick e messaggio.
   font-size 16px e' un requisito, non una preferenza: sotto quella misura
   iOS ingrandisce la pagina al primo tocco. Non abbassarlo.
   (Il campo alias qui sopra resta a 13px come nei mockup perche' e'
   disabilitato e non puo' ricevere il fuoco; quando il modulo 2 lo attivera'
   andra' portato a 16px per lo stesso motivo.) */
.campo-riquadrato {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--bright);
  font-family: var(--mono);
  font-size: 16px;
  padding: 12px;
  min-height: 48px;
  outline: none;
}

.campo-riquadrato:focus {
  border-color: var(--green);
}

input[type='text']::placeholder {
  color: var(--dim);
  opacity: 1;
}

input[type='text']:disabled {
  color: var(--dim);
}

/* --------------------------------- footer --------------------------------- */

.spaziatore {
  flex-grow: 1;
}

.pie {
  display: flex;
  justify-content: center;
  gap: 14px;
  font-size: 11px;
  color: var(--dim);
}

.pie a {
  color: var(--dim);
}

.pie a:hover,
.pie a:focus-visible {
  color: var(--text);
}

/* Spinge il piede in fondo alla colonna senza usare un div vuoto con
   flex-grow. Fa lo stesso lavoro di .spaziatore ma non aggiunge un elemento,
   quindi risparmia anche il `gap` che quell'elemento porterebbe con se'.
   Sta su una classe a parte perche' le pagine che centrano il contenuto fra
   due spaziatori (bruciata.html) non devono ereditarlo: un margine automatico
   assorbe tutto lo spazio libero e lascerebbe quegli spaziatori a zero. */
.pie--fondo {
  margin-top: auto;
}

/* ------------------------------- link stanza ------------------------------- */

.link-stanza {
  border: 1px solid var(--border);
  padding: 12px;
  color: var(--green);
  font-size: 13px;
  min-width: 0;
  /* Il link di una stanza e' una sola parola lunga 45 caratteri: va spezzato,
     non tagliato e non fatto sporgere. */
  overflow-wrap: break-word;
  overflow-wrap: anywhere;
  user-select: all;
}

.nascosto {
  display: none !important;
}

/* ---------------------------------- chat ---------------------------------- */

.chat-testa {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 20px 20px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.chat-testa-riga {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
}

/* Un figlio flex ha min-width: auto, cioe' non si stringe sotto la larghezza
   del suo contenuto. Con un nick lungo a sinistra e il countdown a destra
   (che non puo' andare a capo) la riga non starebbe nei 320px utili di uno
   schermo da 360. Qui si permette ai figli di stringersi. */
.chat-testa-riga > * {
  min-width: 0;
}

.canale {
  font-family: var(--vt);
  font-size: 30px;
  line-height: 1;
  color: var(--green);
  overflow-wrap: break-word;
  overflow-wrap: anywhere;
}

/* Il nick di chi sta scrivendo ("tu: ...") cede il posto al countdown:
   si accorcia con i puntini invece di spingere la riga oltre il bordo. */
.io {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Countdown: verde, ambra sotto un'ora, rosso sotto dieci minuti.
   nowrap perche' "autodistruzione 23:41:07" spezzato a meta' non si legge,
   e flex-shrink: 0 perche' e' l'informazione che non deve cedere: se lo
   spazio manca si accorcia il nick accanto, non questo. */
.countdown {
  font-size: 12px;
  color: var(--green);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex-shrink: 0;
}

.countdown--attenzione {
  color: var(--amber);
}

.countdown--critico {
  color: var(--red);
}

.log {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 18px 20px;
  overflow-y: auto;
  /* Esplicito: con overflow-y impostato e overflow-x lasciato a `visible`, la
     specifica fa calcolare `auto` anche sull'altro asse, e il log si
     ritroverebbe una barra orizzontale propria. Qui dentro nulla deve
     scorrere di lato: i testi vanno a capo. */
  overflow-x: hidden;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  min-width: 0;
}

/* Le righe del log sono figlie di un contenitore flex in colonna: senza
   min-width: 0 una riga con un messaggio lunghissimo senza spazi imporrebbe
   la propria larghezza al contenitore. */
.log-riga {
  min-width: 0;
  /* break-word prima, anywhere dopo: il primo e' sostenuto da molto piu'
     tempo (Safari lo ha da sempre, `anywhere` solo dalla 15.4), il secondo
     e' migliore perche' riduce anche la larghezza minima calcolata
     dell'elemento. I browser che non capiscono il secondo valore tengono il
     primo. */
  overflow-wrap: break-word;
  overflow-wrap: anywhere;
}

/* I pezzi della riga sono span in linea: l'andare a capo si eredita, ma lo
   dichiariamo dove il testo arriva da chi scrive, cosi' resta vero anche se
   un domani queste parti finiscono fuori da .log-riga. */
.corpo,
.nick-host,
.nick-guest,
.epitaffio,
.sta-scrivendo {
  overflow-wrap: break-word;
  overflow-wrap: anywhere;
}

/* Avvisi di sistema: prefisso *** aggiunto dal CSS, non dal testo, cosi' il
   contenuto salvato nel database resta pulito. */
.sistema {
  color: var(--dim);
  font-size: 12px;
}

.sistema::before {
  content: '*** ';
}

.sistema--allarme {
  color: var(--amber);
}

.sistema--critico {
  color: var(--red);
}

.ora {
  color: var(--dim);
}

.nick-host {
  color: var(--green);
}

.nick-guest {
  color: var(--guest);
}

.corpo {
  color: var(--bright);
}

/* La riga "sta scrivendo" nei mockup e' l'ultima del flusso dei messaggi. Qui
   sta appena sopra il campo di scrittura, fuori dall'area che scorre: altri-
   menti sparirebbe appena si scorre indietro la conversazione. I 4px la
   riallineano al bordo sinistro dei messaggi, che hanno 20px di padding
   contro i 16px della zona di scrittura. */
.sta-scrivendo {
  color: var(--dim);
  font-size: 12px;
  min-height: 1.55em;
  padding-left: 4px;
}

.composizione {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 16px 20px;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}

.composizione-riga {
  display: flex;
  gap: 8px;
  align-items: stretch;
  min-width: 0;
}

/* Il campo si stringe (min-width: 0 lo dichiara .campo-riquadrato), il prompt
   e il pulsante no: sono le due estremita' fisse della riga, e lo dicono con
   flex-shrink: 0.
 *
 * Qui NON va una regola `.composizione-riga > * { min-width: 0 }`: avrebbe la
 * stessa specificita' di .bottone--invia e, stando piu' in basso nel file, ne
 * cancellerebbe il `min-width: 72px`. Il pulsante scenderebbe a 69px, la
 * larghezza del suo testo. */

.prompt {
  display: flex;
  align-items: center;
  color: var(--green);
  font-weight: 600;
  flex-shrink: 0;
}

.composizione-nota {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 11px;
  color: var(--dim);
}

/* ------------------------------ ingresso chat ------------------------------ */

/* Pannello del nick, mostrato prima di entrare. Vive dentro la colonna, non
   e' una finestra sovrapposta. */
.ingresso {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 28px 24px;
  justify-content: center;
  flex-grow: 1;
}

/* ------------------------------- distruzione ------------------------------- */

/* Una riga che si sta cancellando: sfarfalla e collassa. */
.brucia {
  animation: brucia 0.22s ease-in forwards;
}

@keyframes brucia {
  0% {
    opacity: 1;
  }
  40% {
    opacity: 0.35;
    color: var(--red);
  }
  100% {
    opacity: 0;
    transform: translateX(-6px);
  }
}

.epitaffio {
  color: var(--dim);
  font-size: 12px;
}

/* -------------------------------- pagina note ------------------------------- */

.note {
  padding: 28px 24px 24px;
  gap: 18px;
}

.note h1 {
  font-family: var(--vt);
  font-size: 30px;
  line-height: 1;
  color: var(--green);
  margin: 0;
  font-weight: 400;
}

.note h2 {
  font-family: var(--vt);
  font-size: 22px;
  line-height: 1.1;
  color: var(--bright);
  margin: 18px 0 6px;
  font-weight: 400;
}

.note p,
.note li {
  font-size: 13px;
  color: var(--text);
  margin: 0 0 8px;
}

.note ul {
  margin: 0 0 8px;
  padding-left: 20px;
}

/* ---------------------------- movimento ridotto ---------------------------- */

/* Chi ha chiesto meno animazioni vede la stessa interfaccia, ferma: le righe
   di avvio sono gia' scritte, il logo e' presente, niente sfarfallii. */
@media (prefers-reduced-motion: reduce) {
  .crt,
  .fiamma-a,
  .blink {
    animation: none;
  }

  .fiamma-b {
    animation: none;
    opacity: 0;
  }

  /* La riga di avvio resta sul suo stato finale, "> pronto_": e' quello che
     c'e' gia' nell'HTML, e splash.js non la tocca. */

  .sale {
    animation: none;
    opacity: 1;
  }

  .brucia {
    animation: none;
    opacity: 0;
  }
}
