/* Casa — tema chiaro, ricalcato sulla nuova app Google Home.
 *
 * I valori qui sotto non sono a occhio: sono misurati sugli screenshot di
 * riferimento (`casa-v2/imgs.jpg`, `casa-v2/images.jpg`). Fondo bianco,
 * tessere tonali con raggio 20, spazi di 8, e — il dettaglio che si nota
 * più di tutti — la tessera di una luce accesa non è tinta uniforme: è
 * riempita da sinistra in proporzione a quanto è accesa, giallo pieno
 * sopra giallo pallido. Nell'app di Google quel riempimento è la
 * luminosità; qui sono le lampade che stanno davvero facendo luce.
 *
 * Due registri tipografici, non uno: Figtree per la casa (i nomi delle
 * luci, le stanze, i pulsanti), DM Mono per la macchina (il motivo di un
 * guasto, gli identificativi di avvio, gli orari). Quando qualcosa si
 * rompe si vede anche dal carattere che si sta leggendo un fatto tecnico
 * e non una frase di cortesia.
 *
 * Niente librerie: sono quattro schermate, il CSS scritto a mano pesa meno
 * di qualunque framework e non va aggiornato.
 */

/* ------------------------------------------------------------ caratteri */

/* Serviti dal Pi, non da un CDN: quando salta la linea di casa la rete
   locale c'è ancora, e l'app deve continuare ad avere la sua faccia. */
@font-face {
  font-family: "Figtree";
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url("/caratteri/figtree.woff2") format("woff2");
}

@font-face {
  font-family: "DM Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/caratteri/dmmono-400.woff2") format("woff2");
}

@font-face {
  font-family: "DM Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/caratteri/dmmono-500.woff2") format("woff2");
}

:root {
  --fondo: #ffffff;
  --carta: #ffffff;
  /* Il grigio appena azzurrato delle superfici secondarie: la barra in
     fondo, i campi di testo, i cerchi vuoti. */
  --velo-superficie: #f4f6f9;
  --filo: #e1e3e7;

  --inchiostro: #1b1b1f;
  --inchiostro-2: #45474e;
  --inchiostro-3: #74777f;

  /* Luce accesa. Il pieno è la parte illuminata della tessera, la traccia
     è il resto: la differenza fra i due è quanta luce manca. */
  --giallo-pieno: #fde18d;
  --giallo-traccia: #fdeec3;
  --giallo-su: #423600;

  /* Luce spenta: grigio, non azzurro. Deve sparire, non attirare. */
  --grigio: #eceef2;
  --grigio-su: #45474e;
  --grigio-icona: #74777f;

  /* Il verde è l'unico accento della casa: la scheda aperta, la stanza
     scelta, il pulsante che porta avanti, il quadratino di un anello che
     regge. Prima queste cose erano azzurre e il verde valeva solo "va
     bene": due accenti senza una regola che li distinguesse. Uno solo, e
     vuol dire sempre la stessa cosa — questo è acceso, questo è a posto,
     sei qui. Il pieno serve dove ci va sopra del bianco. */
  --verde: #c9ecd9;
  --verde-su: #08513a;
  --primario: #146c4a;

  --guaio: #ffdad6;
  --guaio-su: #8c1d18;
  --avviso: #ffe7bd;
  --avviso-su: #5c4100;

  /* Cinque tinte per le cinque persone di casa. Nessuna è gialla, verde,
     rossa o ambra: quei quattro colori qui dentro vogliono già dire
     qualcosa (una luce accesa, un anello che regge, un guasto, un
     avvertimento) e una faccia che se li prende in prestito racconta una
     bugia — la M di Michele in giallo tessera sembra una lampada accesa
     in cima alla pagina. Le identità stanno su un mazzo tutto loro. */
  --chi-0: #dfe3ff;
  --chi-0-su: #2b3a9b;
  --chi-1: #ffdfd0;
  --chi-1-su: #8a3b12;
  --chi-2: #ebdcff;
  --chi-2-su: #4a2b86;
  --chi-3: #ffd9ea;
  --chi-3-su: #86104b;
  --chi-4: #cfeaf5;
  --chi-4-su: #0e4d63;

  /* Il blu di notte che spegne le stanze nelle illustrazioni. */
  --notte: #16203a;

  --r-tessera: 20px;
  --r-carta: 24px;
  --r-campo: 16px;

  --tondo: "Figtree", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --macchina: "DM Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* Due curve: una per i cambi di colore, una elastica per le forme che si
     riassestano dopo il dito. È la molla a far sembrare vive le tessere. */
  --morbida: cubic-bezier(0.2, 0, 0, 1);
  --molla: cubic-bezier(0.34, 1.42, 0.64, 1);
}

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

html,
body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  background: var(--fondo);
}

body {
  font-family: var(--tondo);
  color: var(--inchiostro);
  font-size: 16px;
  line-height: 1.35;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  /* Niente rimbalzo elastico sotto la barra: fa sembrare rotta la PWA. */
  overscroll-behavior-y: none;
}

button {
  font: inherit;
  color: inherit;
  border: none;
  background: none;
  cursor: pointer;
  padding: 0;
}

input {
  font: inherit;
}

:focus-visible {
  outline: 3px solid var(--primario);
  outline-offset: 2px;
}

/* ------------------------------------------------------------ impianto */

.schermo {
  max-width: 560px;
  margin: 0 auto;
  padding: calc(env(safe-area-inset-top) + 8px) 12px
    calc(env(safe-area-inset-bottom) + 104px) 12px;
}

/* Solo la faccia, a destra. Nell'app di riferimento accanto c'è un campo
   di ricerca; qui non c'è niente da cercare — sono quattro luci — e
   qualunque cosa ci si mettesse al suo posto la direbbero già meglio le
   tessere sotto. Una riga vuota vale più di una riga che ripete. */
.testata {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 4px 0 12px 0;
}

.faccia {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 16px;
  flex: 0 0 auto;
  transition: transform 0.34s var(--molla);
}

button.faccia:active {
  transform: scale(0.92);
}

/* Le cinque tinte delle persone. Le stesse dei cerchi dell'accesso: chi
   entra premendo il pesca si ritrova il pesca in cima. */
.faccia.t0,
.cerchio.t0 {
  background: var(--chi-0);
  color: var(--chi-0-su);
}

.faccia.t1,
.cerchio.t1 {
  background: var(--chi-1);
  color: var(--chi-1-su);
}

.faccia.t2,
.cerchio.t2 {
  background: var(--chi-2);
  color: var(--chi-2-su);
}

.faccia.t3,
.cerchio.t3 {
  background: var(--chi-3);
  color: var(--chi-3-su);
}

.faccia.t4,
.cerchio.t4 {
  background: var(--chi-4);
  color: var(--chi-4-su);
}

/* -------------------------------------------------------------- filtri */

/* La fila di pastiglie sotto la testata. Nell'app di riferimento filtra
   per tipo di apparecchio; qui gli apparecchi sono tutti lampade, quindi
   filtra per stanza — che è l'unica divisione vera che questa casa ha. */
.filtri {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 12px;
  margin: 0 -12px;
  padding-left: 12px;
  padding-right: 12px;
}

.filtri::-webkit-scrollbar {
  display: none;
}

.filtro {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 16px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.1px;
  color: var(--inchiostro-2);
  box-shadow: inset 0 0 0 1px var(--filo);
  transition:
    background-color 0.24s var(--morbida),
    color 0.24s var(--morbida),
    box-shadow 0.24s var(--morbida),
    transform 0.3s var(--molla);
}

.filtro:active {
  transform: scale(0.96);
}

.filtro.scelto {
  background: var(--verde);
  color: var(--verde-su);
  box-shadow: none;
}

/* ------------------------------------------------------------- stanze */

.stanza {
  margin-bottom: 20px;
}

/* Il titolo di scorta per una stanza senza illustrazione: quando c'è il
   disegno, il nome sta scritto sopra al disegno e questo non compare. */
.stanza-cima {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 2px 6px 8px 6px;
}

.stanza-cima .nome-stanza {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.2px;
}

.stanza-cima .conta {
  font-size: 13px;
  font-weight: 600;
  color: var(--inchiostro-3);
}

/* --------------------------------------------------------- la vetrina */

/* Il disegno della stanza vera, al posto che nell'app di riferimento tiene
   la diretta della telecamera: stessa forma, stesse scritte agli angoli.
   Non è un ornamento — è il colpo d'occhio che dice com'è messa la stanza
   prima di leggere qualsiasi parola.

   Qui non c'è più nessun effetto di luce: la fotografia è già quella giusta
   per le lampade accese in questo momento, scelta per nome dalla cartella
   `stanze/`. Prima erano un velo blu e un alone giallo dosati a opacità
   sopra un'unica foto, e si vedeva che erano un trucco — la luce cadeva
   dove diceva il gradiente, non dove sta la lampada. Al CSS resta solo
   tenere leggibili le scritte bianche agli angoli. */
.vetrina {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-carta);
  overflow: hidden;
  background: var(--notte);
  margin-bottom: 8px;
  isolation: isolate;
}

/* Tutte le combinazioni di luci della stanza stanno qui insieme, impilate
   nello stesso riquadro: si vede solo quella accesa adesso. Costa dieci
   immagini in pagina per tutta la casa, e in cambio il cambio di luce non
   scarica e non decodifica niente — sposta una classe. Con un `src`
   cambiato al volo, invece, il riquadro sbianca per un istante a ogni
   tocco, che è proprio il momento in cui si sta guardando.

   Le nascoste non sono `visibility: hidden` né `display: none`: quelle il
   browser ha il diritto di non decodificarle finché non servono, e la
   decodifica al primo tocco è esattamente il ritardo che si vuole togliere.
   Stanno sotto, coperte da quella mostrata — che è opaca e riempie tutto il
   riquadro — e a scegliere è solo l'ordine di impilamento.

   Nessuna dissolvenza: l'interruttore vero non dissolve. */
.vetrina img {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 42%;
}

.vetrina img.mostrata {
  z-index: 1;
}

/* Le scritte e il pulsante stanno sopra la pila delle fotografie: senza
   questo, un'immagine con lo z-index alzato se li mangerebbe. */
.vetrina .orlo,
.vetrina .targa,
.vetrina .conta,
.vetrina .spegni {
  z-index: 2;
}

/* Una fascia scura appena accennata agli orli: le scritte bianche agli
   angoli devono restare leggibili anche quando la stanza è tutta accesa e
   la fotografia sotto è chiara. */
.vetrina .orlo {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(0, 0, 0, 0.42), rgba(0, 0, 0, 0) 32%),
    linear-gradient(0deg, rgba(0, 0, 0, 0.34), rgba(0, 0, 0, 0) 28%);
  pointer-events: none;
}

/* Il nome della stanza in alto a sinistra col puntino acceso, come il
   "Live" della telecamera. Il puntino è giallo quando c'è luce e vuoto
   quando non ce n'è: da lontano è la prima cosa che si legge. */
.vetrina .targa {
  position: absolute;
  left: 14px;
  top: 12px;
  display: flex;
  align-items: center;
  gap: 7px;
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.1px;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}

.vetrina .targa .punto {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.55);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18);
  transition: background-color 0.4s var(--morbida);
}

.vetrina.accesa .targa .punto {
  background: #ffcf49;
  box-shadow: 0 0 10px rgba(255, 197, 61, 0.9);
}

.vetrina .conta {
  position: absolute;
  right: 14px;
  top: 12px;
  color: rgba(255, 255, 255, 0.92);
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}

/* Spegnere una stanza intera è l'unico comando che ha senso mettere qui:
   accenderla tutta no, perché "tutta" vorrebbe dire scegliere al posto di
   chi entra quante lampade gli servono. Sta dove l'app di riferimento
   mette il pulsante dell'audio: cerchio scuro traslucido, angolo in
   basso a destra. */
.vetrina .spegni {
  position: absolute;
  right: 12px;
  bottom: 12px;
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(20, 20, 24, 0.5);
  color: #fff;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition:
    transform 0.34s var(--molla),
    background-color 0.2s var(--morbida);
}

.vetrina .spegni:active {
  transform: scale(0.9);
  background: rgba(20, 20, 24, 0.7);
}

/* ------------------------------------------------------------ tessere */

.griglia {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

/* Una tessera dispari in coda non lascia mai un buco: si prende la riga.
   Meglio di riempire lo spazio con un comando inventato apposta. Quante
   caselle occupa la stanza lo sa solo Rust — la tessera a gradini ne vale
   due — quindi è lui a mettere `dispari` sulla griglia. */
.griglia.dispari > .tessera:last-child {
  grid-column: span 2;
}

.tessera {
  position: relative;
  overflow: hidden;
  min-height: 82px;
  border-radius: var(--r-tessera);
  background: var(--grigio);
  color: var(--grigio-su);
  text-align: left;
  animation: sorgi 0.45s var(--morbida) backwards;
  transition:
    background-color 0.34s var(--morbida),
    color 0.34s var(--morbida),
    border-radius 0.34s var(--molla),
    transform 0.34s var(--molla);
}

/* Il riempimento: giallo pieno da sinistra fino a dove arriva la luce, il
   resto giallo pallido. Con una lampada sola sono 0% o 100% e la tessera
   sembra a tinta unita; con le due della sala il mezzo si vede, ed è
   esattamente l'informazione che serve. */
.tessera::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--riempi, 0%);
  background: var(--giallo-pieno);
  opacity: 0;
  transition:
    width 0.5s var(--morbida),
    opacity 0.34s var(--morbida);
  pointer-events: none;
}

.tessera.accesa {
  background: var(--giallo-traccia);
  color: var(--giallo-su);
}

.tessera.accesa::before {
  opacity: 1;
}

/* La deformazione dell'angolo sotto il dito è il tocco di Material 3
   Expressive che si sente più di quanto si veda: la tessera reagisce
   prima ancora che la centralina risponda. Solo le tessere che sono
   davvero un pulsante: quella larga è una scatola con dentro i gradini, e
   se si stringesse tutta a ogni tocco reagirebbe due volte allo stesso
   dito. */
button.tessera:active {
  transform: scale(0.97);
  border-radius: 30px;
}

.tessera.larga {
  grid-column: span 2;
}

.tessera[disabled] {
  opacity: 0.45;
}

@keyframes sorgi {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.985);
  }
}

.griglia > .tessera:nth-child(2) {
  animation-delay: 0.04s;
}

.griglia > .tessera:nth-child(3) {
  animation-delay: 0.08s;
}

/* Il contenuto sta sopra al riempimento. */
.tessera > * {
  position: relative;
  z-index: 1;
}

/* La tessera semplice è tutta un pulsante: il bersaglio è il rettangolo
   che si vede, non le due righe di testo dentro. */
.tessera.semplice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 14px;
  width: 100%;
}

/* Ogni SVG iniettato sta dentro questo involucro: senza, un `span` con
   dentro un disegno si comporta come testo e si porta dietro la riga
   base, che sfalsa di un paio di pixel tutto quello che gli sta accanto. */
.segno {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

.tessera .lume {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  color: var(--grigio-icona);
  transition: color 0.34s var(--morbida);
}

.tessera.accesa .lume {
  color: #6b5300;
}

.tessera .nome {
  display: block;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.1px;
  line-height: 1.2;
}

.tessera .stato {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  opacity: 0.66;
  margin-top: 2px;
}

/* Puntino che pulsa mentre aspettiamo la conferma della centralina: senza,
   un comando lento sembra un comando ignorato. */
.tessera.in-volo::after {
  content: "";
  position: absolute;
  top: 16px;
  right: 16px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.35;
  animation: respiro 1.1s ease-in-out infinite;
  z-index: 2;
}

@keyframes respiro {
  0%,
  100% {
    opacity: 0.15;
    transform: scale(0.8);
  }
  50% {
    opacity: 0.6;
    transform: scale(1.15);
  }
}

/* ------------------------------------------------- comando a gradini */

/* La centrale della sala sono due lampade in cascata, ed è l'apparecchio
   più importante della casa: si prende la riga intera e la forma grande
   che nell'app di riferimento ha il termostato — in mezzo, disegnato,
   quello che sta succedendo, e sotto il comando.
   Il comando però non è il meno e il più del termostato: quello ha trenta
   gradini, e con trenta gradini è l'unica forma possibile. Qui i gradini
   sono tre, e col meno e il più le due cose che si fanno tutti i giorni —
   accendere tutto e spegnere tutto — costerebbero due tocchi invece di
   uno. Resta un pulsante segmentato di Material 3, che è la stessa
   famiglia: cambia il componente, non il sistema. */
.tessera.larga .cima {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px 0 16px;
}

.tessera.larga .cima .nome {
  font-size: 14px;
}

.quadrante {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px 16px 16px 16px;
}

.lettura {
  text-align: center;
  min-width: 0;
}

.lettura .lampade {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: currentColor;
}

/* Il bianco è l'unica tinta che si stacca sia dal giallo pieno sia dalla
   traccia pallida sia dal grigio di spento: il gradino scelto è bianco su
   qualunque cosa gli passi sotto il riempimento. */
.gradini {
  display: flex;
  gap: 4px;
  padding: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.52);
}

.gradini button {
  flex: 1 1 0;
  height: 38px;
  padding: 0 6px;
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: -0.1px;
  color: inherit;
  opacity: 0.7;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition:
    background-color 0.28s var(--morbida),
    opacity 0.28s var(--morbida),
    transform 0.3s var(--molla);
}

.gradini button:active {
  transform: scale(0.95);
}

.gradini button.qui {
  background: #fff;
  opacity: 1;
  box-shadow: 0 1px 2px rgba(27, 27, 31, 0.1);
}

/* ------------------------------------------------------------ avvisi */

.avviso {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  border-radius: var(--r-tessera);
  font-size: 14px;
  margin-bottom: 8px;
  background: var(--avviso);
  color: var(--avviso-su);
}

.avviso.grave {
  background: var(--guaio);
  color: var(--guaio-su);
}

/* Non è un guaio né un avvertimento: è il codice di invito appena creato,
   una cosa andata a buon fine. Prende il verde di casa, lo stesso della
   scheda aperta in fondo. */
.avviso.calmo {
  background: var(--verde);
  color: var(--verde-su);
}

.avviso strong {
  display: block;
  font-weight: 700;
  letter-spacing: -0.2px;
  margin-bottom: 2px;
}

/* La riga sotto il titolo dell'avviso. Di suo è italiano e si legge come
   tale; quando invece riporta parola per parola quello che ha detto il
   server prende in più la classe `tecnica` e passa al mono, che è la voce
   della macchina. Una frase intera in mono a 12,5px non si legge. */
.avviso .motivo {
  font-size: 13px;
  line-height: 1.45;
  opacity: 0.95;
}

.avviso .motivo.tecnica {
  font-size: 12.5px;
}

.avviso .chiudi {
  margin-left: auto;
  font-weight: 700;
  opacity: 0.6;
  padding: 0 4px;
  align-self: flex-start;
}

/* ------------------------------------------------------------ elenchi */

/* Chi è entrato, in cima alle impostazioni. Stava nella pastiglia, dove
   però nelle altre schermate c'era tutt'altro: qui è a casa sua. */
.chi {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 6px 6px 0 6px;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.7px;
  color: var(--inchiostro);
}

/* "Amministratore" accanto al nome è un'etichetta, non una scelta né uno
   stato: sta in grigio perché il verde in questa pagina vuol dire
   "selezionato" e qui non c'è niente da selezionare. */
.chi .ruolo {
  padding: 4px 11px;
  border-radius: 999px;
  background: var(--velo-superficie);
  color: var(--inchiostro-2);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0;
}

.sezione {
  margin: 22px 6px 8px 6px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.1px;
  color: var(--inchiostro-2);
}

.lista {
  background: var(--velo-superficie);
  border-radius: var(--r-carta);
  overflow: hidden;
}

.riga {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 13px 16px;
  text-align: left;
  border-bottom: 1px solid rgba(27, 27, 31, 0.06);
}

.riga:last-child {
  border-bottom: none;
}

.riga .titolo {
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: -0.1px;
}

.riga .nota {
  font-size: 13px;
  color: var(--inchiostro-3);
  margin-top: 2px;
}

/* Orari, identificativi di avvio, stato della catena: numeri da
   confrontare, quindi in mono e a cifre di larghezza fissa. */
.tecnica,
.riga .coda {
  font-family: var(--macchina);
  font-size: 12.5px;
  line-height: 1.4;
  font-variant-numeric: tabular-nums;
  color: var(--inchiostro-3);
}

.riga .coda {
  margin-left: auto;
  white-space: nowrap;
}

/* Una riga di dati sotto un titolo sta su una riga sola: se una data va a
   capo a metà si legge come due date diverse. */
.riga .nota.tecnica {
  font-size: 12px;
}

.riga .pallino {
  width: 38px;
  height: 38px;
  flex: 0 0 auto;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: #e4e6ea;
  color: var(--inchiostro-2);
  font-weight: 700;
}

.riga .pallino.oro {
  background: var(--giallo-pieno);
  color: var(--giallo-su);
}

.riga .pallino.rosso {
  background: var(--guaio);
  color: var(--guaio-su);
}

/* I pallini colorati sono due soli: oro quando una luce si è accesa, rosso
   quando qualcosa si è rotto. Accessi, inviti e chiavetta restano grigi —
   sono cronaca, non allarmi, e l'icona dentro il pallino dice già quale. */

.spoglio {
  padding: 36px 20px;
  text-align: center;
  color: var(--inchiostro-3);
  font-size: 14.5px;
}

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

.pieno,
.vuoto-bordo {
  display: block;
  width: 100%;
  height: 56px;
  padding: 0 20px;
  border-radius: 999px;
  font-size: 15.5px;
  font-weight: 700;
  letter-spacing: -0.1px;
  text-align: center;
  transition:
    border-radius 0.34s var(--molla),
    transform 0.34s var(--molla),
    opacity 0.2s var(--morbida);
}

.pieno {
  background: var(--primario);
  color: #fff;
}

.vuoto-bordo {
  background: transparent;
  color: var(--primario);
  box-shadow: inset 0 0 0 1.5px var(--filo);
}

.pieno:active,
.vuoto-bordo:active {
  transform: scale(0.98);
  border-radius: 18px;
}

.pieno[disabled],
.vuoto-bordo[disabled] {
  opacity: 0.5;
}

.testuale {
  display: block;
  width: 100%;
  color: var(--primario);
  font-weight: 700;
  font-size: 14.5px;
  padding: 14px 4px;
}

.testuale.pericolo {
  color: #b3261e;
}

/* Campo pieno, non riquadrato: è la forma dei campi di Material 3, e su
   fondo bianco si vede meglio di un bordo sottile. */
.campo {
  width: 100%;
  height: 56px;
  padding: 0 18px;
  border-radius: var(--r-campo);
  border: none;
  background: var(--velo-superficie);
  box-shadow: inset 0 0 0 1px var(--filo);
  outline: none;
  margin-bottom: 10px;
}

.campo.codice {
  font-family: var(--macchina);
  letter-spacing: 2px;
  text-align: center;
}

.campo:focus {
  box-shadow: inset 0 0 0 2px var(--primario);
}

/* Il codice di invito va letto ad alta voce cifra per cifra: mono, grande
   e spaziato, perché "0" e "O" non si confondano al telefono. */
.codice-grosso {
  display: block;
  font-family: var(--macchina);
  font-weight: 500;
  font-size: 26px;
  letter-spacing: 3px;
  margin-bottom: 6px;
}

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

/* La schermata d'ingresso non chiede niente da ricordare, quindi non ha
   niente da riempire. Prima al posto del modulo c'era mezzo schermo di
   fotografia della sala: bella, e muta — la casa la si vede appena
   entrati, e qui davanti non si è ancora entrati.

   Al suo posto c'è quello che questa casa ha e quasi nessun accesso può
   permettersi: i nomi di chi ci abita, cinque, sempre gli stessi. Sono il
   soggetto della pagina, non l'arredamento, e stanno scritti grandi come
   si scrive un titolo — uno per riga, tutta la larghezza, perché sono
   l'unica scelta che c'è da fare qui dentro. Niente sottotitolo di
   presentazione: chi apre quest'app sa già cos'è. */
.ingresso {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  max-width: 560px;
  margin: 0 auto;
  padding: calc(env(safe-area-inset-top) + 26px) 16px
    calc(env(safe-area-inset-bottom) + 20px) 16px;
}

/* Il nome dell'app in piccolo e in alto, come sulla targa di un
   citofono: serve a dire dove si è, non a fare da titolo. Il titolo è la
   domanda. */
.ingresso .insegna {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--inchiostro-3);
}

.ingresso .domanda {
  margin: 6px 0 0 0;
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -1.1px;
  line-height: 1.05;
  color: var(--inchiostro);
}

/* L'elenco si prende tutto il vuoto fra il titolo e i comandi, ma i nomi
   stanno appoggiati in alto e non in mezzo. Se stessero in mezzo si
   alzerebbero di un paio di centimetri ogni volta che sotto compare il
   campo del codice o il pulsante secondario — cioè esattamente nell'istante
   in cui uno ha appena toccato un nome e sta guardando lì. Il vuoto è
   meglio che stia tutto da una parte e non si muova mai. */
.ingresso .elenco {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 2px;
  padding: 22px 0 8px 0;
  overflow-y: auto;
  scrollbar-width: none;
}

.ingresso .elenco::-webkit-scrollbar {
  display: none;
}

/* Tutto quello che si tocca sta in fondo, dove arriva il pollice. */
.ingresso .pedana {
  flex: 0 0 auto;
}

/* Una riga per persona, larga quanto lo schermo. Prima erano cinque
   pastiglie in fila orizzontale: cinque nomi in 366px vuol dire settanta
   pixel a testa, e "Michele" e "Lorena" ci finivano tagliati con i
   puntini. Un nome troncato sulla schermata dove si sceglie il proprio
   nome è il difetto peggiore che questa pagina potesse avere. */
.volto {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 9px 12px;
  border-radius: 999px;
  text-align: left;
  transition:
    background-color 0.22s var(--morbida),
    transform 0.3s var(--molla);
}

.volto:active {
  transform: scale(0.98);
}

/* Scelto è verde come ogni altra cosa scelta in quest'app. La tinta della
   persona resta dov'era, sul cerchio: è la sua, non è lo stato della
   riga, e fra un attimo la si ritrova in cima alla schermata di casa. */
.volto.scelto {
  background: var(--verde);
}

.volto .cerchio {
  width: 50px;
  height: 50px;
  flex: 0 0 auto;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 20px;
  font-weight: 700;
  transition: box-shadow 0.26s var(--morbida);
}

/* Un filo di bianco fra il cerchio e il verde: due tinte pastello
   attaccate si impastano, e il cerchio deve restare un oggetto a sé. */
.volto.scelto .cerchio {
  box-shadow: 0 0 0 3px var(--fondo);
}

.volto .chi {
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.3px;
  color: var(--inchiostro);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.volto.scelto .chi {
  color: var(--verde-su);
  font-weight: 700;
}

/* La riga che dice cosa succederà premendo il pulsante grande. Tiene il
   posto per due righe anche quando ne occupa una: alcune frasi vanno a
   capo e altre no, e senza questo l'elenco dei nomi si alzerebbe di
   mezzo centimetro proprio mentre il dito sta scendendo sul pulsante. */
.ingresso .promemoria {
  margin: 0 6px 12px 6px;
  font-size: 13.5px;
  line-height: 1.35;
  color: var(--inchiostro-3);
  text-align: center;
  min-height: 37px;
}

/* ------------------------------------------------------------ barra */

.navigazione {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  gap: 4px;
  padding: 10px 12px calc(env(safe-area-inset-bottom) + 10px) 12px;
  background: var(--velo-superficie);
  z-index: 10;
}

.navigazione button {
  flex: 1 1 0;
  max-width: 160px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1px;
  color: var(--inchiostro-2);
}

.navigazione .bolla {
  width: 64px;
  height: 32px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  transition:
    background-color 0.28s var(--morbida),
    width 0.34s var(--molla);
}

.navigazione button.attivo {
  color: var(--verde-su);
  font-weight: 700;
}

.navigazione button.attivo .bolla {
  background: var(--verde);
  color: var(--verde-su);
}

/* ------------------------------------------------------------ girella */

.girella {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2.5px solid var(--verde);
  border-top-color: var(--primario);
  animation: gira 0.7s linear infinite;
  margin: 0 auto;
}

.girella.chiara {
  border-color: rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
}

@keyframes gira {
  to {
    transform: rotate(360deg);
  }
}

.attesa {
  min-height: 100dvh;
  display: grid;
  place-items: center;
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}
