:root {
  /* Inchiostro e carta, non grigi neutri: il goban e' legno, l'interfaccia gli
     sta intorno con la stessa temperatura calda. */
  --ink: #14120e;
  --ink-raised: #1c1915;
  --paper: #ece3d2;
  /* Il grigio dello spento e' stato alzato due volte, e questa e' la seconda:
     al 55% e al 30% le etichette in maiuscoletto piccolo — che sono quasi tutte
     le scritte della colonna — si leggevano solo guardandole apposta, e su uno
     schermo poco contrastato sparivano. Spento vuol dire "non e' la cosa
     principale", non "non si legge". */
  --paper-dim: rgba(236, 227, 210, 0.78);
  --paper-faint: rgba(236, 227, 210, 0.56);
  --rule: rgba(236, 227, 210, 0.16);
  --rule-strong: rgba(236, 227, 210, 0.36);
  /* Il rosso dei sigilli: unico colore acceso, quindi vuol dire qualcosa. */
  --seal: #c8482a;
  /* Lo stesso rosso, ma **da leggere**. Quello pieno e' un colore da fondi e da
     bordi: in una scritta piccola sull'inchiostro sta a 3,7 volte il contrasto
     dello sfondo, che per un corpo da dodici e mezzo non basta. Schiarito
     arriva a 5,8 e resta lo stesso rosso. */
  --seal-text: #e8785c;

  /* Il legno di riserva: la fotografia (texture.png) la dipinge il renderer
     sul canvas, questa e' la tinta che si vede finche' non e' arrivata. */
  --board: #e0a851;
  --line: #3a2a15;
  --black-stone: #0e0e0d;
  --white-stone: #f2ece0;

  --serif: "Fraunces", "Iowan Old Style", "Hoefler Text", "Palatino Linotype",
    Palatino, Georgia, "Liberation Serif", serif;
  /* Il mono era dappertutto — dodici etichette su dodici, piu' i numeri — e
     adesso e' rimasto in quattro posti, ognuno con la sua ragione.
     La riga del giocatore: il totale, il margine e la forza stanno uno sopra
     l'altro e si confrontano solo se le cifre sono incolonnate. Il ritardo di
     rete, che cambia dieci volte al secondo e con cifre di larghezza diversa
     farebbe ballare la riga. E il link d'invito, che e' un indirizzo da
     copiare carattere per carattere, dove la elle e l'uno devono potersi
     distinguere.
     Dappertutto altrove il mono non stava dicendo niente: stava solo facendo
     sembrare un gioco da tavolo un pannello di controllo. */
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", "DejaVu Sans Mono", Menlo,
    Consolas, monospace;
}

/* ------------------------------------------------------------ il carattere
 *
 * Sta nella cartella, e non e' uno stack di sistema. Quello di prima —
 * Iowan Old Style, Hoefler Text, Palatino Linotype — era fatto di caratteri
 * installati solo su Mac o solo su Windows: su Linux, su Android e su
 * parecchi Chrome la pagina cadeva su Georgia, cioe' sul ripiego. Il
 * carattere che si era scelto, a meta' delle persone non arrivava mai.
 *
 * Fraunces ci sta **per intero**: e' variabile, quindi un file solo copre
 * tutti i pesi da 100 a 900, e ha l'asse ottico (`opsz`). Con quello la
 * stessa famiglia e' un carattere da testo a tredici pixel e uno da titolo a
 * novanta, disegnati diversi — le grazie si assottigliano crescendo, come nei
 * caratteri da piombo, dove ogni corpo era un disegno a se'. E' il motivo per
 * cui qui non serve una seconda famiglia.
 *
 * L'asse `WONK` e' il magheggio vero: accende le terminazioni storte, quelle
 * disegnate a mano invece che ricavate per simmetria. A corpo piccolo non si
 * vedrebbero e sporcherebbero, quindi si accende **solo dove si legge
 * grande** — il grido, il verdetto, i tastoni, il nome in cima.
 *
 * I file sono tagliati su misura (solo latino, e con l'asse SOFT fissato):
 * 64 kB il tondo, 80 il corsivo, invece dei 271 originali.
 */
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/fraunces.woff2") format("woff2");
}

@font-face {
  font-family: "Fraunces";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/fraunces-italic.woff2") format("woff2");
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
}

/* Il goban prende tutta l'altezza della pagina, quindi l'interfaccia gli sta
   di fianco in una colonna: in orizzontale lo spazio avanza sempre, in
   verticale mai. */
/* Lo sfondo dice in che stato e' la partita senza scriverlo: inchiostro
   mentre si gioca, un grigio piu' chiaro quando il goban si congela. Il
   passaggio e' lento apposta — e' il contrario del lampo di gelo, che e'
   istantaneo: quello annuncia, questo resta. */
body {
  display: flex;
  flex-direction: row;
  background: var(--ink);
  transition: background 0.8s ease-out;
  color: var(--paper);
  font: 16.5px/1.5 var(--serif);
  /* L'asse ottico lo guida il browser dalla misura del testo: e' quello che fa
     sembrare la stessa famiglia due caratteri diversi fra un'etichetta e un
     titolo, ed e' gratis. */
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
}

/* --------------------------------------------------------------------- hud */

#hud {
  flex: 0 0 300px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 20px;
  padding: 18px;
  border-right: 1px solid var(--rule);
  background: linear-gradient(var(--ink-raised), var(--ink));
  overflow-y: auto;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Lo stato scivola in fondo alla colonna: sopra c'e' la partita, sotto la
   macchina che la fa girare. */
.status {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}

/* Mezzo nero e mezzo bianco, come il segno di un'intersezione contesa. */
.brand-stone {
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: linear-gradient(90deg, var(--black-stone) 50%, var(--white-stone) 50%);
  box-shadow: 0 0 0 1px var(--rule-strong);
}

.brand-name {
  font-size: 21px;
  font-weight: 600;
  letter-spacing: 0;
  /* Il nome e' la cosa piu' grande della colonna: qui le terminazioni storte
     si vedono, ed e' il posto dove devono vedersi. */
  font-variation-settings: "WONK" 1;
}

/* ------------------------------------------------------------ a che punto e' */

/* Una riga sola, e dice una cosa per volta: si gioca, si contano i morti, ha
   vinto qualcuno. Il colore del vincitore lo mette la pietra davanti. */
.verdict {
  /* Era in maiuscoletto spaziato: gridava un nome proprio — «PIPPO WINS BY 12»
     — e gridarlo non aggiungeva niente. Adesso e' scritto come si scrive, e a
     farsi notare ci pensa la misura. */
  font: 600 20px/1.2 var(--serif);
  font-variation-settings: "WONK" 1;
  color: var(--paper-dim);
}

.verdict[hidden] {
  display: none;
}

.verdict[data-color="nero"],
.verdict[data-color="bianco"] {
  display: flex;
  align-items: center;
  gap: 9px;
  color: var(--paper);
}

.verdict[data-color="nero"]::before,
.verdict[data-color="bianco"]::before {
  content: "";
  width: 13px;
  height: 13px;
  border-radius: 50%;
  box-shadow: 0 0 0 1px var(--rule-strong);
}

.verdict[data-color="nero"]::before { background: var(--black-stone); }
.verdict[data-color="bianco"]::before { background: var(--white-stone); }

/* ------------------------------------------------------- i due giocatori */

.score {
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
}

/* Pietra, nome, forza, punti, margine. Le pietre stanno qui e solo qui: il
   conto finale si aggiunge a queste due righe invece di avere un pannello suo
   con un secondo paio di dischi. */
.player {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  padding: 8px 0 8px 10px;
  border-left: 2px solid transparent;
  cursor: default;
}

.player + .player {
  border-top: 1px solid var(--rule);
}

/* In colonna il segno del proprio colore passa di fianco: sottolineare due
   righe impilate le farebbe sembrare separate invece che marcate. */
.player[data-self="true"] {
  border-left-color: var(--seal);
}

.player[data-present="false"] {
  opacity: 0.4;
}

.player-stone {
  align-self: center;
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  box-shadow: 0 0 0 1px var(--rule-strong);
}

.player[data-color="nero"] .player-stone { background: var(--black-stone); }
.player[data-color="bianco"] .player-stone { background: var(--white-stone); }

/* Il tastone premuto si vede da qui: un cerchietto acceso attorno alla pietra
   dell'altro dice "lui e' pronto" senza aggiungere una riga di testo. */
.player[data-ready="true"] .player-stone {
  box-shadow: 0 0 0 2px var(--seal);
}

.player-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* La forza: due caratteri, in mono perche' e' un numero da confrontare a
   colpo d'occhio con quello dell'altra riga. */
/* La forza resta in mono, ed e' il primo dei tre posti dove ci resta: e' un
   numero che si confronta con quello della riga di sopra, e due numeri si
   confrontano se stanno incolonnati. */
.player-rank {
  font: 13px/1 var(--mono);
  color: var(--paper-dim);
}

.player-rank:empty {
  display: none;
}

/* Il punteggio spinge a destra: la colonna dei numeri resta allineata anche
   con nomi di lunghezza diversa. */
/* Il secondo posto del mono, e il piu' importante: i due totali stanno uno
   sopra l'altro e si leggono a colpo d'occhio solo se le cifre hanno tutte la
   stessa larghezza. Fraunces ha cifre proporzionali e nessuna funzione
   `tnum` — l'ho controllato — quindi qui il mono non e' pigrizia. */
.player-points {
  margin-left: auto;
  font: 18px/1 var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--paper);
}

.player-lead {
  font: 13px/1 var(--mono);
  color: var(--seal-text);
}

.player-lead:empty {
  display: none;
}

/* -------------------------------------------------------- stato e comandi */

.seat, .conn {
  display: flex;
  align-items: center;
  gap: 7px;
  font: 14px/1 var(--serif);
  color: var(--paper-dim);
}

/* Il terzo e ultimo posto del mono: il ritardo di rete cambia dieci volte al
   secondo, e con le cifre proporzionali la riga ballerebbe. */
.conn {
  font-family: var(--mono);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}

.seat[hidden] {
  display: none;
}

/* Il pallino della connessione: verde acceso, ambra mentre ci prova, rosso
   quando e' caduta. Tre stati in un pixel, invece di tre parole. */
.conn .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #6f9f6a;
}

.conn[data-status="connecting"] .dot { background: #c79a3e; }
.conn[data-status="offline"] .dot { background: var(--seal); }
.conn[data-status="offline"] { color: var(--seal-text); }

.btn {
  padding: 12px 16px;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  background: transparent;
  color: var(--paper-dim);
  font: 500 16px/1 var(--serif);
  cursor: pointer;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}

.btn:hover:not(:disabled) {
  color: var(--paper);
  border-color: var(--paper-dim);
  background: rgba(236, 227, 210, 0.06);
}

.btn:focus-visible {
  outline: 2px solid var(--seal);
  outline-offset: 2px;
}

.btn:disabled {
  opacity: 0.4;
  cursor: default;
}

.btn[hidden] {
  display: none;
}

.btn-yes {
  border-color: var(--seal);
  background: var(--seal);
  color: #fdf6ec;
}

.btn-yes:hover:not(:disabled) {
  border-color: #d95530;
  background: #d95530;
  color: #fff;
}

.btn-wide {
  width: 100%;
}

/* Il tastone. E' l'unica cosa da fare in tutta la pagina in quel momento,
   quindi si prende lo spazio di un tastone vero. */
.btn-big {
  width: 100%;
  padding: 20px 15px;
  font-size: 21px;
  font-weight: 600;
  font-variation-settings: "WONK" 1;
}

/* Il tastone della colonna: **quadrato e grosso**. Li' sotto lo spazio c'e'
   tutto, e quello e' il solo tasto che si preme mentre si guarda il goban — lo
   si deve trovare con la mano senza staccare gli occhi da dove si sta
   giocando, e un rettangolo alto quaranta pixel come tutti gli altri non lo
   permetteva. Un blocco alto quanto e' largo lo si trova a occhi chiusi. */
.btn-square {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 108px;
  padding: 16px 12px;
  font-size: 26px;
  font-weight: 600;
  font-variation-settings: "WONK" 1;
}

/* Le due righe del tastone: cosa fa, e a che punto e' l'accordo. La seconda
   c'e' solo quando ha qualcosa da dire — vuota sparisce, e il tasto torna a
   essere una parola sola in mezzo al quadrato. */
.btn-label {
  display: block;
}

.btn-sub {
  display: block;
  font: italic 400 14px/1.3 var(--serif);
  font-variation-settings: "WONK" 0;
  /* Non e' una postilla: e' l'unica riga che dice a che punto e' l'accordo.
     Spenta quanto una nota a pie' di pagina non la leggeva nessuno. */
  color: var(--paper-dim);
}

.btn-sub:empty {
  display: none;
}

/* Chi aspetta noi lo dice piu' forte di chi aspettiamo noi: e' l'unica delle
   due righe che chiede di fare qualcosa. */
.btn[data-state="theirs"] {
  border-color: var(--seal);
}

.btn[data-state="theirs"] .btn-sub {
  color: var(--seal-text);
}

/* Ma sul tasto **rosso pieno** — il via — il rosso non si vede: e' il colore
   del tasto. Li' la riga sotto va chiara, ed e' proprio quella che si deve
   leggere, perche' dice che l'altro sta aspettando te. */
.btn-yes .btn-sub {
  color: #fff;
}

.btn-yes[data-state="theirs"] {
  border-color: #fdf6ec;
}

.btn-yes[data-state="theirs"] .btn-sub {
  color: #fff;
}

/* Il tasto del ritorno in guerra sta sotto il tastone, e non e' un tastone:
   e' la via d'uscita, non la cosa da fare. */
#war {
  width: 100%;
}

/* Premuto, non e' piu' un comando ma un'attesa: si spegne e dice chi manca.
   Ripremendolo si de-preme, che e' il motivo per cui resta un pulsante. Vale
   per tutti e due i tastoni — il via e la fine — che sono lo stesso gesto ai
   due capi della partita. */
.btn[data-ready="true"] {
  border-color: var(--rule-strong);
  background: transparent;
  color: var(--paper-dim);
  letter-spacing: 0.1em;
  animation: waiting 2.4s ease-in-out infinite;
}

@keyframes waiting {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}

body[data-mode="pace"] {
  background: #38332b;
}

/* ------------------------------------------------------- il pannello dell'accordo */

/* Al centro dello schermo e sopra tutto. Il velo dietro e' semitrasparente:
   la posizione appena finita resta visibile mentre si decide la prossima, che
   e' anche il motivo per cui il pannello non e' opaco fino ai bordi.

   Solo scuro, **non sfocato**. La sfocatura sembrava la cosa giusta — mettere
   a fuoco il pannello — ma quello che c'e' dietro e' un goban, cioe' righe
   sottili e pietre tonde: sfocarlo lo trasforma in una macchia, e la posizione
   che si voleva lasciar vedere non si legge piu'. Abbassare la luce la lascia
   leggibile e il pannello viene avanti lo stesso, perche' e' chiaro su scuro. */
.veil {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(12, 10, 8, 0.72);
}

.veil[hidden] {
  display: none;
}

.lobby {
  width: min(430px, 100%);
  max-height: 100%;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 26px 28px 24px;
  border: 1px solid var(--rule-strong);
  border-radius: 4px;
  background: var(--ink-raised);
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.65);
}

.lobby-title {
  font: 600 27px/1.1 var(--serif);
  font-variation-settings: "WONK" 1;
  letter-spacing: 0;
  color: var(--paper);
}

/* Com'e' finita quella di prima, in cima alla scelta della prossima. */
.lobby-result {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: -10px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--rule);
  font-size: 15px;
  color: var(--paper-dim);
}

.lobby-result[hidden] {
  display: none;
}

.lobby-result b {
  color: var(--paper);
  font-weight: 600;
}

/* ------------------------------------------------------------- il riepilogo */

/* Sta nella colonna, sotto le due righe dei giocatori. Chi ha vinto lo dice il
   verdetto in cima, il conto dei due sta dentro le loro righe: qui resta solo
   quello che non e' di nessuno dei due — com'e' andata la partita. */
.stats {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.stats[hidden] {
  display: none;
}

/* Il resto: numeri che non decidono la partita ma la raccontano. Etichetta a
   sinistra e valore a destra, che in una colonna stretta e' l'unico modo di
   tenerli in riga; quando il valore non ci sta (i parametri della partita, che
   sono tre cose in una) va a capo per conto suo. */
.facts {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 0;
  padding-top: 14px;
  border-top: 1px solid var(--rule);
}

.facts div {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
}

.facts dt {
  flex: 0 0 auto;
  font: italic 14px/1.4 var(--serif);
  color: var(--paper-faint);
}

.facts dd {
  margin: 0 0 0 auto;
  font: 14px/1.4 var(--serif);
  color: var(--paper-dim);
}

/* Etichetta con la sua "i" sopra, comando sotto. E le etichette si leggono:
   il grigio spento di prima le rendeva quasi invisibili proprio sulle uniche
   parole che dicono cosa stai cambiando. */
/* La porta chiusa: `?v=` senza una versione che si conosca. Non e' un errore
   da segnalare in un angolo — e' che qui non c'e' niente da aprire — quindi
   prende il posto di tutto, e dietro non resta un goban a meta' da guardare. */
body[data-gate] #hud,
body[data-gate] main,
body[data-gate] #veil {
  display: none;
}

.gate-note {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--paper-dim);
}

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

/* Serve davvero: il `display: flex` qui sopra e' un selettore di classe e
   batte il `[hidden] { display: none }` del browser, quindi senza questa riga
   una riga nascosta resterebbe li' a farsi vedere. E' il motivo per cui ogni
   cosa che si nasconde, qui dentro, ha la sua riga apposta.
   Le versioni bloccate (`?v=101`) tolgono cosi' board, pace e handicap. */
.field[hidden] {
  display: none;
}

.field-head {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* L'etichetta di una riga del pannello. Era in maiuscoletto mono spaziato,
   come tutte le altre: dodici scritte identiche che gridavano piano. Adesso e'
   una parola scritta come si scrive, un po' piu' grande — quello che la fa
   leggere e' che sta da sola sopra la sua riga, non che sia in maiuscolo. */
.field-label {
  font: 500 17px/1 var(--serif);
  color: var(--paper-dim);
}

.field-body {
  display: flex;
  align-items: center;
  gap: 8px;
}

.field-body[hidden] {
  display: none;
}

/* La "i". Sta accanto all'etichetta e non in fondo alla riga: e' l'etichetta
   che uno non capisce, quindi la spiegazione va chiesta li'. */
.info {
  width: 19px;
  height: 19px;
  flex: 0 0 auto;
  padding: 0;
  border: 1px solid var(--rule-strong);
  border-radius: 50%;
  background: transparent;
  color: var(--paper-dim);
  font: italic 700 12px/1 var(--serif);
  cursor: help;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}

.info:hover, .info[data-on="true"] {
  border-color: var(--paper-dim);
  background: rgba(236, 227, 210, 0.1);
  color: var(--paper);
}

/* La spiegazione, quando la si chiede. Era una scatola scura con una barra a
   sinistra — il modo in cui un programma segnala una cosa. Ma questa e' prosa,
   la si legge per righe intere, e allora si tratta come prosa: rientrata e
   tenuta da una riga sottile, come una citazione in un libro. Niente fondo:
   il fondo la faceva sembrare un avviso. */
.hint {
  margin: 0;
  padding: 2px 0 2px 14px;
  border-left: 1px solid var(--rule);
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--paper-dim);
}

.hint[hidden] {
  display: none;
}

.hint b {
  color: var(--paper);
  font-weight: 600;
}

#lobby-name {
  flex: 1;
  min-width: 0;
  padding: 9px 10px;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.25);
  color: var(--paper);
  font: 15px/1.2 var(--serif);
}

#lobby-name::placeholder {
  color: var(--paper-faint);
}

#lobby-rank {
  flex: 0 0 auto;
  padding: 9px 8px;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  background: transparent;
  color: var(--paper-dim);
  font: 15px/1 var(--serif);
  cursor: pointer;
}

#lobby-rank option {
  background: var(--ink-raised);
  color: var(--paper);
}

.chips {
  display: flex;
  flex: 1;
  gap: 6px;
}

.chip {
  flex: 1;
  padding: 11px 6px;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  background: transparent;
  color: var(--paper-dim);
  font: 500 16px/1 var(--serif);
  cursor: pointer;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}

.chip:hover:not(:disabled) {
  color: var(--paper);
  border-color: var(--paper-dim);
  background: rgba(236, 227, 210, 0.06);
}

.chip[data-on="true"] {
  border-color: var(--paper);
  background: rgba(236, 227, 210, 0.16);
  color: var(--paper);
}

.chip:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Bianco e nero si scelgono per nome, con la pietra davanti: "swap colours"
   diceva cosa fa il pulsante invece di cosa stai scegliendo, e con due posti
   soli scegliere il proprio e' la stessa cosa detta meglio. */
.stone-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 4px;
}

.chip-stone {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  box-shadow: 0 0 0 1px var(--rule-strong);
}

.chip-stone[data-color="nero"] { background: var(--black-stone); }
.chip-stone[data-color="bianco"] { background: var(--white-stone); }

/* La nota sotto una riga: e' un a parte, e il corsivo e' il modo in cui i
   libri dicono "questo lo sto aggiungendo io". */
.note {
  font: italic 14px/1.4 var(--serif);
  color: var(--paper-faint);
}

/* Meno e piu' attorno al valore. Sono passi da mezzo, quindi il valore va
   letto: sta in mezzo e in chiaro, i due tasti ai lati sono spenti. */
.stepper {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 8px;
}

.step {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  background: transparent;
  color: var(--paper-dim);
  font: 19px/1 var(--serif);
  cursor: pointer;
}

.step:hover:not(:disabled) {
  color: var(--paper);
  border-color: var(--paper-dim);
  background: rgba(236, 227, 210, 0.06);
}

.step:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Il valore fra i due tasti. Non e' incolonnato con niente — sta da solo e in
   mezzo — e non e' nemmeno sempre un numero: a passo zero ci si legge
   "infinite (spam go)", che in mono sembrava un messaggio di errore. */
.step-value {
  flex: 1;
  min-width: 0;
  font: 18px/1 var(--serif);
  text-align: center;
  color: var(--paper);
}

.num {
  width: 82px;
  padding: 9px 10px;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.25);
  color: var(--paper);
  font: 15px/1 var(--serif);
}

/* L'invito: si vede finche' l'altro posto e' vuoto, e sparisce quando sono
   seduti in due — a quel punto non c'e' piu' niente da mandare a nessuno. */
.invite {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 16px;
  border-top: 1px solid var(--rule);
}

.invite[hidden] {
  display: none;
}

.invite-text {
  font-size: 14.5px;
  color: var(--paper-dim);
}

.invite-row {
  display: flex;
  gap: 6px;
}

#invite-link {
  flex: 1;
  min-width: 0;
  padding: 8px 9px;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.3);
  color: var(--paper-dim);
  font: 12.5px/1 var(--mono);
}

#invite-copy {
  padding: 8px 12px;
}

/* ------------------------------------------------------------------ goban */

main {
  position: relative;
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Niente ombra proiettata: il goban arriva al bordo dello schermo, e un'ombra
   la' sotto non avrebbe dove cadere. Gli angoli invece sono appena smussati,
   quel tanto che basta perche' il legno sembri un oggetto posato li' e non un
   ritaglio. */
#board {
  background: var(--board);
  border-radius: 10px;
  cursor: pointer;
  touch-action: none;
}

/* In pace il goban resta il legno di sempre. Cambia pero' il gesto: non si
   posa piu' niente, si segnano i morti. */
body[data-mode="pace"] #board {
  cursor: crosshair;
}

/* Fuori dalla partita non si posa niente, e la manina direbbe il contrario. */
body[data-seat="spettatore"] #board,
body[data-mode="lobby"] #board,
body[data-mode="finita"] #board {
  cursor: default;
}

/* ------------------------------------------------------------- il grido */

/* Compare sul goban, non nella colonna: e' una cosa che succede alla partita,
   e li' la si vede senza staccare gli occhi da dove si sta giocando.
   Un solo colpo, e se ne va da solo — un cartellino che restasse acceso
   diventerebbe subito una scritta da ignorare. */
#shout {
  /* Steso su tutto il goban e centrato dentro: cosi' lo `scale`
     dell'animazione cresce attorno al centro del legno invece che attorno a
     un angolo, e non serve un `translate` che poi litigherebbe con lo scale. */
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  /* L'unico maiuscolo rimasto in tutta la pagina, ed e' l'unico che se lo
     merita: e' un grido. A questa misura l'asse ottico ha gia' assottigliato
     le grazie da solo, e `WONK` storce le terminazioni — il carattere qui non
     e' quello delle etichette, e' un parente stretto. */
  font: 800 clamp(40px, 8.5vmin, 96px)/1 var(--serif);
  font-variation-settings: "WONK" 1;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: #fdf6ec;
  text-shadow: 0 0 24px rgba(200, 72, 42, 0.8), 0 6px 18px rgba(0, 0, 0, 0.55);
  opacity: 0;
}

#shout.go {
  animation: shout 1.15s cubic-bezier(0.18, 0.9, 0.3, 1) 1;
}

@keyframes shout {
  0% { opacity: 0; transform: scale(2.1) rotate(-4deg); }
  18% { opacity: 1; transform: scale(1) rotate(-4deg); }
  70% { opacity: 1; transform: scale(1.04) rotate(-4deg); }
  100% { opacity: 0; transform: scale(1.3) rotate(-4deg); }
}

/* I numeri del conto alla rovescia. Stessa scritta del grido, ma il verso e'
   l'opposto: il grido se ne va **crescendo**, perche' apre qualcosa; i numeri
   se ne vanno **stringendosi**, perche' chiudono un'attesa. Non c'e' bisogno
   di scriverlo da nessuna parte, si vede.

   E dura meno di un secondo, che e' l'intervallo fra un numero e l'altro: uno
   che si spegnesse in 1,15s come il grido sarebbe ancora acceso quando entra
   il successivo, e i tre si accavallerebbero invece di battere. */
#shout.count {
  animation: count 0.86s cubic-bezier(0.18, 0.9, 0.3, 1) 1;
  /* Il numero non e' un grido: e' un battito. Piu' leggero, e senza le
     terminazioni storte — quelle sono del "via", che arriva subito dopo, e la
     differenza fra i tre numeri e la parola si deve sentire. */
  font-weight: 500;
  font-variation-settings: "WONK" 0;
}

@keyframes count {
  0% { opacity: 0; transform: scale(1.75) rotate(-4deg); }
  14% { opacity: 1; transform: scale(1) rotate(-4deg); }
  62% { opacity: 1; transform: scale(1) rotate(-4deg); }
  100% { opacity: 0; transform: scale(0.84) rotate(-4deg); }
}

/* -------------------------------------------------------- il conto alla rovescia */

.mode {
  font: italic 16px/1 var(--serif);
  color: var(--paper-dim);
}

.mode:empty {
  display: none;
}

/* Il conto alla rovescia e' l'unica scritta del cartellino, quindi puo'
   prendersi lo spazio: un numero grande che cala mentre tutto il resto e'
   fermo si legge con la coda dell'occhio, senza doverlo cercare. Ed e' uno
   solo: quello che porta al gelo. */
.mode[data-phase="attesa"] {
  font: 600 38px/1 var(--serif);
  font-variation-settings: "WONK" 1;
  color: var(--paper);
}

/* In pace non c'e' nessun numero: la partita non si chiude piu' da sola, la
   chiudono i due premendo "done". Il conto rosso che stava qui contava verso
   una cosa che adesso decidono loro — e quando il timer non c'e' piu', un
   cronometro fermo sullo zero e' solo una cifra che resta li'. */

/* Il ritorno in guerra dopo la pace: il cartellino si accende una volta, cosi'
   non passa inosservato che la partita e' ripartita. */
.mode.flash {
  animation: mode-flash 1.1s ease-out 1;
}

@keyframes mode-flash {
  0% {
    background: var(--seal);
    color: #fdf6ec;
    letter-spacing: 0.32em;
  }
  60% {
    background: rgba(200, 72, 42, 0.25);
    color: #fdf6ec;
  }
  100% {
    background: transparent;
  }
}

/* Chi preferisce niente animazioni si tiene il colore, che basta a capire. */
@media (prefers-reduced-motion: reduce) {
  .mode.flash, .btn[data-ready="true"] {
    animation: none;
  }
  #shout.go {
    animation: shout-still 1.15s linear 1;
  }
  /* I numeri restano, e restano meno: senza il movimento e' il ricambio a
     dire che il conto sta scendendo, quindi ognuno deve sparire prima che
     arrivi il successivo. */
  #shout.count {
    animation: shout-still 0.86s linear 1;
  }
  @keyframes shout-still {
    0%, 85% { opacity: 1; }
    100% { opacity: 0; }
  }
}

#toast {
  position: absolute;
  bottom: 26px;
  left: 50%;
  transform: translateX(-50%);
  padding: 10px 16px;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: rgba(20, 18, 14, 0.94);
  color: var(--paper);
  font: 15px/1.3 var(--serif);
  opacity: 0;
  transition: opacity 0.25s;
  pointer-events: none;
}

#toast.visible {
  opacity: 1;
}

/* --------------------------------------------------------------- stretto */

/* Su uno schermo piu' alto che largo il goban non puo' prendersi l'altezza
   senza sfondare di lato: li' la colonna torna a essere una fascia in cima e
   il goban si prende tutta la larghezza. */
@media (max-aspect-ratio: 1 / 1), (max-width: 620px) {
  body {
    flex-direction: column;
  }
  #hud {
    flex: 0 0 auto;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    border-right: none;
    border-bottom: 1px solid var(--rule);
    overflow-y: visible;
  }
  .score {
    flex-direction: row;
  }
  .player {
    gap: 7px;
    padding: 3px 10px;
    border-left: none;
    border-bottom: 2px solid transparent;
  }
  .player + .player {
    border-top: none;
    border-left: 1px solid var(--rule);
  }
  .player[data-self="true"] {
    border-left-color: transparent;
    border-bottom-color: var(--seal);
  }
  .player-points {
    margin-left: 6px;
  }
  /* Il pannello si prende tutta la fascia: sono cinque righe, e in orizzontale
     non ci starebbero mai di fianco alle altre cose. Il conto di fine partita
     idem, e sta prima — e' della partita appena finita, non della prossima. */
  .lobby {
    flex: 1 0 100%;
    order: 9;
  }
  .stats {
    flex: 1 0 100%;
    order: 8;
  }
  .status {
    margin-top: 0;
    margin-left: auto;
    flex-direction: row;
    align-items: center;
    gap: 14px;
  }
  .brand-name, .seat {
    display: none;
  }
}
